ComboBox e ListBox. Ovvero: come caricare una ListBox selezionando una voce nella Combobox

Le ComboBox e ListBox  che useremo fanno parte delle ActiveX, e le troviamo nella "Casella degli Strumenti" o "Strumenti di controllo" (a seconda delle versioni di Excel) dal menù "Visualizza/Barre degli strumenti". Questi due "oggetti" sono diversi dalle ComboBox e ListBox presi da "Moduli".

Gli "oggetti" facenti parte delle ActiveX sono inseribili sia in un foglio di lavoro, sia in una UserForm, anch'esso un "oggetto" inseribile ma dall'Editor di Visual Basic (VBE). Tutti gli "Oggetti" possiedono delle "proprietà", ed una di queste proprietà presenti sia nelle ComboBox sia nelle ListBox è quella che ci consente di determinare la provenienza dei dati che saranno poi visualizzati nelle stesse. A secondo il posizionamento di questi due "controlli" (su foglio o su UserForm) , cambia il nome della "proprietà", anche se il "funzionamento" è il solito:

  • con oggetto sul foglio di lavoro la proprietà è : ListFillRange

  • con oggetto su una UserForm la proprietà è : RowSource

Entrambe queste proprietà sono programmabili, sia scrivendo direttamente nella finestra delle loro "proprietà" il percorso della zona che contiene i dati da visualizzare, sia attraverso istruzioni inserite in un evento.

Dopo queste premesse, veniamo al problema preso come esempio. Supponiamo di avere una tabella sul foglio1 (o elenco, o database che dir si voglia), dove sono inseriti degli articoli, con codice articolo (campo necessariamente univoco), descrizione, prezzo, ecc. Ogni articolo però è formato da sottocategorie, ognuna con caratteristiche diverse, e non tutti gli articoli possiedono lo stesso numero di sottocategorie. Non è quindi pensabile di realizzare un'unica tabella che comprenda tutte queste disponibilità. Ci affideremo quindi ad un secondo foglio (Foglio2) dove costruire la nostra tabella delle sottocategorie. Questa tabella dovrà necessariamente possedere il campo "Codice articolo", un campo "categoria" (che potrà essere a sua volta formata da un codice), ed altri dati correlati che ne identifichino le diversità. Il problema nasce quando vorremo, per un determinato articolo, visualizzare tutti i dati pertinenti l'articolo, presenti nelle sottocategorie. Ovviamente questo esercizio si presta ad un'infinità di varianti, sia come tipo di dati sia come scelta dei campi correlati che vorremo vedere, se ci pensiamo bene, corrisponde un pò a "filtrare" i dati, anche se con tecniche diverse dall'uso del "Filtro" e con risultati diversi.

Stabilito qual'è il problema, vediamo come affrontarlo : useremo una UserForm, che chiameremo da un pulsante posto sul Foglio1, e nella U.F. inseriremo una Combobox ed una Listbox. Useremo l'apertura della
UserForm  (UserForm1_Activate) per "caricare" l'elenco nella ComboBox1 assegnando via codice, la zona che contiene i "Codici Articolo" della nostra tabella, ciòe la colonna A, dalla riga 1 fino a dove vorremo, usando questa istruzione:

Private Sub UserForm_Activate()
'carico la lista degli articoli nella colonna A del foglio1
ComboBox1.RowSource = ("A1:A10")
End Sub

e questo sarà l'effetto sulla Combobox (a sinistra l'elenco sul foglio 1)

A questo punto dovremo sviluppare delle istruzioni che ci consentano di ottenere , selezionando uno degli articoli presenti nella lista, che nella ListBox vengano caricate tutte le occorrenze relative al codice scelto. Il sistema che presento è semplice: faccio cercare nella tabella sul Foglio2, tutti i codici articolo uguali a quello selezionato. Individuato un articolo, faccio estrarre i dati che mi interessano (nella stessa riga ma nelle due colonne a destra) e li copio in una zona appositamente assegnata, sullo stesso Foglio2 (colonne G e H), con ricerca della prima riga libera, in modo da comporre un elenco. Questa zona con l'elenco così composto, è la zona che assegno alla proprietà RowSource della ListBox. Un'altra proprietà della ListBox da sfruttare, è la "ColumnCount" normalmente impostata a 1 e che determina in numero delle colonne visibili nella Listbox. Noi imposteremo questa proprietà a 2, perchè due sono i campi che abbiamo deciso di estrarre. Un'altro accorgimento da usare, sarà quello di pulire la zona che forma il RowSource della Listbox, in modo che ad ogni selezione nella ComboBox si azzeri il contenuto della ListBox e si rinfreschi con nuovi dati (Refresh).

Per queste istruzioni sfrutteremo l'evento Click della Combobox:

Private Sub ComboBox1_Click()
'questo sotto evita il saltellamento a schermo
Application.ScreenUpdating = False
'faccio pulire la zona che uso come estrazione dati
Worksheets(2).Range("G1:H10").ClearContents

Dim CL As Object  
'dichiaro la variabile CL come Object
Worksheets(2).Select   
'seleziono il foglio2
'per ogni cella nel range A1:A20 foglio2
For Each CL In Worksheets(2).Range("A1:A20")
'se il valore nella cella  (CL) è uguale al valore selezionato nella combobox
If CL = ComboBox1.Text Then
'allora seleziono le due celle a destra di quella trovata
Range(CL.Offset(0, 1), CL.Offset(0, 2)).Select
'copio tutte e due i valori
Selection.Copy
'cerco la prima riga libera a partire dalla riga 1 e nella colonna 7 (la G )
Dim iRow As Integer
iRow = 1
While Cells(iRow, 1).Columns(7).Value <> ""
iRow = iRow + 1
Wend
'trovata la riga con la cella vuota, incollo i dati copiati con Selection.Copy (sopra)
Selection.Copy Cells(iRow, 1).Columns(7)

End If
Next
'finito il ciclo di ricerca, carico la listbox con i dati ora contenuti nelle colonne G e H
ListBox1.RowSource = "Foglio2!G1:H10"
'poi ritorno sul foglio1
Worksheets(1).Select
End Sub

e questo sarà il risultato (a sinistra la zona del Foglio2 con la seconda tabella)

Appare evidente che i range usati nell'esempio sono modificabili a piacere e sarà possibile usare anche la funzione End per non determinare a priori la lunghezza di un elenco.

 

File consultabile e scaricabile :  combo e carica lista2000.zip    16 Kb


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