Considerazioni su DOVE inserire il codice (Le Istruzioni in codice VBA).  

Abbiamo visto che cos'è una Macro : una o più istruzioni compilate in linguaggio VBA e come associare una macro per attivare le istruzioni in essa contenute. Vorrei però riepilogare meglio i concetti di QUANDO e DOVE posizionare le istruzioni, cercando di spiegare PERCHE'.

E' necessario ribadire che il VBA è un linguaggio di programmazione a "OGGETTI" - In una cartella di lavoro di Excel, sono "oggetti" i fogli di lavoro (Foglio1, Foglio2, ecc), la stessa cartella (WorkBook), e, trascurando per ora di parlare dell'oggetto "Range", sono "oggetti" anche tutti gli strumenti che possiamo inserire in un foglio di lavoro, quali ad esempio, un Commandbutton, un Combobox, un Pulsante di Opzione, una UserForm, un textbox, ecc.. Tralasciando di parlare in questo paragrafo delle "Proprietà" degli "oggetti", fisseremo la nostra attenzione sugli "EVENTI"  che OGNI "Oggetto"  possiede.  Per "EVENTO" si intende l'"AZIONE" che si deve compiere per ATTIVARE le istruzioni abbinate all'"Oggetto" di cui l'evento fa parte.

Precisiamo che esistono due modi per attivare le istruzioni (che da ora chiameremo "codice"):

  1. attivazione in automatico

  2. attivazione su comando

Per l'attivazione di codice in Automatico, useremo gli oggetti WorkBook, ed i Fogli, sfruttando gli eventi ad essi collegati: se per esempio, vogliamo che un'istruzione si attivi ad ogni apertura della cartella di lavoro, sceglieremo l'evento "Open" dell'oggetto "WorkBook", scrivendo il codice tra inizio e fine della routine che Excel stesso, se selezioneremo l'oggetto WorkBook  nell'editor di visual basic,  provvede ad inizializzare, oppure "chiamando" in questo evento il nome di una macro precedentemente preimpostata:

Private Sub Workbook_Open()
in questa zona va scritta l'istruzione oppure il nome della macro
End Sub

Oppure, secondo esempio, se vogliamo che l'istruzione si attivi ad ogni variazione in un foglio di lavoro, possiamo scegliere l'evento "Change" dell'oggetto "Foglio1" ripetendo quando detto nell'esempio precedente:

Private Sub Worksheet_Change(ByVal Target As Range)
MsgBox ("Ciao !")
End Sub

Appare evidente che, selezionando l"Evento" più appropriato, tra quelli disponibili per l"oggetto" scelto, potremo pilotare l'esecuzione di codice come più ci necessita, compreso rendere l'automatismo dell'evento ancora più flessibile, inserendo un'istruzione opportuna, per esempio:

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Range("A1") = ""  Then exit Sub
MsgBox ("Ciao !")

End Sub

(la differenza tra i due eventi sopra, che sembrano simili, è questa: l'evento "Change" si verifica quando, selezionando una cella, inseriamo un valore o modifichiamo quello già presente, premendo invio, altrimenti non si ha l'evento "Change". L'evento "SelectionChange" si verifica anche quando selezioniamo o clicchiamo su una cella diversa da quella attualmente selezionata, e quindi praticamente sempre, compreso un inserimento valore o modifica valore, perchè dovremo deselezionare la cella in questione per attivare la modifica, selezionandone un altra, compreso l'uso del tasto "invio" che sposta il focus sulla cella sottostante e quindi genera un cambio di selezione.)

L'esempio sopra, nonostante sia abbinato all'evento "SelectionChange" (cambio di selezione di cella) e quindi praticamente ad ogni modifica che facciamo su un Foglio, "usa" un "interruttore di consenso" rappresentato da una cella (A1 per esempio): l'istruzione dice: "Se la cella A1 è vuota, esci da questa routine" : cioè non viene più eseguito tutto ciò che si trova sotto. Infatti l'esecuzione di qualunque istruzione contenuta tra inizio e fine routine, avviene sempre eseguendo le istruzioni riga dopo riga, partendo da inizio istruzioni e fino alla fine. Potremo quindi scrivere in A1 "Si" o qualunque altra cosa e l'istruzione verrà eseguita fino in fondo, o lasciare la stessa cella vuota per evitare di attivare la stessa istruzione.

Il vantaggio di esecuzione di codice in automatico appare quindi evidente: non dovremo premere nessun pulsante, o richiamare nessuna macro, perchè sarà sufficiente il verificarsi di un "evento" .

Ci sono istruzioni che però vorremo attivare direttamente noi, e non lasciarle gestire da "eventi" collegati ad un foglio di lavoro, sono quelle definite "Attivazione su comando". Questo tipo di istruzioni si possono inserire in due modi:

  • Inserimento in un Modulo

  • Inserimento in un "Evento" associato ad un oggetto preso dalla Casella degli Strumenti

