Uso avanzato delle ComboBox

Ovvero più colonne in una ComboBox

Mentre scrivevo il precedente articolo per le ComboBox, spulciando qua e là, ho intravisto la possibilità di poter usare, in alcuni applicativi sviluppati col VBA di Excel, anche ComboBox a più colonne. Andando avanti con l'articolo mi son detto di non voler abbandonare la possibilità di approfondire questo argomento.

Quindi eccomi qua.

 

La ComboBox a più colonne

In questa sede mi limiterò a trattare quelle proprietà che occorre approfondire per cercare di ottenere il massimo da questo nuovo aspetto della ComboBox.

Disegnare la ComboBox

E' ovvio che nel disegnare la ComboBox occorre tener presente che deve contenere due o più colonne, quindi se disponiamo di abbastanza spazio sulla UserForm sarà opportuno riservargliene quanto più possibile. Se la dimensione è limitata potremmo trovarci con una visualizzazione limitata dei dati in essa contenuti e anche se in questo caso comparirà una barra di scorrimento orizzontale potremmo non lavorare in condizioni ottimali.

Questo potrebbe essere un esempio della UserForm completata.

 

Impostazione per ottenere una ComboBox a più colonne

In questa trattazione faremo conoscenza con tre delle proprietà poco note della ComboBox:

ColumnCount che imposta il numero di colonne

TextColumn identifica il contenuto della colonna indicata da visualizzare nella casella della ComboBox. Il dato memorizzato nella proprietà Value sarà sempre quello della prima colonna

BoundColumn identifica la colonna in cui viene memorizzata la proprietà Value da usare quando l'utente seleziona una riga (nelle ComboBox rimane visualizzato il contenuto della prima colonna)

 

La proprietà Text della ComboBox leggerà sempre il dato visualizzato nelle ComboBox

In questa immagine possiamo vedere un esempio sull'uso di queste proprietà. Per facilitare l'osservazione in questa UserForm ho scelto sempre lo stesso nome come si vede in questa immagine

 

Popolare la ComboBox con i nostri dati

E' necessario, innanzitutto, dire al compilatore che intendiamo usare una ComboBox a più colonne e dobbiamo specificare quante. Nell'esempio che segue specifichiamo che ne desideriamo avere 2

ComboBox1.ColumnCount = 2

 

Vediamo ora come gestire una UserForm che ospita una ComboBox a più colonne.

Per il nostro progettino cerchiamo di costruire una userform simile a questa dove abbiamo usato:

In linea di massima il metodo è quasi simile a quello visto nel precedente articolo esempio nel paragrafo "La ComboBox che viene usata in una Userform" e la UserForm potrebbe avere questo aspetto.

Anche qui usiamo alcuni eventi di alcuni controlli che si trovano nella UserForm e della UuserForm stessa.

Quindi:

l'evento Activate della UserForm

l'evento Change della ComboBox1

l'evento Change della TextBox2

l'evento Click del CommandButton1

l'evento Click del CommandButton2

Ma ora passiamo alla descrizione del codice che scriveremo nel modulo relativo alla ComboBox.

 

La dichiarazione della Variabile pubblica a livello di questo Modulo

Dim Intervallo As Range

Questa variabile verrà usata in più di una routine

 

L'evento Activate della UserForm

Private Sub UserForm_Activate()
Dim NumR, NumC, R
'=============================
With Worksheets("Foglio3").Range("H1")
NumR = .CurrentRegion.Rows.Count
NumC = .CurrentRegion.Columns.Count
Set Intervallo = .CurrentRegion.Offset(1, 0).Resize(NumR - 1, NumC)
End With
'=============================
With ComboBox1
.ColumnCount = 2
.BoundColumn = 2
.Clear
'=============================
For R = 1 To Intervallo.Rows.Count
.AddItem (Intervallo(R, 1))
.List(R - 1, 1) = (Intervallo(R, 2))
Next
End With
'=============================
End Sub

In questo codice, dopo la ormai usuale dichiarazione delle variabili osserviamo:

