Uso avanzato delle combobox

Ultima modifica: 30-05-2016

Spulciando qua e là, ho intravisto la possibilità di poter usare, in alcuni applicativi sviluppati col VBA di Excel, anche ComboBox a più colonne.

Una premessa veloce.

Molte proprietà di questo controllo, anche se si presenta in modo diverso per via delle colonne che mostra, sono identiche a quelle delle ComboBox ad una unica colonna, Quindi in questa trattazione non ci ritorno su. 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.

Ecco come si presenta la ComboBox disegnata nelle due maniere:

combobox con colonne combobox con colonne

E' indubbio che la Combobox di sn è di più facile lettura ed utilizzo.

Impostazione per ottenere una ComboBox a più colonne

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 tre

ComboBox1.ColumnCount = 3.

Popolare la ComboBox con i nostri dati

Anche se i metodi per aggiungere dati in una ComboBox del genere sono sostanzialmente molto simili a quelli già visti in altre occasioni, pure se ne discostano leggermente. Teniamo conto che dobbiamo scrivere su tre colonne e non su una sola.

In questa serie di istruzioni notiamo oltre all'ormai noto metodo AddItem abbiamo anche la presenza di List(I, 1).

Dopo l'impostazione in cui si indica il numero di colonne da attribuire alla ComboBox si procede con l'inserimento dei nostri dati usando il metodo che più ci piace.

Il primo dato viene inserito nel modo consueto usando la proprietà AddItem.

Nella sintassi della nuova proprietà List(x,y), tra le parentesi sono espressi gli indici (sempre a base 0 - zero) relativi alla riga ed alla colonna in cui andremo ad inserire i dati successivi al primo. In tale situazione quando viene eseguita la istruzione ComboBox1.AddItem Cells(I + 2, 1).Value, viene senz'altro creata una nuova riga nella lista della ComboBox e il primo dei nuovi dati va ad occupare la prima colonna, mentre le successive istruzioni continuano con l'inserimento degli altri dati nelle colonne successive.

For I = 0 To UltimaRiga - 2
ComboBox1.AddItem Cells(I + 2, 1).Value
ComboBox1.List(I, 1) = Cells(I + 2, 2).Value
ComboBox1.List(I, 2) = Cells(I + 2, 3).Value
Next

Affermando che il modo con cui abbiamo appena scritto le istruzioni rappresenta uno tra quelli disponibili per rispettare la sintassi che tali istruzioni richiedono, occorre tuttavia prestare una particolare attenzione al modo con cui si istruisce il ciclo For .... Next

Così come è stato impostato, il ciclo segue l'andamento dell'indice della ComboBox che via via viene incrementato di 1 partendo da 0 (zero) e sono giuste tutte le espressioni con cui la variabile I viene associata anche alle celle da cui prelevare i dati.

Se avessimo invece voluto seguire l'andamento delle righe del foglio da cui andiamo a prelevare i dati con un ciclo impostato in questo modo:

For I = 2 To UltimaRiga (2 è la riga del foglio da cui parte il nostro elenco) avremmo dovuto istruire la formula per puntare correttamente all'indice della lista della ComboBox e di conseguenza avremmo dovuto riscrivere tutte le successive istruzioni nella seguente maniera:

For I = 2 To UltimaRiga
ComboBox1.AddItem Cells(I, 1).Value
ComboBox1.List(I - 2, 1) = Cells(I, 2).Value
ComboBox1.List(I - 2, 2) = Cells(I , 3).Value
Next

in modo da tenere sempre corretti i riferimenti sia alle righe della lista della ComboBox sia alle righe del foglio di Excel.

Ma se i nostri dati sono presenti in un file di testo?

In questo caso dovremo lavorare un po' di più.

In questo caso occorre prestare particolare attenzione nello scrivere (o correggere) il contenuto del file di testo inserendo nel contesto anche dei particolari caratteri per separare i diversi campi in modo da poterli facilmente individuare da programma.

Nell'esempio i vari campi sono divisi dal carattere "," (virgola) ma si può scegliere un qualsiasi carattere purché facilmente riconoscibile (un trattino, un asterisco, ecc) con l'obbligo di andare anche a correggere la riga Rossa evidenziata in grassetto.

Questo è un esempio di una delle voci che abbiamo preparato nel file di testo:

SESTO FIORENTINO,28,33

questa la divisione desiderata

SESTO FIORENTINO     28     33

Ecco il codice necessario:

Dim Città As String
Dim A, B, C, I, Carattere, Posizione
ComboBox1.ColumnCount = 3
ComboBox1.Clear
Cartella = ThisWorkbook.Path
Open Cartella & "\" & "list_e_combo_città.txt" For Input As #1
I = 0
Do Until EOF(1)
' questa è la stringa prelevata dal file di testo
Line Input #1, Città ' per seguire l'esempio sarà: SESTO FIORENTINO,28,33
' stabiliamo quale sarà il carattere discriminante per il punto di divisione della stringa
Carattere = ","
' trasferiamo in A la stringa contenuta in Città
A = Città ' = SESTO FIORENTINO,28,33
' stabiliamo la posizione del primo carattere discriminante
Posizione = InStr(1, A, Carattere )
' poniamo in B la prima porzione di stringa
B = Left(A, Posizione - 1) ' = SESTO FIORENTINO
' in A rimarrà la parte restante della stringa
A = Mid(A, Posizione + 1) ' = 28,33
' stabiliamo la nuova posizione del carattere discriminante
Posizione = InStr(1, A, Carattere )
' in C rimarrà la seconda porzione di stringa
C = Left(A, Posizione - 1) ' = 28
' in A rimarrà la parte restante della stringa
A = Mid(A, Posizione + 1) ' = 33
ComboBox1.AddItem B ' = SESTO FIORENTINO
ComboBox1.List(I, 1) = C ' = 28
ComboBox1.List(I, 2) = A ' = 33
I = I + 1
Loop
Close #1

Prelevare dati dalla ComboBox

Per default la scelta fatta in una ComboBox a più colonne restituisce l'elemento presente nella prima colonna. In una ComboBox in cui vogliamo scegliere:

SESTO FIORENTINO 28 33

otterremo nella sua casella di testo il solo SESTO FIORENTINO

e se scriviamo la arcimota istruzione:

TextBox4.Text = ComboBox2.Text

otterremo nella quarta casella di teso sempre e solo SESTO FIORENTINO

In questo esempio quel che otteniamo nella casella di testo ci può anche andare bene.

Ma se avessimo la lista della ComboBox organizzata in un modo differente come nel seguente:

wqa7 calzini filanca 7,32

l'output delle nostre istruzioni sarà wqa7 dato assolutamente insignificante ed incomprensibile.

A questo possiamo ovviare intervenendo come di seguito illustrato:

indice = ComboBox1.ListIndex
ComboBox1.Text = ComboBox1.List(indice, 1)
TextBox2.Text = ComboBox1.Text
TextBox1.Text = ComboBox1.List(indice, 0)
TextBox1.Text = ComboBox1.List(indice, 1)
TextBox3.Text = ComboBox1.List(indice, 2)
' oppure:
TextBox2.Text = ComboBox1.Text
TextBox1.Text = ComboBox1.List(indice, 1)
TextBox1.Text = ComboBox1.List(indice, 0)
TextBox3.Text = ComboBox1.List(indice, 2)

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.