Pietrol, per favore non farci arrossire
, e scrivi invece piu' spesso
...
Per Flash:
PERO' trovo pericoloso suggerire una macro che cancella tutti i fogli esistenti eccetto qualcuno; meglio cancellare solo i fogli di cui si conosce l' esistenza e la loro non necessita'.
La macro, mi sembra che produce una copia dell' archivio "filtrata" con Cognome&Nome; un dato intermedio da cui si dovrebbe attingere poi per la ricerca e il popolamento della Maschera; ma con questa logica creare una copia dell' archivio non serve, perche' basterebbe cercare la prima riga che ha quel Nome/Cognome e trasferirla in Maschera.
Io pero' propenderei per una strada leggermente diversa, partendo da presupposto che fatto il controllo dei Nomi poi ci saranno gli omonimi con data di nascita diversa, e poi uno non fa mica solo lo stesso tipo di esame...
Ma prima facciamo un passo indietro, e mi rivolgo a Darix.
L' errore occorre perche' la variabile I non e' inizializzata, quindi in quel momento provi ad accedere alla cella C0.
In realta' manca nella macro tutto il ciclo per scorrere all' indietro l' elenco e verificare il cognome: avevi ustao For
Ri = Sheets("Archivio").Cells(Rows.Count, 1).End(xlUp).Row To 1 Step -1 / Next Ri, che devi inserire attorno alle tue istruzioni (dopo il caricamento dell' array); questo significa anche che nell' istruzione ora in errore dovrai usere "Ri" e non "I" (variabile che e' usata nel ciclo di trasferimento dati).
Ci sono poi alcuni errori, che ho corretto in questa versione della tua macro:
- Codice: Seleziona tutto
Sub CopiaDati()
Dim Rng As Range
Dim SH1 As Worksheet
Dim SH2 As Worksheet
Dim WB As Workbook
Dim Arr As Variant
Dim I As Long, Ri As Long
Set WB = ActiveWorkbook
Set SH1 = WB.Sheets("Maschera Dati")
Set SH2 = WB.Sheets("Archivio")
Set Rng = SH2.Range("C6:EW6") 'Questa e' inutile
Arr = Array("C8", "C9", "C10", "C11", "C12", "C13", "C14", "C16", "C17", "C22", "C23", "C24", "C25", "D24", "D25", "C30", "C31", "C32", "C33", _
"C34", "E30", "E32", "E33", "C36", "C38", "E37", "E38", "C41", "C42", "C43", "E41", "E42", "C46", "C47", "C48", "C49", "E46", "C52", "C53", _
"C54", "C55", "C56", "C57", "C58", "C59", "D56", "E52", "E53", "G53", "C78", "C90", "C92", "C93", "C95", "C96", "C97", "C98", "E98", "C103", _
"C104", "C105", "C106", "C107", "C108", "C109", "C110", "C111", "C112", "C117", "C118", "C119", "C120", "C121", "C123", "C124", "C125", _
"C126", "C127", "C128", "C129", "C130", "C131", "C133", "C134", "C136", "C137", "C152", "D155", "E155", "D156", "E156", "D157", "E157", _
"D158", "E158", "D159", "E159", "D160", "E160", "D161", "E161", "D162", "E162", "C164", "C168", "C169", "C170", "C171", "C172", "C173", "C174", _
"C175", "C176", "C177", "C178", "C179", "C180", "C181", "C188", "C189", "C190", "C191", "C192", "C193", "C194", "C195", "C196", "C197", "C198", _
"C199", "C200", "C201", "C202", "C203", "C204", "C205", "C206", "C207", "C208")
For Ri = Sheets("Archivio").Cells(Rows.Count, 1).End(xlUp).Row To 5 Step -1 '**1
If Sheets("Archivio").Cells(Ri, 3).Value = Sheets("Maschera Dati").Range("C8").Value Then '**2
For I = 0 To UBound(Arr) '**3
SH1.Range(Arr(I)).Value = SH2.Cells(Ri, I + 3).Value '**4
Next I '**5
MsgBox "Richiamo record completato", vbInformation, "Avviso" '**6
Exit Sub '**7
End If
Next Ri '**1
MsgBox ("Non ci sono record con questa chiave di ricerca: " & vbCrLf & _
Sheets("Maschera Dati").Range("C8").Value) '**8
End Sub
Le note:
**1: questo loop mancava ed e' stato inserito
**2: avevi usato come termine di paragone Sheets("Archivio").Cells(i, 3).Value, ma l' indice giusto e' Ri
**3: da 0 perche' 0 e' la base, a "to UBound(Arr)" significa "fino all' elemento piu' alto nell' array; ovviamente dovrebbero esserci in array tanti valori quante le celle da caricare: io ho contato 139 elementi in array, non so se il numero e' giusto perche' non so dove arriva l' archivio (e se va da col C a EW allora sono 151 celle, e non quadrerebbe).
**4: modificato il secondo termine
**5: e' presente un altro ciclo For /Next, meglio essere espliciti
**6: ho portato fuori dal ciclo di trasferimento questo messaggio, altrimenti ti saresti innervosito con 100-150 "Ok"
**7: questo mancava, e serve a uscire trovato il primo confronto
**8: questo l' ho aggiunto
Attenzione, questa macro funziona (probabilmente), ma non e' quella che cerchi, visto che (me l' aspettavo) non basta confrontare il cognome. Un primo approccio e' quello usato da Flash, che confronta in concatenamento tra Cognome e Nome.
Poiche' temo che Cognome+Nome non basta, io propongo:
-ti fai un foglio "Intermedio", dove una macro1 riporta tutti i record di Storico che corrispondono al Cognome immesso; ovviamente non riporterai le 100 e passa celle dell' Archivio, ma solo quelle N che consentono di qualificare l' esame (invento: Cognome, Nome, data di nascita, data esame, tipo di esame, ...), ma in prima colonna metterai l' indice della riga su Archivio (corrisponde al valore di Ri).
-ordini i dati per Nome, data di esame, tipo di esame
-usi questo elenco per scegliere quale esame ricopiare nella Maschera dati, tramite selezione riga e una macro2
La macro1 e' similissima a quella che ti ho dato prima, con la variante che non si esce alla prima riga trovata, userai un array con le colonne che vuoi riportare da Archivio su Intermedio, e' preceduta dall' azzeramento delle righe da 2 a 1000 (in riga 1 avrai messo le intestazioni) ed e' seguita dall' ordinamento dei dati presenti. Il codice per queste due operazioni lo ottieni tramite Registra nuova macro.
Potrebbe essere anche quella usata da Flash, ma il
Delete(row)+Shift(xlUp) non e' proprio velocissimo e in questo metodo (visto che l' obiettivo non e' creare un duplicato delle righe di Archivio, ma una sintesi), non sarebbe nemmeno sufficiente.
La macro2 e' un sotto-insieme della macro "CopiaDati", salvo che Ri lo hai gia' dalla colonna A della riga selezionata su Intermedio, quindi procedi subito al trasferimento senza la ricerca.
Spero che trovi qualcosa di utile, comunque fai sapere come procedi e dove arrivi.
Ciao.