Combobox 1 chiama ComboBox 2

Ultima modifica: 28-05-2016

Per quanto ci impegniamo, anzi appunto per questo, tante volte succede che una cosa che sembra chiarita mostra dei risvolti sconosciuti. E questo accade anche per alcuni componenti della nostra quotidiana vita di programmazione.

Per questo motivo questa volta vorrei approfondire un nuovo aspetto delle ComboBox o ListBox che in questi giorni ho dovuto affrontare.

Su come riempire e gestire le ComboBox e o le listBox oramai abbiamo scritto e letto abbastanza.

Questa volta vediamo come è possibile gestire una ComboBox da un'altra ComboBox.

La tabella su cui intendo lavorare è esempio visibile in questa pagina.

 

Come potete osservare il questa tabella ci sono i seguenti campi:

ID Cognome Nome CAP PROV CITTA' INDIRIZZO

Quel che vogliamo fare è semplice: scelta una città da una ComboBox, nell'altra ComboBox dovremmo poter selezionare solo i contatti ad essa abbinati.

Iniziamo quindi col costruire una bella UserForm come questa.

L'azione, detta semplicemente, la eseguiamo in due tempi:

Ora possiamo vedere in dettaglio come è organizzato il lavoro.

 

L'evento Activate dellUserForm

L'azione si svolge in tre fasi

  1. si inizia col determinare l'intervallo su cui vogliamo lavorare
  2. ora si cercano, in maniera univoca, tutte le città della tabella come già spiegato in questo articolo esempio memorizzandole in una Collection
  3. avuta la collezione delle città le aggiungiamo alla ComboBox1

 

L'evento Change della ComboBox1

Anche qui abbiamo tre fasi

  1. cancellazione della ComboBox2 da eventuali precedenti contenuti
  2. memorizzazione del nome sceltro in una variabile
  3. ricerca dei contatti per la città scelta e loro inserimento nella ComboBox2

 

L'evento Change della ComboBox2

Useremo questo Evento per eseguire il resto del lavoro su cui in questo contesto soprassiedo

 

L'evento Click del CommandButton1

Anche per questo evento per il momento non ci impegnamo più del necessario

 

Il codice

Il codice visto in questa prospettiva risulterà più semplice.

Le variabili pubbliche

Teniamo presente che ci sono delle variabili che useremo in tutte le routine che useremo perciò, invece di ricominciare sempre d'accapo per valorizzare queste variabili le rendiamo pubbliche. Per far questo le dichiariamo nella zona dichiarazione delle variabili, ossia nelle primissine righe del modulo relativo alla UserForm:

Dim Intervallo As Range
Dim Righe, Colonne

L'evento Activate dellUserForm

Il codice che segue non necessita di commenti

Private Sub UserForm_Activate()
Dim Riga
Dim Elenco As New Collection
' 1 fase: determinare l'intervallo
With Range("A1").CurrentRegion
Righe = .Rows.Count - 1
Colonne = .Columns.Count
Set Intervallo = .Offset(1, 0).Resize(Righe, Colonne)
End With
' 2 fase; creare un elenco univoco delle città usando la Collection esempio
On Error Resume Next
For Riga = 1 To Righe
Elenco.Add Intervallo(Riga, 6).Value, CStr(Intervallo(Riga, 6).Value)
Next
On Error GoTo 0
' 3 fase: riempimento della ComboBox1
For Riga = 1 To Elenco.Count
ComboBox1.AddItem Elenco(Riga)
Next
End Sub

L'evento Change della ComboBox1

La ComboBox2, contrariamente alla ComboBox1 che viene riempita una sola volta, viene riempita più volte durante l'uso della routine.

Per questo motivo, ogni volta che viene riempita con nuovi dati, prima deve essere svuotata, altrimenti il suo elenco diverrà così lungo da essere pressocchè inutilizzabile.

Dopo questa unica nota ecco il codice

Private Sub ComboBox1_Change()
Dim Citta, Riga
'1 fase: cancellazione del contenuto della ComboBox2
ComboBox2.Clear
' 2 fase: lettura del nome scelto
Citta = ComboBox1.Text
' 3 fase: reperimento di tutte le occorrenze della città nella tabella
' e riempimento della ComboBox2

With Intervallo
For Riga = 1 To Righe
If .Item(Riga, 6) = Citta Then
ComboBox2.AddItem (.Item(Riga, 2))
End If
Next
End With
End Sub

L'evento Change della ComboBox2

Dopo i lavori appena descritti possiamo usare questa ComboBox2 come più ci aggrada. In questo esempio lo uso semplicemente per riempire le TextBox correlati al nome scelto.

Private Sub ComboBox2_Change()
Dim Nome, Citta
Dim Riga
Nome = ComboBox2.Text
Citta = ComboBox1.Text
With Intervallo
For Riga = 1 To Righe
If .Item(Riga, 2) = Nome And .Item(Riga, 6) = Citta Then
TextBox1 = .Item(Riga, 2)
TextBox2 = .Item(Riga, 3)
TextBox3 = .Item(Riga, 4)
TextBox4 = .Item(Riga, 5)
TextBox5 = .Item(Riga, 6)
TextBox6 = .Item(Riga, 7)
End If
Next
End With
End Sub

 

L'evento Click del CommandButton1

Per il momento ci limitiamo ad usare il pulsante CommandButton1 per trasferire sul Foglio2 i dati che abbiamo raccolto nelle caselle di testo. Per complicarci leggermente la vita decidiamo di non trasferirvi il Codice che, nel foglio1 si trova nella prima colonna.

Private Sub CommandButton1_Click()
Dim Col, Riga, Uriga
' se la textbox1 è vuota non si fa nulla
With Worksheets("Foglio2")
If TextBox1 = "" Then
MsgBox "Occorre scegliere un nome"
Exit Sub
End If
' se nel Foglio2 mancano le intestazioni di colonna si provvede a scriverle copiandole dal Foglio1
If .Range("A1") = "" Then
For Col = 2 To Colonne
.Cells(1, Col - 1) = Intervallo(0, Col)
Next
End If
' ora si possono trasferire sul foglio2 i contenuti delle TextBox
Riga = .Range("A1").CurrentRegion.Rows.Count + 1
For Col = 1 To Colonne - 1
.Cells(Riga, Col) = Controls("Textbox" & Col)
Next
End With
End Sub

Questa routine ha già i commenti che servono quindi mi esimo dal farne altri.

 

Questo è tutto, per ora. Ci sentiamo la prossima volta