Iniziamo col prendere in esame questa tabella. In questa le "X" rappresentano i dati già inseriti nella tabella che è quella zona colorata.
Perchè la tabella sia riconosciuta in tutta la sua ampiezza, è importante che, anche se la tabella non è completamente riempita in tutte le sue celle, come indicato nella prima tabella, i dati non lascino righe o colonne vuote come nelle altre due tabelle a fianco.
|
|
|
Dopo queste premesse possiamo vedere come le seguenti proprietà dell'oggetto Range possano aiutarci ad effettuare precise ed importanti selezioni. Ognuna di esse ha un modo diverso di lavorare (e di farci lavorare). Visto che gli argomenti che sto per esaminare sono abbastanza numerosi, passo subito ad elencarli.
Se teniamo conto di queste considerazioni potremmo essere più sicuri sugli effetti che le seguenti proprietà avranno nelle nostre tabelle: End, CurrentRegion, UsedRange, Count, Cells, Rows, Columns.
Proprietà End equivale a premere CTRL+ FRECCIA SU, CTRL+ FRECCIA GIÙ, CTRL+ FRECCIA SINISTRA o CTRL+ FRECCIA DESTRA e si composta come è descritto in questo grafico:
| A | B | |||||
|---|---|---|---|---|---|---|
| 1 | Range("A1").End(xlDown).Select | seleziona la cella "A4" | ||||
| 2 | ||||||
| 3 | ||||||
| 4 | X | Range("A4").End(xlDown).Select | seleziona la cella "A7" | |||
| 5 | X | Range("A4", Range("A4").End(xlDown)).Select | seleziona l'intero intervallo "A4:A7" | |||
| 6 | X | |||||
| 7 | X | Range("A7").End(xlDown).Select | seleziona la cella "A11" | |||
| 8 | ||||||
| 9 | ||||||
| 10 | ||||||
| 11 | X | Range("A11").End(xlDown).Select | seleziona l'ultima cella del foglio | |||
| 12 | ||||||
| 13 |
Una delle selezioni da mettere in evidenzia è quella che, qui sopra nello schema, è evidenziata.
Questa effettua una selezione che va dalla "A4" per finire in "Range("A4").End(xlDown)". La sintassi dell'istruzione rispecchia quella classica di base che è:
Restituisce un oggetto Range, che rappresenta l'area corrente, cioè l'area che circonda o è vicina alla cella di riferimento.
Perchè questa particolare proprietà funzioni non è necessario che tutte le celle della tabella in esame siano non vuote, ma che le celle non vuote occupino tutte le righe e le colonne della tabella (vedi la prima tabella qui in alto).
Non è necessario che la cella di partenza sia nell'angolo superiore sinistro della tabella, ma in una qualsiasi locazione all'interno della tabella o esternamente ad essa purché nella immediata vicinanza ci sia una cella appartenente alla tabella stessa. In quest'ultimo caso il riferimento si allarga al di fuori della tabella.
Tuttavia la selezione eseguita con questo metodo funziona a grappolo: se una o più celle non sono a contatto con con le altre che verrebbero incluse dalla selezione, verranno escluse.
A conclusione si ha che la proprietà CurrentRegion esige che la cella da cui parte l'azione sia:
Vediamo qui sotto alcuni esempi:
|
|
Non a caso ho presentato la tabella di esempio. A seconda della cella di origine le celle con la "X" in rosso potrebbero essere escluse dalla selezione. Provate ad eseguire "CurrentRegion" partendo dalla cella "F3" o dalle celle "J5" o "K4".
Un'altra caratteristica richiesta da questa proprietà è che la cella da cui parte l'azione sia:
Restituisce un oggetto Range, che rappresenta l'intervallo utilizzato del foglio di lavoro specificato anche se i dati sono sparsi in più parti del foglio.
Contrariamente a "CurrentRegion" la proprietà UsedRange esegue una selezione su tutte le celle non vuote presenti sul foglio inglobando nella selezione anche le celle vuote tra quelle comprese.
Un'altra particolarità è che CurrentRegion si applica ad un oggetto range, mentre UsedRange si applica al foglio.
Questa proprietà non solo restituisce un riferimento a tutte le celle non vuote, ma anche a qualsiasi cella che, anche se vuota, in qualche modo ha una qualsiasi formattazione: formato, formato carattere, bordo, riempimento, ecc.
Nella tabella che stiamo trattando come esempio restituirà l'intervallo "C3:K7" se nel foglio è presente la sola tabella che in questa esercitazione, ma se ci fosse in un posto qualsiasi del foglio anche una sola cella che, anche se vuota, abbia una qualche formattazione che non sia quella predefinita del foglio, si estenderebbe sino a comprendere quella determinata cella.
Questa è la sua sintassi:
ActiveSheet.UsedRange.Select
Worksheets("Foglio2").UsedRange.Select
E' questa una proprietà che si applica a moltissimi oggetti che incontriamo in VBA. Se applicata all'oggetto Range ci restituisce il numero di celle, righe o colonne in esso compreso.
Vediamo alcuni esempi applicati alla tabella che stiamo esaminando:
NumEl = Range("C3").CurrentRegion.Cells.Count
restituisce il numero "45"
Riga = Range("C3").CurrentRegion.Rows.Count
restituisce il numero "5"
Colonna = Range("C3").CurrentRegion.Columns.Count
restituisce il numero "9"
Queste sono proprietà sia dell'oggetto Worksheet che all'oggetto Range.
Usandoli come proprietà dell'oggetto Worksheet vengono usati in questo modo (che è il nostro modo più usuale:
Cells(Riga, Colonna).Select
per selezionare la cella che incontriamo alle coordinate indicate da "Riga" e "Colonna", oppure
Range("A1").Select
per selezionare la prima cella in alto a sinistra del foglio di lavoro.
Ma possiamo usarli anche con le seguentiistruzioni:
Range("C3:K7").Cells(1, 1).Select
Range("C3:K7").Range("A1").Select
per selezionare la prima cella e cioè la cella C3
Queste selezioni non ci restituiscono l'intervallo che ci aspetteremmo, infatti ci restituiscono la cella "C3" e non "A1".
Questo potrebbe essere un modo di esplorare tutte le celle dell'intervallo compreso in Range("C3").CurrentRegion, che nel nostro esempio è rappresentato dall'intervallo C3:K7:
In queste istruzioni occorre porre attenzione al . (punto) posto prima di Cells(R, C). Se questo punto viene omesso le selezioni non vengono più effettuate dalla cella C3 alla cella K7, bensì dalla della A1 del foglio.
A questo punto si potrebbe creare della confusione perchè "Range" è, a seconda dei casi, sia una proprietà dell'oggetto "Worksheet" che dello stesso oggetto "Range".
Ma rifacciamoci un attimo alla sintassi canonica da usare per selezionare una determinata cella.
Object.Cells(Riga,Colonna).
Se nell'usare questa proprietà ci riferiamo all'oggetto "Worksheet", possiamo semplificare l'istruzione ommettendo la descrizione dell'Object.
Ma se ci riferiamo ad un oggetto "Range" la descrizione dell'Object "Range va sempre espressa.
Come il solito alcuni esempi possono chiarirci le idee.
Con riferimento al Foglio
| Worksheets("foglio1").Range("A1").Select | per la cella A1 | |
| Worksheets("foglio1").Cells(5, 3).Select | per la cella C5 | |
| Worksheets("foglio1").Cells(1, 180).Select | per la cella FX1 | |
| Worksheets("foglio1").Cells(1, 260).Select | Questa non si può usare in quanto il limite massimo per le colonne è 256 |
Forse è il caso di ribadire che il numero limite per indicare una colonna è 256 mentre quello per indicare una riga è 65536 ma c'è anche un altro modo di riferirsi alle celle, indicando un solo indice, anzichè due.
| Worksheets("foglio1").Cells(265).Select | per la cella I2 | |
| Worksheets("foglio1").Cells(2650).Select | per la cella CL11 | |
| Worksheets("foglio1").Cells(16777216).Select | per la cella IV65536 che è l'ultima cella del foglio |
In questo caso il numero più grande che viene accettato è 16.777.216 che risulta dal prodotto 256 * 65.536 che sono i limiti massimi consentiti per le colonne e per le righe.
In tutti questi casi possiamo scrivere le stesse istruzioni senza far riferimento all'oggetto padre (in questo caso Worksheets che se omesso è comunque sottinteso).
| Range("A1").Select | per la cella A1 | |
| Cells(5, 3).Select | per la cella C5 | |
| Cells(1, 180).Select | per la cella FX1 | |
| Cells(2650).Select | per la cella CL11 |
Con riferimento a Range
Come dicevo prima posso riferirmi ad un range partendo da un intervallo ben preciso:
| Range("C3:K7").Range("A1").Select | per la cella C3 | |
| Range("C3:K7").Cells(5, 3).Select | per la cella E7 | |
| Range("C3:K7").Cells(1).Select | per la cella C3 | |
| Range("C3:K7").Cells(260).Select | per la cella J31 | |
| Range("C3:K7")(1).Select | per la cella C3 | |
| Range("C3:K7")(1, 1).Select | per la cella C3 |
Ma in questi casi si può usare anche l'istruzione With in questo modo:
Ma attenzione al . (punto) da anteporre a Range o a Cells. Se si omette il punto si torna a lavorare sulle celle come appartenenti all'intero foglio e non più all'intervallo di riferimento.
Interessante è lavorare con intervalli denominati.
Con questi ultimi esempi è possibile spaziare oltre i limiti di 5 Righe e 9 Colonne di cui è composto l'intervallo in oggetto, ma si può andare ben oltre.
Ne consegue che è possibile creare l'intervallo anche facendo riferimento ad una sola cella come nella seguente istruzione:
Set Intervallo = Range("C3")
In entrambi i casi, per i vari spostamenti si fa riferimento sempre alla cella C3.
Lo stesso discorso si può applicare sulle altre due proprietà, Rows e Columns. Anche queste due proprietà possono riferirsi sia all'oggetto Worksheets che alloggetto Range, per cui non mi dilungo ulteriormente sull'argomento. Ecco alcuni esempi:
| Worksheets("foglio1").Rows(5).Select | restituisce la riga "5" - con Oggetto omesso si sottintende il riferimento a "Worksheets" | |
| Columns(7).Select | restituisce la colonna "G" | |
| Range("C3:K7").Rows(1).Select | restituisce la prima riga dellintervallo "C3:K3" (la 3)- qui l'oggetto è rappresentato da "Range" | |
| Range("C3:K7").Rows(Range("C3:K7").Rows.Count).Select | restituisce l'ultima riga dell'intervallo "C3:K7" (la 7) | |
| Range("C3:K7").Columns(1).Select | restituisce la prima colonna dell'intervallo "C3:K7" (la C) | |
| Range("C3:K7").Columns(20).Select | nella colonna 22 (la ventesima da "C3") tra la terza e la settima riga |
L'uso combinato di tutte o qualche proprietà appena viste ci daranno dei risultati interessanti.
Ora una piccola chicca sulla selezione di più colonne usando delle variabili.
Lavorando su Righe e/o colonne si potrebbero incontrare delle difficoltà.
Sappiamo che la sintassi canonica è:
Rows("3:8").Select
Columns("H:K").Select
Ma se volessimo selezionare più righe o colonne contemporaneamente, usando magari delle variabili per coordinate o indici, ci troveremmo in difficoltà.
Allora, o ricorriamo ad istruzioni del genere:
Range(Cells(A, 1), Cells(B, 1)).EntireRow.Select
Range(Cells(1, A), Cells(1, B)).EntireColumn.Select
o dobbiamo costruire manualmente la stringa di cui abbiamo bisogno.
Per le righe possiamo usare questo:
A = 3: B = 5
Rows(A & ":" & B).Select
Per le colonne non possiamo usare la stessa espressione: "Columns(A & ":" & B).Select" in quanto l'espressione produrrebbe un errore.
Allora dobbiamo ricorrere ad un espediente:
Contare il numero di celle, righe e colonne
NumEl = Range("C3:K7").Cells.Count
Ci restituisce "45" che è il numero complessivo delle celle contenute nell'intervallo
NumEl = Range("C3:K7").Count
Ci restituisce "45" (le due istruzioni sono equivalenti)
Riga = Range("C3:K7").Rows.Count
Ci restituisce "5"
Colonna = Range("C3:K7").Columns.Count
Ci restituisce "9"
Trovare la prima cella, riga o colonna della tabella:
Range("C3:K7").Cells(1).Select
Ci restituisce la cella "C3" la prima cella dell'intervallo
Range("C3:K7")(1).Select
Ci restituisce la cella "C3" ancora la prima cella
Range("C3:K7").Rows(1).Select
Ci restituisce l'intervallo "C3:K3" la prima riga
Range("C3:K7").Columns(1).Select
Ci restituisce l'intervallo "C3:C7" la prima colonna
Trovare l'ultima cella, riga o colonna della tabella
Riga = Range("C3:K7").Rows.Count
restituisce "5" che è il numero di righe dell'intervallo
Colonna = Range("C3:K7").Columns.Count
restituisce "9" che è il numero di colonne
Range("C3:K7")(Range("C3:K7").Count).Select
Ci restituisce la cella "K7" che è l'ultima cella dell'intervallo
Range("C3:K7")(Riga, Colonna).Select
Ci restituisce "K7" che è l'ultima cella dell'intero intervallo
Range("C3:K7")(Range("C3:K7").Rows.Count, Range("C3:K7").Columns.Count).Select
Anche questo ci restituisce "K7"
Range("C3:K7").Rows(Riga).Select
Ci restituisce "C7:K7" che è l'ultima riga dell'intera tabella
Range("C3:K7").Columns(Colonna).Select
Ci restituisce "K3:K7" che è l'ultima colonna dell'intera tabella
Conclusioni
Per ogni argomento trattato ho cercato di passare in rassegna vari metodi e dove possibile ho cercato anche di esporre metodi alternativi. Questo perchè molte volte è capitato anche a me di cercare una soluzione alternativa a quella standard e di non trovarne. Spero perciò di aver dato delle soluzioni valide per la maggior parte delle situazioni in cui potremmo venere a trovarci. Ma il discorso sulle selezioni non si esaurisce qui. Prossimamente a completamento cercheremo di illustrare altre nuove situazioni e soluzioni.
Buon lavoro