Trovare un dato (vettore) in una tabella, con restituzione di un dato correlato.

La ricerca di dati è uno degli "sport" preferiti dagli Excelnauti. La varietà delle necessità delle ricerche è tale, che è impensabile esemplificarli tutti. Stasera una richiesta mi fornisce lo spunto per esaminare un metodo di ricerca che può essere semplice da capire e al tempo stesso adattabile, con poche modifiche, in modo che i concetti usati siano sfruttabili da chiunque. Se vogliamo, l'esempio che faremo, richiama a grandi linee il comportamento delle funzioni CERCA.VERT e CERCA.ORIZ unite insieme: ognuna di queste funzioni, ricerca un dato (vettore) in un elenco di dati su più colonne o righe, restituendo il valore che si troverà sulla stessa riga, o colonna,  del vettore trovato, ma in una colonna o riga scelta in precedenza. L'esempio:

  • una tabella di dati su un foglio (Foglio1), formata da più colonne; nella colonna A della tabella una serie di valori.

  • un'altra tabella su un'altro foglio (Foglio2), formata anch'essa da più colonne e righe: da B1 a Z100, in ognuna di queste celle si trovano dei valori, e in una sola delle celle di questa zona si può trovare uno qualsiasi dei valori presenti nella colonna A del foglio1. Nella colonna A ma sempre del Foglio2 (quindi da A1 a A100) si trovano dei valori correlati.

  • esercizio : vogliamo che selezionando una cella contenente un valore nella colonna A del foglio1, venga trovato lo stesso valore nella tabella sul foglio2, nella zona B1:Z100, ma non vogliamo il valore trovato, bensì il valore presente nella stessa riga ma nella colonna A.

  • I valori presenti nel Range(B1:Z100) sono univoci, ma non sappiamo dove sono.

La procedura è semplice: selezioniamo sul foglio1 la cella con il valore da cercare, attiviamo la macro che avremo associato ad un pulsante, indichiamo con una variabile il valore della cella da cercare (X), iniziamo un ciclo di ricerca di X nella zona Foglio2 , Range B1:Z100, trovato il valore, selezioniamo la cella, ci spostiamo a inizio riga, selezioniamo quindi la cella stessa riga ma della colonna A, e restituiamo il valore della cella ora attiva, con una MessageBox. Ovviamente potremmo restituire detto valore in qualunque cella lo volessimo, con un semplice: Range("tuacella").Value = ActiveCell.Value

Questa la procedura:

Sub cercalapippo()

'evitiamo i saltellamenti a schermo
Application.ScreenUpdating = False

'siamo sul foglio1, abbiamo selezionatoo una cella e ne assegnamo il valore ad una 'variabile, la X
X = Selection.Value

'ci spostiamo sul foglio2 dove esiste la zona in cui eseguire la ricerca Range("B1:Z10")

Worksheets(2).Select

'dichiariamo una variabile di tipo Object
Dim CL As Object

'inizia il ciclo di ricerca: per ogni cella (CL) nel range previsto
For Each CL In Worksheets(2).Range("B1:Z100")

'se il valore della cella (CL) è uguale al valore della X
If CL.Value = X Then

'allora selezioniamo la cella (CL)
CL.Select
'ora dalla cella selezionata, ci spostiamo a inizio riga e selezioniamo la cella inizio riga
With ActiveCell
Cells(ActiveCell.Row, 1).Select
End With
'rendiamo il valore della cella attiva nella colonna A con un messaggio
MsgBox "Il valore è " & ActiveCell & ""

End If
Next

'ritorniamo sul foglio1
Worksheets(1).Select
End Sub

E' evidente che potrete avere in "restituzione" qualunque valore di qualsiasi colonna. Uno dei problemi delle ricerche è che spesso non sappiamo dove si troverà il valore che cerchiamo, e risulta problematico quindi fornire richieste di dati correlati, visto che Excel lo può fare solo se gli si danno delle coordinate precise. Impossibile quindi impostare a priori istruzioni che dicano "restituisci il valore che si trova due colonne a destra o 3 colonne a sinistra", visto che non sapremo quale sarà la colonna in cui esisterà il valore cercato. L'istruzione Cells(ActiveCell.Row, 1).Select  invece ci permette di determinare con esattezza di quale colonna, stessa riga, vorremo il valore restituito, modificando il numero presente nell'istruzione; se avessimo voluto in valore che si trovava nella colonna C avremmo dovuto scrivere: Cells(ActiveCell.Row, 3).Select

Se il valore cercato (X) non è presente nella zona ricerca (Range("B1:Z100")), la routine non porterà risultato e quindi nessun messaggio. Se invece saranno presenti più valori X, verrà riportato il valore associato alla prima riga dove sarà presente il primo valore X, poi il successivo, fino all'ultimo dove il ciclo però si fermerà, e solo l'ultimo sarà visualizzato, o memorizzato nel caso si usi una cella per la destinazione del valore correlato, a meno che non si usi un'istruzione che a partire dalla cella di destinazione prevista, non cerchi una cella in una riga libera; in questo caso saranno registrati tanti valori X correlati quanti saranno i valori X trovati.

 

Buon lavoro.

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