L'inserimento in un modulo è forse il metodo più conosciuto e lo stesso usato da Excel quando si fa uso del "Registratore di Macro". Manualmente si ottiene recandosi nell'editor di visual basic e, da "Inserisci", scegliamo "Modulo"; appare nella finestra degli "Oggetti" una nuova cartella "Moduli" e cliccandoci si apre mostrandoci "Modulo 1". Nella parte destra si dovrà inserire il codice, avendo cura di dare un nome alla routine, per esempio "Sub conteggi()". Excel predisporrà "End Sub". All'interno tra inizio e fine scriveremo il nostro codice. Esempio, facciamo eseguire due semplici operazioni, la somma di due celle (A1+A2) e la divisione della somma per 2, il risultato lo vogliamo in C1:

Sub conteggi()
Range("C1") =  (Range("A1") + Range("A2")) / 2
End Sub

Il vantaggio di questa soluzione e che disporremo di un codice che potremo attivare a nostro piacimento. Come? Associando il codice (macro) ad un pulsante ottenuto usando un "Formato forme" degli strumenti "Disegno",  magari un "rettangolo". Al "rettangolo" possiamo cambiare la dimensione, aggiungere del testo, cambiare il colore di sfondo e del font, posizionarlo sul foglio dove più ci piace, ecc. ecc. Una volta associato il "pulsante" ad una macro, tutte le volte che ci cliccheremo sopra, attiveremo il codice contenuto nella stessa macro. Un altro modo è quello di lavorare con la finestra "Moduli" ottenibile da "Visualizza/Barre degli Strumenti/Moduli". Appare una finestra con una serie di icone che rappresentano degli oggetti simili a quelli che sono nella finestra "Strumenti di Controllo": ATTENZIONE: non sono "OGGETTI",  infatti non possiedono "Proprietà" nè "Eventi". Assomigliano molto di più alle "Forme" ottenibili da "Disegno" anche se il loro aspetto è decisamente più consono. L'associazione al codice è ancora più diretta: cliccando sull'icona "pulsante" e trascinando sul foglio, apparirà un bel pulsante e contemporaneamente una finestra per associazione alla macro, basta selezionare quella giusta. Trascuro di parlare dell'attivazione macro attraverso il percorso che passa dal menù "Strumenti/ Macro/Macro/Nome Macro/ Esegui" , secondo me troppo lungo e noioso. La differenza sostanziale che notiamo in queste soluzioni è che non sfrutteremo più nessun "EVENTO". Come contropartita, oltre ad  inserire pulsanti sul nostro foglio di lavoro, (spesso lo spazio a disposizione non ci lascia troppe chances), avremo un' esecuzione codice che attiveremo solo se interveniamo noi.

Esistono tuttavia casi nei quali vorremmo che l'attivazione del codice si verificasse in automatico, ma SOLO se interveniamo noi modificando uno o più dati del foglio di lavoro. Un pò come avviene con le formule inserite in un foglio di lavoro: basta cambiare un dato in una cella richiamata in una formula, e il risultato si aggiorna automaticamente senza bisogno di codice. (ricordo però che il codice NON può risiedere sul foglio di lavoro e quindi và attivato, in una maniera o nell'altra). Questi casi si affrontano utilizzando gli "Eventi" degli "OGGETTI"  "STRUMENTI" presi dalla "Finestra degli Strumenti" o "Strumenti di Lavoro" , che sono la stessa cosa , ma vengono chiamati diversamente a secondo la versione di Excel che abbiamo. Se inseriamo in un foglio di lavoro, per esempio, un "combobox" detta in italiano "casella combinata", potremo sfruttare gli "eventi" che possiede (Change, Click, Dblclick, LostFocus, Keypress, ecc. ecc), scegliendo l'evento che meglio si adatta per attivare il codice, che ovviamente andrà inserito tra inizio e fine routine che si genera appena scelto l'evento da noi selezionato. Continuando con l'esempio, ipotiziamo di avere collegato la proprietà "ListFillRange" dell'oggetto combobox1 alla colonna A del Foglio1, dove dalla 5 alla 20a riga abbiamo inserito un elenco di nomi (ListFillRange A5:A20), e di avere scelto l' evento "Click", vedremo che la routine inizierà con

Private Sub ComboBox1_Click()
Qui inseriremo l'istruzione
End Sub

Tornati sul foglio di lavoro, e usciti da modalità progettazione con un click sull'icona "Squadra" della finestra degli strumenti, vedremo che la nostra "casella combinata" porta tutti i nomi presenti nel range di celle che gli avevamo assegnato nella proprietà ListFillRange. Basterà selezionare un nome, tra quelli inseriti, (per selezionare usiamo un Click del mouse), per vedere attivato il nostro codice. L'evento "Click" si verifica tutte le volte che cliccheremo nella "zona bianca" della casella, NON se clicchiamo sul triangolino nero che attiva il "menù a discesa (zona bianca o, se preferite, la lista dei nomi)". Se questo evento può generare errori per "cliccaggi" imprecisi, potrete usare l'evento "Change" che si verifica tutte le volte che si "cambia", selezionandolo dal menù a discesa, un nominativo.

Ritengo che l'attivazione di codice attraverso un "evento" collegato ad un "oggetto" sia di gran lunga da preferire, quando possibile, ad altri sistemi, compreso l'uso di un semplice "commandutton", in cui, nell'evento Private Sub CommandButton1_Click() inseriremo il nostro codice anzichè usare i moduli. (in questo caso non occorrerà dare un nome alla macro perchè il nome esiste già)