Usare l'Operatore LIKE
(19/07/03)
Sappiamo tutti,
almeno spero, cosa sono gli "Operatori di confronto",
eventualmente date un occhiata all'articolo "operatori
numerici" nella sezione "primi passi".
Comunque servono a confrontare due valori (testi, numeri o date). In genere
i confronti si fanno per valutare la corrispondenza esatta tra due o più
valori, oppure se un valore può essere maggiore o minore rispetto ad un
altro; ma quando abbiamo bisogno di confrontare "approssimativamente" due
valori, gli operatori normalmente usati non bastano più. Un esempio potrebbe
essere quello di cercare, in un elenco, tutti valori la cui lettera iniziale
corrisponde ad "a". Sappiamo che una parola come "atlante", che pure
comincia con "a", non verrebbe trovata in quanto in quanto i metodi di
ricerca si basano su un valore preciso fornito come chiave di ricerca, e la
stringa "a" ovviamente è diversa dalla stringa "atlante". In questi casi ci
viene in aiuto l'operatore LIKE, che vuol dire
appunto "simile a...", "come" o " che "assomiglia a..". Perchè Like ci possa
aiutare in una ricerca, va a sua volta aiutato, (indicando di seguito ad un
valore chiave per esempio la lettera "c"), un carattere speciale definito
sintatticamente "criterio", e che può
essere rappresentato da uno dei seguenti caratteri
Jolly :
-
? - (punto di domanda) che fa
corrispondere qualsiasi carattere singolo.
-
* - (asterisco) che fa
corrispondere zero o più caratteri.
-
# - (cancelletto) che fa
corrispondere qualsiasi cifra singola (0-9).
I caratteri Jolly
ci consentono quindi di sostituirsi ad elenchi di caratteri o intervalli di
caratteri in qualsiasi combinazione. Un'istruzione quindi che ci
consentirebbe di trovare "atlante" digitando solo la lettera "a",
diventerebbe:
If CL.Value Like "a*" Then
dove l'asterisco posto dopo la lettera "a" consentirebbe di riconoscere "a
tlante" perchè l'asterisco sostituisce l'intervallo di caratteri "tlante". In
parole povere, l'istruzione sopra dice:
se il valore della variabile CL comincia con "a" con
tutto quello che ci sia dopo, Then ecc. ecc.
Ma come e dove usare Like ? Essenzialmente per
eseguire ricerche di dati, di cui si voglia inserire una sola lettera
iniziale, o un numero come chiave di ricerca, e si vogliano trovare tutti i
valori che iniziano con quella lettera (o gruppo di lettere), e quel numero
(o gruppi di numeri). Avremo quindi che con la stringa di ricerca
c* -
verranno trovati tutti i valori che iniziano per "c" : catullo,
circo, caramba, cucurnia, ceffo, ecc.
ca* -
verranno trovati tutti i valori che iniziano per "ca" : catullo,
caramba
car* -
verranno trovati tutti i valori che iniziano per "car" : caramba
lo stesso dicasi
per i numeri, o per le date (più avanti troverete una
precisazione a questo proposito)
1* -
verranno trovati tutti i valori che iniziano per "1" : 10, 125,
1543, 10/07/03 ecc.
10* -
verranno trovati tutti i valori che iniziano per "10" : 10, 10/07/03
154*
-verranno trovati tutti i valori che iniziano per "154" : 1543
Abbiamo quindi
imparato un metodo flessibile che ci consente un'ampia possibilità di
variare le ricerche. Vediamo ora qualche esempio di applicazione, con
relative istruzioni e commenti (in verde). Iniziamo con chiarire come
impostare la chiave di ricerca:
inserendo la
chiave di ricerca direttamente nelle istruzioni: es.
Like "a*" ; sistema poco flessibile
perchè ci costringerebbe alla modifica dell'istruzione nel codice se
volessimo trovare altri valori che inizino con altre lettere.
usare una
cella del foglio di lavoro, nella quale di volta in volta scrivere il
valore che serva come chiave di ricerca; es. usando la cella C1, la nostra
istruzione diventerebbe Like Range("C1") & "*".
Come si nota usiamo un concatenatore
di stringa (la &) per restituire, uniti, il
valore che scriveremo in C1 seguito dall'asterisco
(carattere Jolly)
usare una
textbox se usiamo una userform, nella quale scriveremo il valore chiave di
ricerca (come sopra) e in questo caso l'istruzione sarà :
Like TextBox1 & "*"
usare una
InputBox. in questo caso dovremo assegnare ad una variabile il valore
restituito dalla InputBox, e richiamare questa variabile+asterisco dopo
Like. Sarà sufficiente compilare:
Myvar =
InputBox("Inserisci il valore da cercare")
......Like CStr(Myvar) & "*"
Ora passiamo a
vedere in quale contesto usare queste istruzioni. Molte sono le situazioni
in cui si può presentare la necessità di svolgere una ricerca, qui
sceglieremo l'esempio di cercare tutti i valori la cui iniziale
corrisponderà ad una determinata lettera, e con i dati così trovati,
riempire una ListBox. Sotto vediamo l'immagine dell'esercizio: la colonna A
è la zona dove risiedono i dati, la cella C1 è la cella che usiamo come
vettore per l'iniziale che serve a trovare nella colonna A tutti i valori
che cominciano con una lettera, in questo caso la lettera "c", e la ListBox1
con i nomi trovati
e questa la
routine usata:
Sub carica1()
Dim CL As Object
ActiveSheet.ListBox1.Clear 'predisponiamo
la pulizia della listbox per la nuova ricerca
For Each CL In Range("A1:A20") 'inizia il
ciclo di ricerca: per ogni CL (cella presente 'nel Range A1:A20 (tanto
per fare l'esempio mi fermo alla riga 20)
'sotto: se il valore che presente nella
cella in quel momento scorsa, è uguale al valore che 'è in C1*, cioè
basta che inizi con "c" (in questo caso), allora
If CL.Value Like Range("C1") & "*" Then
'carichiamo con AddItem
quel valore nella ListBox1
ActiveSheet.ListBox1.AddItem CL.Value
End If
Next
End Sub |
Basterà quindi
variare la lettera in C1 per ottenere, se presenti nell'elenco, i nomi che
iniziano per quella lettera, nella ListBox. Un'altro aspetto interessante di
questo metodo di estrazione dati, perchè di
questo si tratta, è che se nell'elenco dati esistono celle vuote, queste non
figureranno mai nella ListBox.
Qualcuno potrebbe obiettare: ma come fare per ottenere i nomi trovati, messi
in ordine alfabetico nella ListBox? E ancora: come fare perchè eventuali
dati doppi vengano riportati una sola volta? A quest'ultima domanda
rispondo: leggete l'articolo "ComboBox . ordinare la lista", dove si parla
della routine per l'eliminazione dei doppioni. Alla prima domanda rispondo.
-
applicare
un'ordinamento all'elenco a cui si attingono i dati da ricercare: i dati
trovati saranno già in ordine alfabetico.
-
creare in una
colonna fuori vista, un riepilogo dei dati estratti, applicare a questo
secondo elenco un'ordinamento ascendente, reperire quindi il
riferimento alla cella iniziale e con
End il riferimento alla
cella finale, e fornire questi riferimenti alla proprietà
ListFillRange della ListBox (anzichè usare
AddItem) in modo che la ListBox ci mostri l'elenco in ordine alfabetico.
Vediamo
un'immagine basata su quest'ultima ipotesi, dove, per comodità visive, il
secondo elenco lo ospito nella colonna D, a partire dalla cella D4. A questo
elenco è stato già applicato l'ordinamento, a destra la Listbox caricata
usando la sua proprietà ListFillRange :
E questa la
routine, le istruzioni sono un pò più complesse rispetto alla routine
carica1, ma viene svolto un lavoro diverso :
Sub carica2()
'iniziamo pulendo la
ListBox1 predisponendo alla nuova ricerca, e NON usiamo Clear, 'ma
impostiamo il ListFillRange a vuoto ("")
ActiveSheet.ListBox1.ListFillRange = ""
Dim CL As Object 'dichiariamo CL
come "oggetto" (usato nel ciclo For Each..Next)
Dim iRow As Integer 'dichiariamo la
variabile iRow come Integer (è la variabile con la 'quale impostiamo
da quale riga iniziare il riepilogo dei dati trovati (il secondo
elenco)
iRow = 3 'rendiamo iRow uguale a 3,
cioè il riepilogo inizierà dalla riga 3
Range("D:D").ClearContents 'Puliamo
tutta la colonna destinata al riepilogo, e la puliamo 'tutta in quanto
non sappiamo quanto lungo era il riepilogo precedente.
'sotto: ATTENZIONE :
istruzione necessaria per ripristinare tutta la colonna destinata al
'riepilogo, impostando il formato celle a "Generale". Operazione
necessaria nel caso in cui 'si cerchino occasionalmente anche valori
tipo data (es. 10/07/03), quando il dato 'cercato viene trovato, se è
una data, Excel nel copiare la data nel riepilogo, modifica 'anche il
formato della cella che ospiterà la data a formato cella data. Questa
'impostazione rimane anche per le nuove ricerche, e se nella nuova
ricerca venissero 'cercati numeri anzichè date, il numero che finisse
dove prima era stata ospitata una data, 'sarebbe errato e inservibile.
Range("D:D").NumberFormat = "General"
'sotto: si imposta il
valore della cella, ora riga 3, 4 colonna, cioè la D, a "riepilogo"
come 'se fosse un'intestazione di campo
Cells(iRow, 4).Value = "riepilogo"
'sotto: si inizia il ciclo
di ricerca nel Range A1:A20, ognuno metterà i suoi riferimenti
For Each CL In Range("A1:A20")
'sotto: se il valore che è presente nella
cella in quel momento scorsa, è uguale al valore 'che è in C1*, cioè
basta che inizi con "a" (in questo caso), allora
If CL.Value Like Range("C1") & "*" Then
'inizia il ciclo interno
per cercare una cella libera, colonna D (4) dove scrivere il valore
'trovato sopra (CL.Value)
Do While Cells(iRow, 4).Value <> "" 'fino
a che la cella è occupata
iRow = iRow + 1 'si passa a controllare
la cella sottostante (+1) e si continua con Loop
Cells(iRow, 4) = CL.Value 'quando si
verifica che una cella è vuota, gli si passa il valore 'rappresentato
da Cl.Value
Exit Do 'e si esce dal ciclo Do While..Loop
Loop 'altrimenti si continua a cercare
una cella vuota ritornando a Do While
End If
Next ' con Next si scorrono, una ad una
le celle del Range A1:A20
'a questo punto, finita la
ricerca e caricato il "riepilogo", abbiamo bisogno di reperire gli 'Address, cioè gli indirizzi
delle celle che delimitano il "riepilogo"
lista = Cells(4, 4).Address 'con "lista"
prendiamo l'indirizzo della cella riga 4, colonna 4 '(D4)
nera = Cells(4, 4).End(xlDown).Address
'con "nera" reperiamo l'ultima cella occupata 'della colonna D.
'sotto: applichiamo
l'ordinamento ai range i cui estremi sono stati trovati con le due
'variabili
Range(lista & ":" & nera).Sort Key1:=Range("D4"), Order1:=xlAscending,
Header:= _
xlGuess, OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom
'e alla fine carichiamo la
ListFillRange della ListBox1 con l'assegnazione dei range di
'pertinenza
ActiveSheet.ListBox1.ListFillRange = (lista & ":" & nera)
End Sub |
Sotto riporto,
senza spiegazioni (sono uguali), la routine che si avvale di una InputBox
per reperire il valore da cercare:
Sub caricainput()
ActiveSheet.ListBox1.ListFillRange = ""
Dim CL As Object
Dim iRow As Integer
iRow = 3
cosa = InputBox("Scrivi cosa cerchi")
'con "cosa" prendiamo il valore da cercare
Range("D:D").ClearContents
Range("D:D").NumberFormat = "General"
Cells(iRow, 4).Value = "riepilogo"
For Each CL In Range("A1:A20")
If CL.Value Like CStr(cosa) & "*" Then 'e
usiamo la variabile stringa "cosa" al posto 'dell'indicazione di una
cella
Do While Cells(iRow, 4).Value <> ""
iRow = iRow + 1
Cells(iRow, 4) = CL.Value
Exit Do
Loop
End If
Next
lista = Cells(4, 4).Address
nera = Cells(4, 4).End(xlDown).Address
Range(lista & ":" & nera).Sort Key1:=Range("D4"), Order1:=xlAscending,
Header:= _
xlGuess, OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom
ActiveSheet.ListBox1.ListFillRange = (lista & ":" & nera)
End Sub |
Unica
precisazione: il carattere Jolly * (asterisco),
può essere usato come valore iniziale da cercare, seguito da una o più
lettere, e quindi ancora un asterisco. In questo modo possiamo trovare
valori al cui interno compaia la lettera o le lettere digitate tra gli
asterischi. Esempio: se in C1 o nella InputBox scriviamo
*lo*, verranno trovati tutti i nomi al cui
interno compare la coppia "lo", cioè : bellotti, cellosi,
luppolo .
Buon lavoro.
prelevato sul sito http://ennius.interfree.it |