Assegnare nomi a celle o intervalli, tramite vba. - pagina vista: volte Sappiamo che per poter lavorare su fogli di cartelle di Excel, è necessario specificare la cella o le celle su cui desideriamo intervenire, attraverso un riferimento che identifichi la cella o l'intervallo di celle (area). Sappiamo pure che un modo abbastanza pratico per definire celle o intervalli di celle è quello di assegnargli un "nome", selezionando la cella o l'area, e dal menù "Inserisci/Nome/definisci" scrivere un nome che identificherà ciò che avremo selezionato. Ovviamente è possibile usare istruzioni vba per assegnare un "nome", ma prima di vedere le istruzioni, è opportuno fare due puntualizzazioni:
Infatti quando si inserisce un "nome" dal menù "Inserisci/Nome/definisci", Excel usa la sintassi : " FoglioX!Range(x : y) ", memorizzando quindi il nome del foglio insieme all'intervallo (o la singola cella), e basterà usare in istruzioni vba il "nome" perchè Excel identifichi foglio e intervallo. Questo ci consentirà di usare moltissime istruzioni lanciate da qualsiasi foglio, con la certezza che verranno eseguite "a distanza", cioè senza prima selezionare (Select) o attivare (Activate) il foglio contenente l'intervallo: se, per esempio, avremo assegnato il nome "pippo" all'intervallo A1:A5 del Foglio2, potremo istruire istruzioni, in questo caso lanciate dal Foglio1, esempi:
Lanciate da un altro foglio, senza aver assegnato un "nome" all'intervallo, avremmo necessariamente dovuto scrivere:
Se invece vorremo selezionare (Select) la cella o l'intervallo (relativo ad un foglio diverso da quello attivo), e rappresentato con un "nome", senza prima aver selezionato il Foglio che lo contiene, otterremo la protesta del debugger, che ci segnalerà un errore nell'uso del metodo Select, esempio:
L'uso di un "nome" ci può tornar utile anche quando dovremo assegnare un'intervallo (RowSource o ListFillRange) ad una ComboBox o ListBox ActiveX (anche poste su UserForm), ad esempio:
E' evidente che l'assegnazione di un "nome" presuppone che la cella o l'intervallo restino fissi nel tempo, sia come dimensione dell'intervallo, sia come posizione sul foglio. E' possibile tuttavia impostare istruzioni che "rileggano" una nuova dimensione dell'intervallo e riassegnino il nuovo intervallo allo stesso "nome". Ma vediamo intanto l'istruzione di base per assegnare via vba un nome ad un'intervallo; l'istruzione si basa sul metodo "Add" dell'oggetto "Names" relativo all'oggetto Workbook, e bisogna specificare quale nome assegnare e a quale cella o intervallo di un foglio, così:
se non avessimo specificato il foglio (Sheets(2)) in "ReferTo", l'intervallo sarebbe stato assunto come intervallo del foglio in quel momento attivo e memorizzato come tale. Vediamo ora come assegnare, usando un ciclo For Next, dei nomi ad intervalli multipli. Per evitare di assegnare lo stesso nome due volte, incrementeremo il nome aggiungendovi un numero, in modo da ottenere "pippo1", "pippo2" ecc. ecc. In questo primo esempio assegneremo un nome ad ogni cella, nell'intervallo A1:A10, e non specificheremo il foglio. Lanciando la macro dal Foglio1, i nomi saranno da Excel identificati come intervalli (celle) del Foglio1:
Ora invece vediamo come assegnare nomi a più intervalli di celle. In questo caso dovremo impostare istruzioni che prevedano il numero di quante righe e quante colonne formeranno l'intervallo, poi dovremo decidere lo scarto, cioè se vorremo che gli intervalli si susseguano, o se invece vorremo saltare una o più righe (o colonne) tra un'intervallo e l'altro. Supponiamo quindi di voler definire nomi a intervalli di 4 righe e 3 colonne; useremo ancora il nome "pippo" che incrementeremo di numero per differenziare i nomi; anche in questo caso non specificheremo il nome del foglio:
** : con RefersTo:=Range(Cells(riga, 1), Cells(riga + 3, 3)) indichiamo che l'intervallo sarà dalla (iniziale) A1 (Cells(riga(1), 1)) alla cella riga1 +3 quindi riga4) (Cells(riga + 3, 3)), e fino alla colonna 3, quindi A1:C4, al successivo ciclo, avendo incrementato la variabile "riga" di 4, ci troveremo alla A5:C8, ecc. Se volessimo uno scarto di una riga tra un'intervallo e l'altro, basterebbe variare il numero di incremento riga, cioè riga = riga + 5 . e invece avessimo voluto assegnare nomi ad intervalli ma sul Foglio3, avremmo dovuto scrivere il numero del foglio in ReferTo, così:
Ora invece vediamo come eliminare solo un "nome" assegnato o tutti i "nomi". I "Names" sono identificati da Excel attraverso appunto un "nome" che lo identifichi, oppure, come in tutti gli insiemi, dal suo numero indice. Questa sotto è l'istruzione per eliminare un solo "nome":
Questa sotto invece è una routine che prima conta quanti nomi sono presenti nella cartella attiva, e poi usa questo numero per effettuare un ciclo che elimini tutti i "nomi", iniziando il ciclo dal limite superiore, e tornando indietro :
Ora vediamo un esempio in cui sia necessario rendere "variabile" l'intervallo assegnato ad un "nome". Potrebbe essere il caso di un "nome" usato per definire il RowSource (o il ListFillRange) di una ComboBox o ListBox ActiveX. Non è raro infatti che uno di questi "oggetti ActiveX" peschi i dati da mostrare nella propria lista, in un'intervallo che si modifica in continuazione, per aggiunte o eliminazione dell'elenco originale. Supponiamo quindi di avere una ComboBox posta su una UserForm; potremo sfruttare l'evento Activate della userform per "controllare" la lunghezza dell'intervallo "nome" assegnato al RowSource della ComboBox, e nello stesso evento, ricreare il "nome" e riassegnarlo. Per poter contare quante righe sono contenute in un "Name" (visto quindi come intervallo), è necessario sfruttare la proprietà ReferToRange che restituisce l'oggetto Range a cui un oggetto Name fa riferimento. Se quindi il nome "pippo" l'avessimo assegnato all'intervallo F1:F10 del foglio attivo, useremo queste istruzioni, tenendo ben presente che il nome "pippo" deve essere già stato assegnato (altrimenti dovremmo istruire altre istruzioni che controllino se il nome "pippo" esiste)
Esistono comunque sistemi diversi per rendere variabili i riferimenti da assegnare ad un RowSource, anche più semplici, ma visto che si sta parlando di "Names", era giusto presentare un esempio basato sui Names. Buon Lavoro. prelevato sul sito www.ennius.altervista.org |