Utilizzare il VBA al posto della Funzione SOMMA.SE   (05/05/03)

Ancora un esercizio con un doppio ciclo For Each ... Next per sostituire la funzione Somma.Se non facilmente applicabile in uno schema di tabella come quello che prendiamo in esame.

Questo esercizio è rivolto a tutti coloro che disponendo di una tabella con inseriti dati alla rinfusa, vogliano reperire totali di valori, da riportare in un'altra tabella. Per "totali di valori" si possono ricercare importi, numeri, numero presenze, ore,  ecc.  ecc. riferiti a nominativi precisi, quali Ditte, Operai, Camere, Fascicoli, Nominativi in genere, Titoli i libri o di film, e chi più ne ha più ne metta. E' molto importante definire lo schema di una tabella, cioè come impostare campi (colonne) e record (righe), molto dipende infatti da una loro impostazione precisa e ordinata, scegliendo la chiave di registrazione più opportuna. Nell'esempio prenderemo quindi come chiave di registrazione una Data.

Vediamo un esempio nel quale per ogni data immessa nella colonna A, abbiamo bisogno di registrare quanti interventi eseguiamo presso una determinata Ditta. Useremo quindi le colonne seguenti la A, per riportare il numero di interventi e a lato a quale ditta si riferiscono. Disponendo di più operatori, destineremo tante coppie di colonne per quanti operatori lavoreranno. Nell'esempio ne ho considerati 5, quindi 10 colonne.

Cosa vogliamo sapere? Desideriamo tenere sotto controllo il TOTALE del numero di interventi per Cliente (ditta). Il risultato lo vogliamo in altra zona del foglio (ma potrebbe essere su un altro foglio).

Per comodità visiva per la zona di raccolta totali uso le celle da A16 a C27: nella colonna A riporteremo i nomi delle Ditte e nella colonna C otterremo i totali per ogni ditta.

Abbiamo bisogno quindi di un ciclo che per ogni ditta riportata in colonna A, zona "raccolta", "spazzoli" tutta la zona della tabella principale alla ricerca dello stesso nome ditta, e trovatala, cominci a totalizzare il valore che si trova nella cella a sinistra. Per questa "spazzolatura" (ricerca) useremo un altro ciclo interno al primo che, munito di un totalizzatore, restituisca alla fine la somma dei valori trovati. Questo totale lo affideremo alla cella della colonna C, stessa riga del nome cercato. Per ovviare all'ipotesi che i nomi scritti nella tabella degli interventi possano differire per maiuscole/minuscole dallo stesso nome scritto nella tabella di raccolta, usiamo nel modulo che ospita la routine, sezione "Generale  -  Dichiarazioni",  l'istruzione : Option Compare Text

Option Compare Text

___________________________________________________________________
Sub CercaeSomma()
Dim CL As Object
Dim C As Object
'riga sotto: per ogni cella nel range A16:A27
For Each CL In Range("A16:A27")
'riga sotto: controllo se nella cella  esiste un nome, se le cella è vuota, passo alla 'successiva (con l'ultimo next)
If CL.Value = "" Then GoTo 10
'altrimenti inizio il secondo ciclo per controllare tutte le celle nel range D1:Y59
For Each C In Range("C2:K13")
'se trovo in nome che è in A (nel CL in quel momento attuale)
If C.Value = CL.Value Then
'allora incremento un totale col valore che è nella cella accanto al nome trovato
tot = tot + C.Offset(0, -1).Value
End If
'controllo tutte le celle con Next C per controllare l'attuale nome
Next C
'finito il ciclo interno, assegno alla cella della colonna H, stessa riga di CL, il totale ottenuto
CL.Offset(0, 2).Value = tot
'poi azzero il contatore
tot = 0
10:
'e proseguo il ciclo per la successiva cella in A che ripete il ciclo interno
Next
End Sub

In pratica il primo ciclo controlla, dall'inizio alla fine, tutte le celle del Range A16:A27, e per ogni cella, attiva il secondo ciclo che ricerca nel Range C2:K13 tutte le celle il cui valore corrisponde, sommando i valori che sono nella cella a sinistra (Offset(0, -1)). E' evidente che se le aree saranno diverse basterà indicare negli appositi range i riferimenti che ci necessitano. Se poi la tabella di destinazione risiedesse su un'altro foglio, oltre ovviamente a definire il range diverso in cui si troveranno i nomi ditte di cui vogliamo il totale, useremo l'accortezza di lanciare la macro da questo foglio, e nelle istruzioni cambierà solamente l'indicazione della zona dove effettuare la ricerca, aggiungendo il nome del foglio, così:

For Each C In Worksheets(1).Range("C2:K13")

 

Buon lavoro.

prelevato sul sito http://ennius.interfree.it