Comportamento ComboBox ed eventi



  • Comportamento ComboBox ed eventi
    di beppexile data: 20/09/2016 12:06:25

    Salve a tutti, in pratica vorrei che un combo si comportasse nel seguente modo:

    - dopo il focus, muovendomi con le frecce della tastiera (su e giù) la lista dei valori deve scorrere
    - dopo il focus, digitando una lettera, deve apparire il primo valore corrispondente;
    ma digitando una seconda lettera, deve continuare il completamento della parola, se invece si sta digitando qualcosa che non è presente in lista, dovrebbe bloccare quella digitazione.

    Esempio: nella combo ci sono i seguenti nomi.

    Marco
    Mirko
    Giuseppe
    Giampiero
    Roberto

    Se inizio digitando la "M", nella combo appare Marco,
    se continuo digitando la "i", appare Mirko,
    se continuo digitando una "m", si deve fermare alla parola Mirko,

    in quanto con Mim in lista non vi è presente nulla.

    Ho già provato a cambiare la proprietà MatchEntry, ma se posso fare una cosa non posso farne un'altra e viceversa.

    Grazie a tutti



  • di patel data: 20/09/2016 20:51:08

    ormai dovresti aver capito che, specialmente in presenza di userform, se non alleghi un file non ti risponde nessuno





  • di beppexile data: 21/09/2016 08:55:01

    Chiedo scusa, hai ragione.
    Allegato

    Grazie



  • di beppexile data: 23/09/2016 10:29:48

    Non c'è modo di farlo?



  • di patel data: 23/09/2016 10:36:12

    dal primo post sembra che tu abbia già fatto qualcosa e vuoi migliorarla, nell'allegato c'è solo una userform.





  • di beppexile data: 23/09/2016 10:44:03

    Provavo ad agire sulle proprietà come MachEntry, ma a quanto pare non basta. (Per questo non avevo allegato il file)

    Quello che vorrei riuscire a fare è descritto nel primo post.
    Ovviamente non mi serve che me lo facciate... mi può bastare anche solo un'indirizzo di come fare.

    grazie



  • di patel data: 23/09/2016 10:58:47

    la richiesta che stai facendo implica secondo me un controllo di ogni carattere digitato che non è banale ed abbastanza inutile a mio parere visto che se digiti un carattere non presente l'autocompletamento si ferma





  • di beppexile data: 23/09/2016 11:12:59

    Si, ma così facendo si riesce a scrivere qualcosa che non è presente in elenco, perché in questo modo, in un'ipotetica fase successiva, quando l'operatore dovrà dare l'ok su un pulsante per trasferire le informazioni sul foglio, trasferirebbe una voce inesistente, creando dei problemi dopo con le operazioni successiva.

    In pratica, devo evitare in maniera efficace che non vengano caricate sul database voci inesistenti, ma solo una di quelle in elenco.



  • di patel data: 23/09/2016 15:39:54

    non penso che tu corra questo rischio, tanto devi cliccare sulla voce selezionata sulla combo e se sbagli a digitare non viene selezionata alcuna voce





  • di beppexile data: 23/09/2016 16:27:12

    Invece no, perchè se una persona si limita a digitare un valore non incluso in lista, nella combo rimane lo stesso, quindi, quando poi lo prelevo dalla proprietà Value, avrò un valore inesistente in memoria.

    Non so se sono stato chiaro.



  • di beppexile data: 23/09/2016 16:50:23

    Ho allegato un nuovo file.



  • di patel data: 23/09/2016 17:12:05

    non capisco a cosa serva una combobox se non clicchi sull'elenco, la digitazione serve soltanto per una ricerca rapida, passo la mano a chi ne sa di più





  • di tanimon data: 24/09/2016 12:55:11

    ciao Beppe,
    intanto saluto Patel
    con il quale condivido quanto da Lui esposto.

    Se proprio vuoi fare un tentativo,
    potresti utilizzare l'Evento AfterUpdate della combo sul quale effettuare un Find nel range del
    Nome Definito "LISTA"

    cerca combobox.text in range("LISTA")

    se il FIND non va a buon fine, allora
    combobox = ""
    combobox.setFocus
    fine SE

    ciao

    Frank



  • di patel data: 24/09/2016 16:16:14

    Ciao tanimon
    mi sembra un'ottima idea e facilmente realizzabile

    Edit:
    forse è meglio sfruttare l'evento Change
     
    Private Sub ComboBox1_Change()
    Dim C As Range, L As Integer
    With Worksheets("Foglio1").Range("LISTA")
        L = Len(ComboBox1.Value)
        Set C = .Find(ComboBox1.Value)
        If C Is Nothing And L > 0 Then ComboBox1.Value = Left(ComboBox1.Value, L - 1)
    End With
    End Sub






  • di tanimon data: 26/09/2016 08:09:43

    @ Patel,
    in effetti è meglio utilizzare il Change:
    obiettivo raggiunto!

    Ciao
    Frank



  • di beppexile data: 26/09/2016 08:30:50

    Si, credo che avete centrato appieno l'obiettivo che volevo raggiungere.

    Serve soltanto una gestione degli errori perché appena cambio schermata di lavoro, (userform a più pagine) ho messo una riga che fa il clear della combo, e una volta svuotata mi legge nuovamente il change, mandando in debug su:

    L = Len(ComboBox1.Value)

    in quanto la combo è vuota

    Ho risolto inserendo opportunamente On Error Resume Next

    Grazie ragazzi.
     
    Private Sub ComboBox1_Change()
    Dim C As Range, L As Integer
    With Worksheets("Foglio1").Range("LISTA")
        On Error Resume Next
        L = Len(ComboBox1.Value)
        Set C = .Find(ComboBox1.Value)
        If C Is Nothing And L > 0 Then ComboBox1.Value = Left(ComboBox1.Value, L - 1)
    End With
    End Sub



  • di beppexile data: 26/09/2016 11:39:40

    Ho riletto un po i post e mi sono accorto di non aver risposto a tutto.

    cit.:patel
    "non capisco a cosa serva una combobox se non clicchi sull'elenco"
    cit.:tanimom
    "intanto saluto Patel con il quale condivido quanto da Lui esposto. "

    risp.: nel mio progetto, nella userform utente ci sono molte textbox e combo con molti valori caricati; per velocizzare le operazioni di inserimento, sto cercando di velocizzare per fare tutto da tastiera senza toccare il mouse.
    Ho dunque impostato una tabulazione sequenziale tra le varie tb e combo, ma devo anche prevedere errori di digitazione; nelle textbox vengono inseriti sempre numeri (ho inserito un controllo che vengano digitati solo numeri), nelle combo invece, volevo, potendo digitare l'iniziale del nome, portare l'operatore a selezionare la voce corretta in combo senza toccare il mouse.

    Facendo ulteriori prove, ho visto che, anche con la vostra sub, se si digita una lettera iniziale di un valore non presente in combo e si da invio per passare alla prossima, nella combo rimane la lettera digitata;
    io vorrei che non non accadesse.
    Preferirei che non mi facesse uscire dalla combo finchè non viene digitato un valore corretto.

    Sto cercando infatti di usare l'evento exit della combo per controllare che nella cella sia digitato un valore presente in lista, e se questo non accade bloccare l'utente su questo inserimento per una nuova digitazione.

    Credo di aver quasi risolto sempre con il metodo find nell'evento exit, ma sto ancora facendo delle prove;
    non appena riesco pubblicherò la soluzione.

    Grazie a tutti



  • di beppexile data: 26/09/2016 11:53:48

    Risolto.

    Adesso:
    - se si digita una lettera di un valore presente in lista, appare subito in combo il primo con quella lettera iniziale;
    a questo punto, digitando nuovamente la stessa lettere (se i valori con quella iniziale sono più di uno), verrà visualizzato il successivo, e così via.
    - se invece si digiterà l'iniziale di un nome non presente in lista e si darà invio per sbaglio, non si potrà uscire dalla combo fino alla digitazione di un valore corretto presente in lista.

    Grazie a tutti per le dritte e le soluzioni proposte.
    Stavolta chiudo definitivamente.
     
    Private Sub ComboBox1_Change()
    Dim C As Range
    L As Integer
        With Worksheets("Foglio1").Range("LISTA")
            On Error Resume Next
            L = Len(ComboBox1.Value)
            Set C = .Find(ComboBox1.Value)
            If C Is Nothing And L > 0 Then ComboBox1.Value = Left(ComboBox1.Value, L - 1)
        End With
    End Sub
    
    Private Sub ComboBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
        Dim L As Integer
        L = Len(ComboBox1.Value)
        If L = 1 Then
            Cancel = True
            ComboBox1.SetFocus
            ComboBox1.SelStart = 0
            ComboBox1.SelLength = Len(ComboBox1)
        End If
    End Sub
    



  • di beppexile data: 27/09/2016 14:21:15

    Rieccomi.

    Dopo tutte le prove fatte in precedenza per ottenere l'effetto desiderato, mi sono messo su un nuovo file con solo una combo popolata con rowsource, per modificare e provare tutte le proprietà; ed ho scoperto che:
    da una combobox standard (appena creata) se si imposta le proprietà

    Style = 2 - fmStyleDropList
    MatchEntry= 0 - fmMatchEntryFirstLetter

    la combo si comporta esattamente come volevo io all'inizio del post;
    in pratica non è possibile scrivere nessun carattere all'interno, ma usa le lettere per poter selezionare le voci dall'elenco.
    E' questo senza scrivere nulla negli eventi Change ed Exit.

    Allego un file.

    Spero che questo sia stato utile.

    Saluti



  • di patel data: 27/09/2016 17:21:34

    ben fatto, infatti la macro precedente non otteneva sempre il risultato voluto, quella giusta è
     
    Private Sub ComboBox2_Change()
    Dim C As Range, L As Integer
    On Error Resume Next
    With Worksheets("Foglio1").Range("LISTA")
        L = Len(ComboBox2.Value)
        Set C = .Find(ComboBox2.Value)
        If C Is Nothing And L > 0 Then
          ComboBox2.Value = Left(ComboBox2.Value, L - 1)
        ElseIf L > 0 And Left(C.Text, L) <> ComboBox2.Value Then
          ComboBox2.Value = Left(ComboBox2.Value, L - 1)
        End If
    End With
    End Sub