Per esercitarci nell'uso degli array, creeremo la nostra versione della macro che abbiamo utilizzato per dimostrare il vantaggio in termini di velocità degli array, passo dopo passo...
Ecco il punto di partenza di questo esercizio (vedrai che il set di dati è stato ridotto a 1000 righe):
Qui puoi scaricare il file di esempio Excel: arrays_exercise.xls
Obiettivo dell'esercizio: la procedura dovrebbe scorrere i dati nel set di dati e contare il numero di risposte SÌ o NO per ogni anno e per ciascun numero di cliente (SÌ o NO a seconda della scelta dell'utente) e inserire questa quantità nella cella specificata di il foglio di lavoro.
Completa la seguente macro per salvare i dati dal foglio di lavoro "DS" in un array:
Sub actualize() Dim last_row As Integer 'L'ultima riga del set di dati '... 'Salvataggio di un set di dati in un array dinamico Dim array_db() '... End Sub
Ecco una soluzione di esempio:
Sub actualize() Dim last_row As Integer 'L'ultima riga del database last_row = Sheets("DS").Range("A1").End(xlDown).Row 'Salvataggio di un set di dati in un array dinamico Dim array_db() ReDim array_db(last_row - 2, 2) For row_number = 2 To last_row array_db(row_number - 2, 0) = Sheets("DS").Range("A" & row_number) array_db(row_number - 2, 1) = Sheets("DS").Range("B" & row_number) array_db(row_number - 2, 2) = Sheets("DS").Range("C" & row_number) Next End Sub
Questo sostanzialmente ripete ciò che abbiamo fatto nella lezione precedente...
Ma ora dobbiamo modificare la nostra macro aggiungendo le seguenti azioni:
Ecco una soluzione di esempio:
Sub actualize() Dim last_row As Integer, search_value As String, insert_row As Integer, value_yes_no As String, rows_number As Integer 'L'ultima riga del database last_row = Sheets("DS").Range("A1").End(xlDown).Row 'Valore di ricerca (YES o NO) If Sheets("RES").OptionButton_yes.Value = True Then search_value = "YES" Else search_value = "NO" End If 'Numero di risposte YES o NO rows_number = WorksheetFunction.CountIf(Sheets("DS").Range("C2:C" & last_row), search_value) 'Salvataggio di un set di dati in un array Dim array_db() ReDim array_db(rows_number - 1, 1) insert_row = 0 For row_number = 2 To last_row value_yes_no = Sheets("DS").Range("C" & row_number) If value_yes_no = search_value Then array_db(insert_row, 0) = Sheets("DS").Range("A" & row_number) array_db(insert_row, 1) = Sheets("DS").Range("B" & row_number) insert_row = insert_row + 1 End If Next End Sub
La ricerca per scelta dell'utente è determinata all'inizio della procedura dal seguente codice:
'Valore di ricerca (YES o NO) If Sheets("RES").OptionButton_yes.Value = True Then search_value = "YES" Else search_value = "NO" End If
Utilizzeremo la funzione CountIF per determinare il numero di risposte "SI" o "NO":
'Numero di risposte YES o NO rows_number = WorksheetFunction.CountIf(Sheets("DS").Range("C2:C" & last_row), search_value)
L'array è stato ridimensionato per adattarsi al numero di risposte SI o NO e ridotto a due colonne:
ReDim array_db(rows_number - 1, 1)
Questi dati verranno ora archiviati nell'array quando la sua terza colonna corrisponde alla selezione dell'utente:
'Inserimento di un numero in un array insert_row = 0 'Elaborazione del set di dati For row_number = 2 To last_row 'Valore della colonna C (YES o NO) value_yes_no = Sheets("DS").Range("C" & row_number) 'Se il valore corrisponde alla selezione dell'utente, la stringa viene archiviata nell'array If value_yes_no = search_value Then 'Salvataggio del valore nella colonna A array_db(insert_row, 0) = Sheets("DS").Range("A" & row_number) 'Salvataggio del valore nella colonna B array_db(insert_row, 1) = Sheets("DS").Range("B" & row_number) 'Una riga è stata salvata => il numero di inserimento nell'array viene incrementato di 1 insert_row = insert_row + 1 End If Next
Il nostro array contiene solo i dati che ci interessano.
Tutto ciò che resta da fare è:
Ecco una soluzione di esempio:
'Numero di risposte "YES"/"NO" For no_years = 2011 To 2026 For no_client = 1 To 30 counter = 0 For i = 0 To UBound(array_db) If Year(array_db(i, 0)) = no_years And array_db(i, 1) = no_client Then counter = counter + 1 End If Next Cells(no_years - 2009, no_client + 1) = counter Next Next
Problema risolto con i commenti che lo spiegano in dettaglio:
'Ciclo per ogni riga For no_years = 2011 To 2026 'Ciclo per ogni colonna For no_client = 1 To 30 'Reset del contatore counter = 0 'Elaborazione di matrici For i = 0 To UBound(array_db) 'Verificare che la riga della tabella corrisponda all'anno e al numero cliente If Year(array_db(i, 0)) = no_years And array_db(i, 1) = no_client Then 'Se l'anno e il numero cliente coincidono il contatore aumenta di 1 counter = counter + 1 End If Next 'Dopo aver elaborato l'array, il risultato viene inserito nella cella corrispondente Cells(no_years - 2009, no_client + 1) = counter Next Next
E infine, il codice per la nostra intera macro:
Sub actualize() Dim last_row As Integer, search_value As String, insert_row As Integer, value_yes_no As String, rows_number As Integer, counter As Integer 'Eliminazione di contenuti Range("B2:AE17").ClearContents 'L'ultima riga nel set di dati last_row = Sheets("DS").Range("A1").End(xlDown).Row 'Valore di ricerca (YES o NO) If Sheets("RES").OptionButton_yes.Value = True Then search_value = "YES" Else search_value = "NO" End If 'Numero di risposte YES o NO rows_number = WorksheetFunction.CountIf(Sheets("DS").Range("C2:C" & last_row), search_value) 'Salvataggio di valori in un array Dim array_db() ReDim array_db(rows_number - 1, 1) insert_row = 0 For row_number = 2 To last_row value_yes_no = Sheets("DS").Range("C" & row_number) If value_yes_no = search_value Then array_db(insert_row, 0) = Sheets("DS").Range("A" & row_number) array_db(insert_row, 1) = Sheets("DS").Range("B" & row_number) insert_row = insert_row + 1 End If Next 'Conteggio delle risposte YES o NO For no_years = 2011 To 2026 For no_client = 1 To 30 counter = 0 For i = 0 To UBound(array_db) If Year(array_db(i, 0)) = no_years And array_db(i, 1) = no_client Then counter = counter + 1 End If Next Cells(no_years - 2009, no_client + 1) = counter Next Next End Sub
Qui puoi scaricare il file di esempio Excel: arrays_exercise_completed.xls