Per eliminare i duplicati c'è la funzione apposita di excel (cerca nell'help o su google e dovresti trovarla facilmente), mentre per eliminare i buchi basta ordinare le righe (anche qui c'è una funzione apposita) in modo che tutti i buchi vadano in cima e poi si eliminano a mano, in un colpo solo, tutte le righe vuote.
Veniamo ai conteggi.
Per semplificare ho fatto direttamente gli interventi nel tuo foglio ma il problema è che il VBA per queste cose è veramente poco pratico comunque ho già fatto parecchio quindi dovresti poter andare avanti da sola, anche perché io adesso devo uscire.
Però devo spiegartelo per bene se no non ci si capisce niente.
Per prima cosa ho aggiunto nel foglio resoconto un pulsantino rosso che, cliccato, effettua tutti i calcoli in modo da svincolarci dai gestori degli eventi e rendere tutto più semplice.
Per modificare l'estetica del pulsante devi entrare in "modalità di progettazione" ed andare col tasto destro nelle proprietà.
La modalità di progettazione la trovi nella scheda sviluppo (se non ce l'hai devi attivarne la visualizzazione dalle opzioni di excel).
Il codice invece lo trovi con ALT-F11, vediamolo.
Per prima cosa c'è una lunga lista di istruzioni che servono a definire e valorizzare delle variabili per dare al vba i riferimenti su cui lavorare, se il foglio che mi hai mandato è uguale a quello reale dovrebbero andare già bene però controllale anche tu che potrei aver sbagliato qualcosa.
L'unica cosa da sistemare sono i valori di prima e ultima riga dei vari fogli (ovviamente mi riferisco sempre e solo ai dati, senza considerare le righe di intestazione) perché quelli che ho usato io sono riferiti alle poche righe di dati del foglio di esempio.
Le coppie di assegnazioni, tipo questa
codice:
Resoconto_Col_CodiceApertura = "B"
Resoconto_Col_CodiceApertura = Columns(Resoconto_Col_CodiceApertura).Column
servono a trasformare la lettera della colonna nel numero corrispondente (quindi la A diventa 1, la B diventa 2, la C 3 eccetera) perché poi la funzione cells che le utilizza ha bisogno dei riferimenti numerici e non letterali.
In questo modo la variabile Resoconto_Col_CodiceApertura assumerà il valore 2 che indica che la colonna CodiceApertura nel foglio Resoconto è la seconda. E così per tutte le altre.
Quindi, in sostanza, questa prima lunga serie di assegnazioni serve solo a definire le righe e le colonne su cui si andrà a lavorare ma ancora non compie nessuna azione.
Poi segue un primo blocco di istruzioni che consiste in due cicli "For Each ... Next" nidificati uno nell'altro.
Lo scopo di queste istruzioni è di inserire nel foglio TbdRes una colonna temporanea di appoggio (io ho usato la M ma puoi usarne anche un'altra, basta indicarlo nelle definizioni iniziali) in cui inserire i valori dei codice apertura corrispondenti agli idContatto. In questo modo dopo sarà più facile fare i conteggi.
Questi due cicli non fanno altro che esaminare tutti gli IdContatto del foglio TDBRES (ciclo esterno) e, per ciascuno di essi, esaminare tutti gli idContatto del foglio CONTATTI alla ricerca di una corrispondenza e, quando la si trova, si riporta il codice apertura nel foglio TBDRES.
Mi soffermo ancora un attimo a spiegarti questi cicli perché, capiti questi, tutto il resto dovrebbe risultare più facile.
Provando a "tradurre" in italiano questa riga:
codice:
For Each TbdRes_IdContatto In Sheets("TBDRES").Range(Sheets("TBDRES").Cells(TbdRes_Prima_Riga, TbdRes_Col_IdContatto), Sheets("TBDRES").Cells(TbdRes_Ultima_Riga, TbdRes_Col_IdContatto))
diventerebbe una cosa del genere:
codice:
Individua sul foglio TBDRES il range delimitato dalle celle che hanno queste coordinate
(prima riga dati, colonna dei contatti)
(ultima riga dati, colonna dei contatti)
(praticamente punta a tutta la colonna dei contatti) ed esaminale una ad una chiamandole TbdRes_IdContatto.
L'esame di ciascuna di queste celle consiste in un altro ciclo effettuato sul foglio dei Contatti che punta anche lì a tutta la colonna dei contatti e chiama la cella in esame Tbd_Contatti_Idcontatto.
Per ognuno di questi successivi esami ciclici viene effettuata una if che si chiede se le due celle sono uguali cioè se il codice contatto che si sta esaminando sul foglio TBDRES coincide con quello che si sta esaminando sul foglio Contatti e se è così viene scritto il codice apertura prelevato dal foglio contatti sulla riga del foglio TBDRES corrispondente al codice she si sta esaminando infatti:
- Cells(TbdRes_IdContatto.Row, TbdRes_Col_Appoggio)
è la cella sulla riga del TbdRes_IdContatto in esame posta sulla colonna di appoggio
- Cells(Tbd_Contatti_Idcontatto.Row, Tbd_Contatti_Col_CodiceApertura)
è la cella sulla riga del Tbd_Contatti_Idcontatto posta sula colonna CodiceApertura.
Trovata la corrispondenza e scritto il codice apertura sul foglio TBDRES si può terminare la ricerca e passare al prossimo idContatto quindi si può uscire dal ciclo interno con Exit For.
E' tutto chiaro? Per questo ti chiedevo che conoscenze avessi di programmazione ...
Comunque cerca di capire bene la logica che sta dietro queste istruzioni così poi potrai completare da te il codice ancora mancante.
Andiamo avanti.
Gli altri due blocchi di istruzioni fanno la stessa cosa del primo sui fogli dei semiresidenti e dei territoriali quindi non te li spiego perché sono uguali.
A questo punto cosa abbiamo ottenuto? Di scrivere nella colonna M dei tre fogli il codice apertura corrispondente all'idContatto. Tutto qui. Sembra poco ma ci servirà nel seguito.
Ora c'è il ciclo dei conteggi e se ti è ben chiaro quello che ti ho detto prima questo sarà una passeggiata.
Qui il ciclo principale, quello esterno, esamina tutti i codici apertura del foglio resoconto e, per ciascuno, conta i residenti, i semiresidenti e i territoriali di ciascun anno eseguendo, per ciascuno dei tre, questa serie di operazioni:
- Azzera i contatori
- Cerca nella colonna di appoggio M caricata prima la corrispondeza del codice apertura con quello del ciclo principale e, se trovato. incrementa il contatore corrispondente all'anno della data.
- Alla fine di ciascun ciclo interno riporta nel foglio resoconto i totali ottenuti.
Mi rendo conto che se non hai conoscenze di programmazione la cosa può risultare piuttosto complessa ma col VBA non c'è tanto da scegliere, bisogna fare così.
Con Access come ti dicevo sarebbe tutto più semplice ma devi decidere tu cosa fare anche perché non ho capito cosa intendi quando dici che hai usato un software ... se hai access e il tuo file si apre si dovrebbe anche poter usare.
Però considera anche che io non ho Access ma MySql che è simile ma non proprio uguale quindi potremmo avere difficoltà anche in quel caso.
Tornando al codice restano solo le ultime istruzioni che cancellano le colonne di appoggio in modo da non lasciare dati indesiderati e un msgbox che fa comparire un pop-up.
Quello che ancora c'è da fare è il conteggio per sesso ma non dovresti avere problemi perché, tutto sommato, è simile a quello che ho già fatto mentre qualche difficoltà potresti trovarla nell'eliminazione dei duplicati nel foglio dei territoriali.
Il problema in quel caso è che i dati sono in ordine sparso (per esempio il codice 17901 lo trovo nelle righe 22 e 23 e poi in quelle da 25 a 30) e quindi non si possono applicare gli schemi classici di rottura di livello. Bisognerebbe inventarsi qualcosa ma adesso non ho il tempo di pensarci.
Un'ultima cosa: perché ci sono due codici 29530 sia nel resoconto che nei contatti?
E per finire una considerazione sui tempi perché quando dicevo che per lunedì avremmo finito mi riferivo al problema dei colori, non a questo macigno, un lavoro così grosso richiede molto più tempo per fare tutto per bene.
Comunque una parte del lavoro è fatta, spero che ti possa servire da guida per il resto. Buon lavoro.
Ciao