In realtà c'è un metodo più voloce per popolare una ComboBox, e cioè, usando la proprietà List() - le parentesi sono vuote - con una matrice. Vediamo come.

Private Sub UserForm_Activate()
Dim NumR, NumC, MiaMatrice
'=============================
With Worksheets("Foglio3").Range("H1")
NumR = .CurrentRegion.Rows.Count
NumC = .CurrentRegion.Columns.Count
Set Intervallo = .CurrentRegion.Offset(1, 0).Resize(NumR - 1, NumC)
End With
'=============================
MiaMatrice = Intervallo.Resize(NumR - 1, 2)
'=============================
With ComboBox1
.ColumnCount = 2
.BoundColumn = 2
.Clear
'=============================
.List() = MiaMatrice
'=============================
End With
End Sub

In questo nuovo listato ci sono da fare solo due commenti:

Il tutto viene eseguito senza usare alcun ciclo

 

L'evento Change della ComboBox1

Private Sub ComboBox1_Change()
If ComboBox1.ListIndex = -1 Then
For Each CTRL In Controls
'=============================
If (TypeName(CTRL) = ("TextBox")) Then
CTRL = ""
End If
Next
Exit Sub
End If
'=============================
TextBox1 = ComboBox1.Value
TextBox2 = ComboBox1.Text
'MsgBox ComboBox1.List(ComboBox1.ListIndex, 1)
End Sub

Avendo impostatp la BoundColumn = 2 posso leggere:

L'evento Change della TextBox2

Private Sub TextBox2_Change()
Dim CTRL As Control
Dim C, R
'=============================
If ComboBox1.ListIndex = -1 Then Exit Sub
'=============================
For R = 1 To Intervallo.Rows.Count
If Intervallo(R, 1) = TextBox2 Then
For C = 3 To Intervallo.Columns.Count
Controls("textbox" & C) = Intervallo(R, C)
Next
Exit For
End If
Next
'=============================
End Sub

Tra le due caselle di testo usate nell'evento Change della ComboBox1 ho scelto questa che visualizza il Cognome.

Dopo la consueta dichiarazione delle variabili, se la ComboBox non mostra nulla (ComboBox1.ListIndex = -1), non succede nulla

Nell'ultimo frammento di codice usato in questo evento viene fatta una ricerca nella tabella di origine per trovare il Cognome scritto in questa Casella di testo. Trovato il cognome scrivo nelle restanti caselle di testo gli altri ati a questo associati.

 

L'evento Click del CommandButton2

Private Sub CommandButton2_Click()
Dim R, C
Dim CTRL As Control
'=============================
If ComboBox1.ListIndex = -1 Then Exit Sub
'=============================
R = 1
While Cells(R, 1) <> ""
R = R + 1
Wend
'=============================
C = 1
For Each CTRL In Controls
If (TypeName(CTRL) = ("TextBox")) Then
Cells(R, C) = CTRL.Text
C = C + 1
End If
Next
'=============================
ComboBox1.ListIndex = -1
End Sub

In questa routine:

 

L'evento Click del CommandButton1

Private Sub CommandButton1_Click()
Dim Risp
If ComboBox1.ListIndex = -1 Then
Unload UserForm2
Exit Sub
End If
Risp = MsgBox("sicuro di voler uscire", vbExclamation + vbYesNo, "Attenzione")
If Risp = vbYes Then Unload UserForm2
End Sub

Questo pulsante per finire i lavori.

 

Da quel che si può notare c'è, nonostante tutto una certa affinità tra l'uso normale della ComboBox mostrata nel precedente articolo esempio e questa a colonne multiple.

Allego ancora il file che ho usato per questa esercitazione: combobox.zip. Questo file può sostituire il precedente di cui è il completamento

 

Con questo mi sembra che io possa anche fermarmi qui.

Per i volenterosi assetati del sapere, da quello che ho cercato di mostrare in queste due ultime pagine, penso ci sia molto da applicarsi.

 

Buon lavoro