Caricare ComboBox dipendenti, Listbox multi-colonna

Stato
Chiusa ad ulteriori risposte.

giulianovac

Access/VBA Expert
Staff
9 Giugno 2018
5.260
245
Italy
2019
415
Capita spesso di dover caricare in un Userform degli elenchi in ComboBox o ListBox presi da un foglio Excel.

Caricare i dati
La seguente routine CaricaElenco, che va inserita in un modulo, assolve a questa funzionalità in modo quasi automatico.
Ma la routine può fare anche molto di più, perché opzionalmente ci permette di stabilire che vogliamo:
- caricare più colonne
- indicare che i dati devono essere filtrati (creando quindi una dipendenza

I parametri obbligatori di questa routine sono i seguenti:
- il Controllo (obbligatorio) può essere sia un ComboBox che un ListBox
- la Colonna (obbligatorio) da cui prelevare i dati


Codice:
Sub CaricaElenco(ByVal ws As Worksheet, ByVal Controllo As Object, ByVal Colonna As Long, Optional Filtro As String = "", Optional ColonnaFiltro As Long = 0, Optional NrColonne As Long = 0)
    Dim uRiga As Long
    Dim i As Long
    Dim iCol As Long
    Dim bValido As Boolean
    On Error GoTo CaricaElenco_Error

    uRiga = ws.Cells(1, Colonna).End(xlDown).Row

    Controllo.Clear

    For i = 2 To uRiga
        bValido = True
  
        If (Filtro > vbNullString) And (ColonnaFiltro <> 0) Then
            If UCase$(ws.Cells(i, ColonnaFiltro)) <> UCase$(Filtro) Then
                bValido = False
            End If
        End If
        If bValido Then
            Controllo.AddItem (ws.Cells(i, Colonna).Value)
            If NrColonne > 1 Then
                Controllo.ColumnCount = NrColonne
                For iCol = 1 To Controllo.ColumnCount
                    Controllo.List(i - 2, iCol) = ws.Cells(i, iCol + Colonna)
                Next iCol
            End If
        End If
    Next i

    On Error GoTo 0
    Exit Sub

CaricaElenco_Error:
    MsgBox "Error " & Err.Number & " (" & Err.Description & ") in procedure CaricaElenco of Modulo modCaricaElenchi"
End Sub
Supponiamo di avere un foglio Elenchi così composto:
*ABCDE
1CategorienullProdottiCategoriaPrezzo
2CarnenullArrosto tacchinoCarne20,30
3FruttanullCoscie di polloCarne12,55
4VerduranullLonza di maialeCarne22,00
5nullnullAranceFrutta6,70
6nullnullMeleFrutta5,40
7nullnullMandariniFrutta3,30
8nullnullAnanasFrutta6,00
9nullnullInsalataVerdura1,00
10nullnullPomodoriVerdura3,90
11nullnullCavoliVerdura2,50
12nullnullFinocchioVerdura2,20
13nullnullRadicchioVerdura1,50
Elenchi

Se volessimo caricare in un ComboBox o ListBox solo le Categorie (quindi 1 sola colonna)sarebbe sufficiente scrivere:
CaricaElenco ws, cboCategorie, 1

Chiaramente se abbiamo più ComboBox o ListBox ripeteremo questa istruzioni per ognuno di essi.
Notare che volutamente il parametro Controllo è stato impostato As Objectcosì la routine funzionerà indistintamente sia con gli uni che con gli altri.



ComboBox dipendenti
Nel Forum leggo spesso richieste di aiuto sul come creare ComboBox a scelta dipendente e questa routine è stata pensata anche per soddisfare questa esigenza.
Ad esempio, caso classico, abbiamo due ComboBox (cboCategorie e cboProdotti) in cui il primo visualizza le Categorie, vogliamo che il secondo mostri solo i Prodotti appartenenti alla Categoria seleziona.
Prima di tutto, doppiamo dire al programma che quando si seleziona una Categoria vengano resi disponibili i rispettivi prodotti in cboProdotti.
Per fare questo dovremo semplicemente passare alla routine CaricaElenco i seguenti parametri:
- Colonna, che contiene i dati da caricare
- Il testo usato come condizione di filtro
- Colonna che contiene il filtro
Così:
Codice:
Private Sub cboCategorie_Click()
    CaricaElenco ws, cboProdotti, 3, cboCategorie.Text, 4
End Sub
N.B.
Ci prega di nota va sempre usato l'evento Click (mai il Change che è il default) perché altrimenti la routine CaricaDati verrebbe chiamata per OGNI tasto premuto, il che sarebbe assolutamente sbagliato.
Inoltre, la proprietà Style del ComboBox va sempre impostata su 2 (il default è 1).

ComboBox/ListBox multi-colonna
Anche questa è un'esigenza abbastanza sentita, ma per molti utenti alle prime armi può sembrare di difficile soluzione.
Invece, grazie alla routine CaricaDati diventa quasi banale.
Infatti, è sufficiente indicare il numero di colonne da caricare nel parametro opzionale: NrColonne

Ad esempio, nel ListBox sul frmDati (che trovate nel progetto allegato) i dati vengono caricati così:
CaricaElenco ws, lstProdotti, 3, "", 0, 2
Se volessimo visualizzare anche la colonna Prezzo, basterebbe solamente sostituire il 2 finale con il 3, il tutto avverrà automaticamente ed in modo trasparente.
Ovviamente, le colonne devono essere adiacenti nel foglio.



In allegato trovate il file di esempio.
Per qualsiasi richiesta di aiuto aprite una discussione e, facendo riferimento a questo snipped-code, esponente il vostro problema.

Ciao Saluto_saluto

AGGIORNAMENTO (13/07/2021)
Dato che spesso accade che in un elenco vi siano elementi ripetuti più volte, si ha l'esigenza di caricare gli elementi distinti solo una volta, pubblico una funzione che verifica la presenza di un elemento prima di aggiungerlo all'elenco.
Codice:
Function GiaPresente(ByRef Controllo As Object, valore As String) As Boolean
    Dim i As Long
    For i = 0 To Controllo.ListCount - 1
        If UCase$(valore) = UCase$(Controllo.List(i)) Then
            GiaPresente = True
        End If
    Next i
End Function
Questa funzione va chiamata all'interno della routine CaricaElenco vista sopra, all'interno del ciclo For/Next. Esempio:
Codice:
        If bValido Then
            If Not GiaPresente(Controllo, ws.Cells(i, iCol + Colonna)) Then '''<<< nuova funzione chiamata
                Controllo.AddItem (ws.Cells(i, Colonna).Value)
                If NrColonne > 1 Then
                    Controllo.ColumnCount = NrColonne
                    For iCol = 1 To Controllo.ColumnCount
                        Controllo.List(i - 2, iCol) = ws.Cells(i, iCol + Colonna)
                    Next iCol
                End If
            End If
        End If
[/Coide]

N.B Vedere anche la discussione:
https://www.forumexcel.it/forum/threads/userform-con-scelta-articoli-e-taglie-convalida-speciale.50107/
 

Allegati

Ultima modifica:
Stato
Chiusa ad ulteriori risposte.

Sostieni ForumExcel

Aiutaci a sostenere le spese e a mantenere online la community attraverso una libera donazione!