Visual Basic Simple
Ricercare un elemento in una ListBox
Sincronizza Indice
Sincronizza Indice
Scarica il progetto
Scarica il progetto
Scarica il testo dell'articolo
Testo dell'articolo
Stampa l'articolo
Stampa l'articolo
Ricerca personalizzata

Richiesta di: Gnappo - 12 Giugno 2002
Difficoltà: 2 / 5

Ho un ListBox con molte righe, e dovrei cercare tra tutte queste righe una stringa particolare...
Come posso fare evitando di dover fare un loop e controllare queste righe una per una?


La soluzione al problema è alquanto semplice e richiede l'invio di un semplice messaggio API alla ListBox da cui ricercare i dati. Mediante un primo messaggio è possibile ricercare il testo esatto richiesto, mentre con un altro messaggio è anche possibile ricercare la prima occorrenza che inizia con il testo specificato.

Abbiamo un semplicissimo form contenente fondamentalmente una ListBox di nome lstElenco contenente i dati, una TextBox di nome txtCerca in cui inserire il testo da ricercare, un CommandButton di nome cmdCerca per effettuare la ricerca esatta ed una CheckBox di nome chkCercaAuto per determinare se cercare automaticamente il testo che inizia con la stringa specificata.

Prima di poter vedere il corretto funzionamento è necessario dichiarare la funzione e le costanti API:

  1. Option Explicit
  2. Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Integer, ByVal lParam As Any) As Long
  3. Private Const LB_FINDSTRING = &H18F
  4. Private Const LB_FINDSTRINGEXACT = &H1A2

La funzione SendMessage dichiarata alla riga 3 è utilizzata in parecchi articoli per inviare un messaggio ad una finestra di cui si conosce l'handle. I messaggi da inviare saranno specificati alle due righe successive: LB_FINDSTRING recupera l'indice dell'elemento della ListBox il cui testo iniziare per il valore specificato; analogamente LB_FINDSTRINGEXACT restituisce l'indice dell'elemento della ListBox il cui testo corrisponde esattamente al testo ricercato.

La ricerca non fa differenza tra maiuscole e minuscole!

  1. Private Sub Form_Load()
  2.     Dim intLen As Integer
  3.     Dim intConta As Integer
  4.     Dim strElemento As String
  5.     Randomize
  6.     For intConta = 1 To 20000
  7.         strElemento = ""
  8.         For intLen = 1 To CInt(Rnd * 15) + 3
  9.             strElemento = strElemento & Chr$(Rnd * 25 + 65)
  10.         Next intLen
  11.         lstElenco.AddItem strElemento
  12.     Next intConta
  13. End Sub

Al caricamento del form la ListBox viene popolata con 20000 stringhe generate casualmente sia in contenuto che in lunghezza mediante due cicli For alle righe 13-19.

  1. Private Sub cmdCercaEsatto_Click()
  2.     lstElenco.ListIndex = SendMessage(lstElenco.hwnd, LB_FINDSTRINGEXACT, -1, ByVal CStr(txtCerca.Text))
  3. End Sub

Il click sopra il pulsante cmdCercaEsatto richiamerà la funzione SendMessage con il messaggio LB_FINDSTRINGEXACT per ricercare la stringa specificata; l'argomento wParam della funzione assumerà la posizione dalla quale iniziare la ricerca. Il valore -1 specifica di iniziare la ricerca dall'inizio. L'argomento lParam riceverà invece il puntatore della stringa da ricercare.

Il valore restituito dalla funzione identifica l'elemento della ListBox contenente il testo desiderato.

  1. Private Sub txtCerca_Change()
  2.     If chkCercaAuto.Value = vbChecked Then
  3.         lstElenco.ListIndex = SendMessage(lstElenco.hwnd, LB_FINDSTRING, -1, ByVal CStr(txtCerca.Text))
  4.     End If
  5. End Sub

In maniera analoga alla routine precedente abbiamo deciso che in base al valore della CheckBox chkCercaAuto (righe 27-29) durante la digitazione verrà automaticamente ricercato il primo elemento somigliante alla stringa specificata. La ricerca è fatta come la precedente, ad eccezione del messaggio utilizzato che sarà invece LB_FINDSTRING.

Figura 2La dimostrazione del progetto è davvero molto semplice: all'avvio del form la ListBox è popolata con 20000 elementi casuali; basterà digitare qualcosa nella casella di testo in basso e premere il pulsante Cerca per recuperare la riga corrispondente esattamente al testo specificato.

Selezionando invece la CheckBox in basso, la ricerca dell'elemento sarà effettuata durante la digitazione del testo da ricercare.

Come già detto, però, la ricerca non fa distinzione tra maiuscole e minuscole, per cui non può sempre essere utilizzata come soluzione definitiva ad una ricerca dati.

Un progetto molto semplice la cui soluzione richiede giusto poche righe di codice per guadagnare tanta velocità nella ricerca degli elementi necessari. Nessun particolare rischio è rilevato dall'uso di questa soluzione.

La stessa soluzione può essere utilizzata per ricercare un elemento da un controllo ComboBox; basterà utilizzare le corrispondenti costanti API CB_FINDSTRING e CB_FINDSTRINGEXACT.

Fibia FBI
4 Novembre 2002

Scarica il progetto
Scarica il progetto
Scarica il testo dell'articolo
Scarica il testo dell'articolo
Stampa l'articolo
Stampa l'articolo
Torna all'introduzione delle Richieste dei lettori