dati in una combobox



  • dati in una combobox
    di rita (utente non iscritto) data: 13/06/2013 16:32:31

    Ciao a tutti
    l'istruzione qui sotto inserite nell'evento enter di una combobox fa si che nel menu a tendina mi vengano riportai i dati
    inseriti dalla cella a1 alla cella a20 del foglio chiamato ELENCO
    c'e' secondo voi un modo per far si che se ho anche dati nelle celle b1b20 o c1c20 questi si accodino sempre nella combobox una volta che ci clicco sopra?


     
    ComboBox1.RowSource = "ELENCO!A1:A20"



  • di HarryBosch data: 13/06/2013 18:07:34

    Ciao Rita :)

    intendi così?

     
    Private Sub ComboBox1_Enter()
        Dim rng As Range, cella As Range
        
        Set rng = Range("a1:a20, b1:b20, c1:c20")
        For Each cella In rng
            If cella.Value <> "" Then ComboBox1.AddItem cella.Value
        Next
        
    End Sub
    



  • di rita (utente non iscritto) data: 14/06/2013 08:25:13

    Inizialmente grazie per la risposta
    cosi' com'e' funziona
    volevo chiederti due cose
    - la prima - come faccio ad azzerare il contenuto della combobox ogni volta che ci clicco sopra
    mi spiego meglio, se cancello dei dati dalle celle queste mi vengono sempre fatte vedere nella combobox mentre a quanto ho capito nella tua istruzione, se la casella e' vuota dovrebbe bypassarle
    ho pensato di inserire la funzione clear all'inizio nella combobox
    - la seconda - e' possibile se un dato nella colonna si ripete far si che venga menzionato una sola volta? parlo di singola colonna
    grazie





  • di HarryBosch data: 14/06/2013 16:54:43

    Alla prima domanda la risposta è si, nel senso che l'istruzione .clear è sufficiente a cancellare tutti gli Item della combo. Per quanto riguarda la condizione che ho inserito, serve a verificare che la cella non sia vuota perché altrimenti, ll'istruzione successiva "ComboBox1.AddItem cella.Value"
    caricherebbe nella combobox una riga vuota (inutile e fuorviante).
    Pertanto all'inizio della sub puoi posizionare il .Clear.

    Se vuoi invece caricare la combo con i soli valori univoci, ti passo una routine che più volte abbiamo illustrato sul Forum, che adempie bene il suo lavoro.
    Si sfrutta la Collection: in sostanza si impone un nome da usare come chiave univoca con la conseguenza che, volendo attribuire alla Collection una chiave già esistente, verrà generato un errore. Errore che però possiamo controllare con
    On error resume next
    il quale non bloccherà l'esecuzione della routine ma impedirà soltanto la scrittura di un valore già esistente.

    La ruotine qua sotto può essere un esempio per caricare i valori delle 3 colonne [A:C] senza doppioni considerando però colonna per colonna. Lo stesso valore trovato in due colonne sarà caricato due volte.

     
    Private Sub ComboBox1_Enter()
        Dim r As Integer, c As Integer
        Dim col As Collection, v As Variant
        ComboBox1.Clear
        For c = 1 To 3
            Set col = New Collection
            For r = 1 To 20
                On Error Resume Next
                If Cells(r, c) <> "" Then
                    col.Add Cells(r, c).Value, CStr(Cells(r, c).Value)
                End If
            Next
            For Each v In col
                Me.ComboBox1.AddItem v
            Next
        Next
    End Sub
    



  • di rita (utente non iscritto) data: 17/06/2013 07:58:13

    ti ringrazio, funziona perfettamente
    volevo farti un ulteriore domanda
    e' possibile poter vedere in una combobox i dati di due colonne insieme
    mi spiego meglio
    nell'istruzione che hai postato i dati si accodano colonna per colonna
    se invece, facendo un esempio avessi in a1 pippo b1 pluto a2 topolino b2 minnie etc richiamare nella combobox i valori di due celle ossia cliccando sulla combobox dovrei avere i valori di a1 e b1 successivamente a2 e b2 etc
    e' fattibile?



  • di HarryBosch data: 17/06/2013 09:13:55

    Certo, si può fare, nello stesso modo in cui carichi la listbox a più colonne.

    Si deve innanzitutto impostare il numero di colonne da mostrare:
    ComboBox1.ColumnCount = 3

    puoi eventualmente modificare la larghezza di ogni colonna (altrimenti rimane l'impostazione di default):
    ComboBox1.ColumnWidths = "30;30;30"

    e successivamente si utilizza l'istruzione .List per caricare ogni colonna della combo, a partire dalla seconda:
    Combobox.List(r, 1) = "Pippo"

    mentre per la prima colonna sarà sufficiente
    .Additem "Topolino"

    la prima riga della combo avrà indice 0

     
    Private Sub ComboBox1_Enter()
        Dim r As Integer
    
        With ComboBox1
            .Clear
            .ColumnCount = 3
            .ColumnWidths = "30;30;30"
    
            For r = 0 To 19
                .AddItem Cells(r + 1, 1).Value
                .List(r, 1) = Cells(r + 1, 2).Value
                .List(r, 2) = Cells(r + 1, 3).Value
            Next
        End With
    End Sub
    



  • di rita (utente non iscritto) data: 17/06/2013 14:07:15

    ti ringrazio, fa esattamente quello che volevo
    solo un inconveniente
    quando clicco sulla combobox vedo i dati delle tre colonne ma quando effettuo la scelta mi restituisce nella combobox solo il valore della prima colonna
    ossia vedo in a1 pippo b1 pluto c1 topolino ma quando effettuo la scelta mi restituisce solo pippo
    dove sbaglio?



  • di HarryBosch data: 17/06/2013 17:22:59

    Si, restituisce il primo indice.

    Potresti unire le stringe per vedere tutti i valori...
    da legare all'evento change della combo.
     
    Private Sub ComboBox1_Change()
        On Error Resume Next
        With ComboBox1
        .Text = .Column(0) & "-" & .Column(1) & "-" & .Column(2)
        End With
    End Sub
    



  • di rita (utente non iscritto) data: 18/06/2013 08:52:06

    Grazie HarryBosch per la tua risposta
    colgo l'occasione per chiederti una cosa.
    Visto che hai utilizzato precedemente "Collection" potresti spiegarmi con un esempio molto molto banale e semplice a cosa serve e come funziona
    Ho provato a vedere l'istruzione in linea ma non riesco a capirla



  • di HarryBosch data: 18/06/2013 19:28:59

    Provo a spiegarlo in maniera semplice:
    detta velocemente, la Collection sono delle strutture che memorizzano qualsiasi tipo di dato, diversamente dagli array che invece sono tipizzati (di norma solo numeri, stringhe...); per questo motivo devi poi dichiarare gli elementi come variant (se ad esempio fai un ciclo sugli elementi memorizzati).
    Hanno un indice univoco, che può essere di tipo numerico o di tipo stringa: per farti un esempio, pensa ai fogli della cartella; essi stessi sono una collezione già predefinita da Excel, e puoi richiamarli
    - con indice numerico: Sheets(1)
    - oppure con indice stringa: Sheets("Foglio1")
    in ogni caso l'indice è univoco. Infatti, se tenti di aggiungerne uno con lo stesso nome o lo stesso indice, ottieni un errore in fase di esecuzione.

    Ora, supponiamo di voler memorizzare i dati del range [a1:a30] utilizzando una Collection, la cui sintassi è:
    Col.Add Item:=valore, Key:=CStr(valore)

    1. se nell'istruzione non definisci la chiave, verrà automaticamente assegnato un indice numerico progressivo:

    Dim rng As Range, cella As Range
    Dim col As Collection, v As Variant

    Set rng = [a1:a30]
    Set col = New Collection

    For Each cella In rng
    'nessuna chiave nell'istruzione: vengono caricati tutti i valori (quindi anche i doppi)
    'e a ciascuno sarà assegnato un numero progressivo
    col.Add cella.Value
    Next


    2. se invece definisci una chiave alfanumerica, ricavata dal valore trovato, quando viene trovata una chiave già memorizzata il codice andrà in errore;
    con una corretta gestione dell'errore fai semplicemente saltare la riga, e quindi il valore doppio non viene memorizzato.

    Dim rng As Range, cella As Range
    Dim col As Collection, v As Variant

    Set rng = [a1:a30]
    Set col = New Collection

    On Error Resume Next
    For Each cella In rng
    'in questo caso nell'istuzione aggiungo la chiave, che corrisponde al valore caricato
    'pertanto quando il ciclo trova una chiave già memorizzata va in errore
    col.Add cella.Value, CStr(cella.Value)
    'l'errore è però gestito precedentemente, e farà semplicemente saltare la memorizzazione
    Next



  • di rita (utente non iscritto) data: 19/06/2013 11:01:17

    grazie, ora mi e' un po piu chiara la cosa
    sei stato gentile



  • di rita (utente non iscritto) data: 19/06/2013 12:13:46

    .