Propongo un veloce esercizio in VBA sull’utilizzo dei dizionari.
Immaginiamo di avere un elenco di studenti e voti in diverse materie come nell’esempio seguente:
Vogliamo calcolare la media dei voti per ciascun studente in ciascuna materia, mettendo tutto in una tabella tipo pivot nel modo seguente:
A tale scopo realizziamo la seguente macro in VBA utilizzando i dizionari. Per usare il dizionario anzitutto aggiungiamo il relativo riferimento da Strumenti > Riferimenti…
Il riferimento che ci interessa è il Microsoft Scripting Runtime, libreria dalla quale andremo a prelevare Scripting.Dictionary
Fatto tutto questo vediamo il codice:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
Sub calcolo() Dim voti As Scripting.Dictionary Set voti = New Scripting.Dictionary riga_inizio = 3 Do nome = Cells(riga_inizio, 1) materia = Cells(riga_inizio, 2) voto = Cells(riga_inizio, 3) If nome = "" Then Exit Do If Not voti.Exists(nome) Then Set voti(nome) = New Scripting.Dictionary End If If Not voti(nome).Exists(materia) Then voti(nome)(materia) = 0 voti(nome)(materia & "_tot") = 0 End If voti(nome)(materia) = voti(nome)(materia) + voto voti(nome)(materia & "_tot") = voti(nome)(materia & "_tot") + 1 riga_inizio = riga_inizio + 1 Loop righe_risultati = 0 colonne_risultati = 0 Do studente = Cells(11 + righe_risultati, 12) If studente = "" Then Exit Do Do materia = Cells(10, 13 + colonne_risultati) If materia = "" Then Exit Do If voti(studente)(materia & "_tot") > 0 Then Cells(11 + righe_risultati, 13 + colonne_risultati) = voti(studente)(materia) / voti(studente)(materia & "_tot") colonne_risultati = colonne_risultati + 1 Loop righe_risultati = righe_risultati + 1 colonne_risultati = 0 Loop End Sub |
Faccio notare che nel mio esempio la tabella di scrittura parte dalla posizione L10 nel foglio di calcolo attivo.
Quello che abbiamo realizzato è un dizionario di dizionari. Per realizzarlo utilizziamo:
1 2 3 4 5 6 7 8 |
If Not voti.Exists(nome) Then Set voti(nome) = New Scripting.Dictionary End If If Not voti(nome).Exists(materia) Then voti(nome)(materia) = 0 voti(nome)(materia & "_tot") = 0 End If |