Comportamento ComboBox ed eventi
Hai un problema con Excel? 
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 |
Vuoi Approfondire?