ListBox - Ricercare ed evidenziare un dato nella Lista. - pagina vista: volte

Requisiti: conoscenza delle proprietà ListIndex e List(riga, colonna) di una ListBox (Casella combinata ActiveX) montata su UserForm.

Questo esercizio può aiutare coloro che usano ListBox su UserForm per riepilogare (metodo AddItem) dati presenti in intervalli sul foglio di lavoro, e che hanno già impostato le necessarie procedure per caricare la Lista con i dati, e comunque utilizzino procedure per l'inserimento o l'aggiornamento dei dati stessi (contenuti nella tabella database presente su un foglio di lavoro) .

L'esempio l'ho strutturato su una ipotetica gestione (inserimento, carico, scarico) di un magazzino (ma è evidente che il concetto si adatta alla gestione di qualsiasi tipo di dati (articoli di magazzino, gestione clienti, gestione fornitori, gestione dipendenti, gestione librerie, ecc. ecc.) e si può sfruttare la procedura sottostante sia per controllare se un nuovo dato è da inserire, sia per rintracciare un dato da modificare, e si voglia svolgere la ricerca non già nell'elenco stesso del foglio, ma nell'elenco presente nella ListBox. (le procedure per la gestione completa del progetto non vengono citate in questo articolo).

L'esercizio è facile da capire, e sfrutta la proprietà Selected di una ListBox, proprietà che richiede di indicare un numero che rappresenta il numero indice della riga da selezionare (ListIndex) , e di impostare a True la proprietà stessa, per capire, un istruzione del genere:

  • ListBox1.Selected(numero indice della riga) = True

questa istruzione provoca la selezione della riga indicata col numero indice.

Nell 'esempio che ho approntato, utilizzo una ListBox a due colonne, la prima colonna (colonna Index 0) rappresenta i codici articolo, la seconda colonna (colonna Index 1) rappresenta i nomi degli articoli; faccio svolgere una ricerca impostata con l'operatore Like, (Vedi articolo) in modo che il criterio di ricerca, rappresentato da ciò che scriveremo in una TextBox2, anche se non completo, ci permetta di identificare tutti gli elementi della lista che contengono almeno una parte di ciò che sarà nella TextBox2 e che sarà letta nel ciclo, dalla proprietà List(r, c). Sarà inoltre opportuno usare (da mettere in Generale - Dichiarazioni del modulo) l'istruzione Option Compare Text per uniformare nella ricerca le maiuscole/minuscole.

Una Routine esemplificativa può essere la seguente:

Sub SelezionaItemListBox()

Dim Quanti, Cont, R, Cosa
Quanti = ListBox1.ListCount - 1 
'con la variabile "Quanti" reperiamo il numero degli elementi (gli Item) presenti nella ListBox
Cosa = TextBox2.Text      'la variabile "Cosa" rappresenta il criterio da cercare, andrà bene qualsiasi mezzo di reperimento del criterio, 'come un riferimento ad una cella contenente un dato, oppure usare una InputBox, una costante inserita nel codice, ecc. ecc.
Cont = 0                           
'impostiamo una variabile (Cont) come contarighe a zero
For R = 0 To Quanti - 1     
 'iniziamo un ciclo For Next per scorrere l'elenco degli Item, e dato che il ListIndex inizia da zero, ci 'fermeremo nel ciclo al numero "Quanti" meno 1. Quindi impostiamo l'istruzione condizionale If che controllerà se cio che sarà nella ListBox, riga R, colonna 1 (la seconda) è simile o uguale a ciò che è scritto nella textbox2
If ListBox1.List(R, 1) Like "*" & Cosa & "*" Then     
'se la comparazione si verifica, allora....

Dim idomanda As Integer    
'impostiamo una richiesta se proseguire con la ricerca o fermarsi
idomanda = MsgBox("Trovato " & ListBox1.List(R, 1) & ". Vuoi Cercare ancora?", vbYesNo)
If idomanda = vbYes Then    
'se risponderemo SI saltiamo all'istruzione Next
GoTo 10
Else               
 'altrimenti, se avremo deciso di fermarci, (pulsante NO) selezioniamo la riga rappresentata dal contarighe Cont
ListBox1.Selected(Cont) = True
Exit Sub          
'ed usciamo dalla routine e anche dal ciclo
End If

End If
10
Cont = Cont + 1         
 'se non siamo usciti, incrementiamo il valore di Cont di una unità prima di passare all'Item successivo
Next
MsgBox "FINE RICERCA"  
 'se non siamo già usciti, avvisiamo che siamo a fine ricerca (alla  fine del ciclo)

End Sub

 

e queste due sotto le immagini della sequenza provocata della macro SelezionaItemListBox(). ho scritto nella textbox2 il valore 155 e la ricerca tramite Like restituisce una voce contenente il numero 155, smettiamo la ricerca premendo il pulsante NO, e viene selezionata la riga della voce rintracciata. (l'azione corrisponde all'evento Click sulla ListBox, al quale evento sono associate le istruzioni per restituire nelle textbox i dati relativi all'articolo selezionato e presenti nelle celle della tabella database sul foglio.

 


Multiselezione.

Se anzichè eseguire la ricerca con conferma o meno di proseguire, volessimo vedere selezionati tutti i dati corrispondenti ad un certo criterio, in modo da avere una panoramica di tutte le presenze nella lista, possiamo modificare la proprietà MultiSelect della ListBox impostandola al valore 2 (alias fmMultiSelectExtended. Nella foto sotto un esempio dove a fronte del criterio "Lib" scritto nella TextBox2 vengono rilevate e selezionate tutte le occorrenze dove appare la stringa "Lib":

Vediamo la routine che ha generato la situazione della foto sopra: (non commento le istruzioni, si spiegano da sole)

Private Sub CommandButton11_Click()
Dim Quanti, Cont, R
ListBox1.MultiSelect = fmMultiSelectExtended  
'inseriamo l'istruzione per impostare la possibilità di selezionare più righe insieme
Quanti = ListBox1.ListCount - 1

Cont = 0
For R = 0 To Quanti - 1
If ListBox1.List(R, 1) Like "*" & TextBox2 & "*" Then

ListBox1.Selected(Cont) = True

End If
Cont = Cont + 1
Next
MsgBox "FINE RICERCA"
End Sub

Vanno precisate alcune cose:

  1. quando la proprietà MultiSelect è impostata a Extended , la proprietà Value del controllo è sempre Null, cioè non possiamo ovviamente visualizzare nessun dato nei campi (textbox) associati in quanto non è possibile rilevare un unico valore di ListIndex.

  2. La guida in linea ci dice che la proprietà ListIndex restituirà l'indice della riga che ha ricevuto lo stato attivo tramite la tastiera.

La cosa non appare del tutto giusta, a me infatti risulta impossibile riuscire a selezionare, cliccando o scorrendo con il tasto TAB, nessuno dei valori evidenziati: dovremmo infatti poter selezionare uno degli elementi evidenziati per poter rilevare il suo numero indice in modo da riuscire a visualizzare i campi associati nelle relative textbox, ma poichè il Value del controllo è Null, risulta disabilitato l'evento Click della ListBox nè tantomeno sfruttabile il tasto tAB..

E' necessario quindi disattivare l'impostazione Extended impostando il Multiselect a Single (alias valore 0) sfruttando un'altro evento della ListBox, che consenta di riattivare l'evento Click, io suggerisco l'evento MouseDown, inserendo una semplice istruzione: impostare a Single il MultiSelect, così:

  • Private Sub ListBox1_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
    ListBox1.MultiSelect = 0
    End Sub

Cliccando infatti su uno degli elementi evidenziati riusciamo ora a ripristinare l'evento Click al quale avevamo associato le istruzioni per rilevare il numero Indice di ListIndex e quindi a gestire l'associazione campi associati - textbox.

Conclusioni.

Questo articolo non contempla tutte le istruzioni usate per realizzare una gestione inserimento o modifica articoli come il progetto completo contiene, ma ha voluto soltanto mostrare come evidenziare e selezionare voci nella lista di una ListBox e le istruzioni a ciò dedicate.


 

Buon lavoro

prelevato sul sito www.ennius.altervista.org