XL 2016 Limiter la Saisie dans un Combobox

aurelio.ewane

XLDnaute Occasionnel
Bonjour jai un combobox qui contient une liste delements
Jaimerais savoir comment limiter la saisie dans mon combobx et n'autoriser que les valeurs qui sy trouvent du genre lorsque je commences a saisir une lettre ca charge dans mon combobox tous les elements de ma liste qui on se mot
une saisie intelligente je veux dire

Merci a tous
 

Dudu2

XLDnaute Barbatruc
Finalement, ce n'est pas compliqué de fusionner les 2 ressources modifiées (publication à faire ultérieurement dans les ressources) pour obtenir à la fois une saisie filtrée et un affichage multi-colonnes.

Comme indiqué ci-dessus, j'ai dû faire une classe pour intercepter les Clicks sur les Labels créés dynamiquement. Si @patricktoulon a une autre solution... pls let me know.

Dans cet exemple, le ComboBox1.TextColumn = 2 => c'est la 2ème colonne qui fait l'objet de la saisie filtrée.
cmb.gif
 

Pièces jointes

  • ComboBox Multi-Colonnes Saisie Filtrée.xlsm
    53.6 KB · Affichages: 3

patricktoulon

XLDnaute Barbatruc
re
ben si c'est pour une combobox avec son textbox mask tu le classe dans le usf c'est tout

ce que je comprends pas c'est le besoins de ce masque de saisie label ou textbox d'ailleurs
si ta combo est en match entry none
en récupérant le ".text" tu refait un tableau puis .list=.... puis resend du ".text"dans le .text
je fait ça avec une 2d combo masqué

si je demasque ça donne ça
demo.gif
 

Dudu2

XLDnaute Barbatruc
en récupérant le ".text" tu refait un tableau puis .list=.... puis resend du ".text"dans le .text
je fait ça avec une 2d combo masqué
C'est en effet ce que je fais avec un filtrage qui peut être:
  • 0 = pas de filtrage (qui peut le plus peut le moins)
  • 1 = filtrage par caractère du début du texte de la TextColumn (commence par)
  • 2 = filtrage par le contenu des mots de la TextColumn (contient)
ce que je comprends pas c'est le besoins de ce masque de saisie label ou textbox d'ailleurs
si ta combo est en match entry none
Ça c'est autre chose, c'est pour gérer l'affichage multi-colonnes en zone texte de la ComboBox.
Zone qui sans cela ne contient QUE la valeur de la TextColumn (et PAS toutes les colonnes)
Les Labels couvrent la zone texte de la ComboBox et contiennent les valeurs des colonnes.

J'ai utilisé un principe simple:
- en mode affichage ce sont les Labels qui sont en premier plan (affiche tous les Labels)
- en mode saisie c'est la ComboBox qui est en premier plan (affiche sa TextColumn)
 

Dudu2

XLDnaute Barbatruc
tu refait un tableau puis .list=....
Si TextColumn > 1 (d'après ce que j'ai compris), .List = provoque le RAZ de la zone texte de la ComboBox et donc un évènement _Change() si elle n'était pas vide, ce qui n'arrive pas en TextColumn = 1.
C'est ce que j'ai expliqué plus haut qui nécessite une parade dans le code pour d'une part ignorer le _Change() en question et remettre la bonne valeur en zone texte de la ComboBox et donc ignorer le 2ème _Change() associé.
 

patricktoulon

XLDnaute Barbatruc
comme je te l'ai dis en matchentry none tu n'a pas besoins de masque label ou autre
tu sépare juste les expressions(sensées être dans une colonne) par un espace
perso je fait ça avec un combo caché par flemme
mais je pourrais très bien le faire avec un tableau redim preserve
 

Dudu2

XLDnaute Barbatruc
Donc tu affiches les différentes colonnes dans une seule colonne ?

De toutes façons, la composition des ComboBoxes candidates à ces fonctions (saisie filtrée, affichage multi-colonnes) est sous le contrôle des utilisateurs. Donc je prends les ComboBoxes telles que fournies et le code travaille dessus.
Pour l'affichage multi-colonnes, il faut garder un alignement des colonnes et donc séparer les valeurs en affichage. Les Labels servent à ça.
 
Dernière édition:

patricktoulon

XLDnaute Barbatruc
oui mais si j'ai bien compris ton truc
pour la recherche, tu travaille que le textcolumn donc une colonne
c'est donc pareil que tu cherche dans une colonne ou une autre
si tu cherche dans plusieur colonne là peut être oui mais dans ton exemple en l'occurence non puisque tu recherche dans la colonne index1(donc la 2d)
mais bon si ça vous convient y a pas de soucis
 

patricktoulon

XLDnaute Barbatruc
tiens regarde
on prend le même tableau comme ça tu vois que l'on a pas besoins de mask
et encore je fait ça a la ouff c'est certainement perfectible et consolidable
mais bon tu vois bien que j'ai le même résultat que toi
demo.gif


le change laisse le de coté pour ce genre de travaux ;)
ce qu'il faut comprendre c'est qu'en matchentry none le value de la combo n'est rien d'autre qu'un textbox
 

patricktoulon

XLDnaute Barbatruc
2 combo avec 3 colonnes et le textcolumn à 2
VB:
Option Explicit
Option Compare Text
Dim TBL

Private Sub ComboBox1_DropButtonClick()
    ComboBox1.List = TBL
End Sub


Private Sub ComboBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
    recall ComboBox1.Text & Chr(KeyAscii)
    ComboBox1.DropDown
    If Len(ComboBox1.Text & Chr(KeyAscii)) > 2 Then KeyAscii = 0
End Sub

Private Sub ComboBox1_KeyUp(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
    recall ComboBox1.Text
    ComboBox1.DropDown
End Sub

Private Sub UserForm_Activate()
   Dim I&
   TBL = Range("tableau3").Resize(, 4)
    For I = 1 To UBound(TBL): TBL(I, 3) = I: Next
    ComboBox1.List = TBL
End Sub

Sub recall(v)
    Dim I&
    Me.Caption = "*" & Replace(v, " ", "*") & "*"
    ComboBox2.Clear
    For I = 1 To UBound(TBL)
        If " " & TBL(I, 2) & " " Like ("*" & Replace(v, " ", "*") & "*") Then
            With ComboBox2
                .AddItem TBL(I, 1)
                .List(.ListCount - 1, 1) = TBL(I, 2)
                .List(.ListCount - 1, 2) = TBL(I, 3)
            End With
        End If
    Next
    ComboBox1.List = ComboBox2.List
    ComboBox1.Text = v
End Sub
 

aurelio.ewane

XLDnaute Occasionnel
re

bonjour a tous
perso j'aimerais bien comprendre
là on part sur des controls dynamico et même une classe
tout ça pour un contrôle de saisie même dans une combobox
c'est quoi le but final du truc ?
sachant que:
on a la possibilité d’exécuter le code du change seulement si c'est le control actif si on veut
parti de là en mode entry none on a pa""s l'auto completion on teste donc dans une variable tableau
Merci de vos messages mais décidément je ne comprends rien je cherchais tout simplement a fire une recherche intuitive dans un combobox Multicolonnes et quand on saisi un mot qui n'est pas dans la liste listindex passe a -1 bien que en arrière plan nous ayons la liste mais avec le dropDown qui reduit je pourrais joindre un fichier sil vous plait
 

aurelio.ewane

XLDnaute Occasionnel
que re
2 combo avec 3 colonnes et le textcolumn à 2
VB:
Option Explicit
Option Compare Text
Dim TBL

Private Sub ComboBox1_DropButtonClick()
    ComboBox1.List = TBL
End Sub


Private Sub ComboBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
    recall ComboBox1.Text & Chr(KeyAscii)
    ComboBox1.DropDown
    If Len(ComboBox1.Text & Chr(KeyAscii)) > 2 Then KeyAscii = 0
End Sub

Private Sub ComboBox1_KeyUp(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
    recall ComboBox1.Text
    ComboBox1.DropDown
End Sub

Private Sub UserForm_Activate()
   Dim I&
   TBL = Range("tableau3").Resize(, 4)
    For I = 1 To UBound(TBL): TBL(I, 3) = I: Next
    ComboBox1.List = TBL
End Sub

Sub recall(v)
    Dim I&
    Me.Caption = "*" & Replace(v, " ", "*") & "*"
    ComboBox2.Clear
    For I = 1 To UBound(TBL)
        If " " & TBL(I, 2) & " " Like ("*" & Replace(v, " ", "*") & "*") Then
            With ComboBox2
                .AddItem TBL(I, 1)
                .List(.ListCount - 1, 1) = TBL(I, 2)
                .List(.ListCount - 1, 2) = TBL(I, 3)
            End With
        End If
    Next
    ComboBox1.List = ComboBox2.List
    ComboBox1.Text = v
End Sub
Que represente Tableau 3
 

patricktoulon

XLDnaute Barbatruc
re
le tableau 3 c'est un tableau structuré dans la feuille pour l'exemple
un range quoi
mais si il le faut voila le fichier
là je montre la combo 2 mais le principe c'est de la cacher
j'ai exactement le résultat que propose @Dudu2 avec sa méthode
sauf que je n'utilise pas de module classe pas de label masck
juste une 2d combo dans une sub qui renvoie la listre filtré de la combo2 dans la combo1 et remet aussi le .text
tout simplement ;)

quand on s'amuse a faire des filtres dans une combo ou listbox l'event change qui est "a postériori"
est à proscrire sinon c'est l'usine a gaz le truc
privilégier les event que l'on peut intercepter qui peuvent être annulés ce qui est justement le cas avec keyascii=0

voila voila ;)
 

Pièces jointes

  • Classeur1.xlsm
    16.9 KB · Affichages: 4
Dernière édition:

patricktoulon

XLDnaute Barbatruc
et si tout d'un coup tu a un regain d'énergie et que la femme te quitte
tu vire la combo2 et tu te sert d'une variable tableau redimée et préservée transposé et tu renvoie ce tableau dans la combo1
ainsi que le texte tapé
voila comme je le disais l'input de la combo n'est qu'un input en mode matchentry none
VB:
Option Explicit
Option Compare Text
Dim TBL

Private Sub ComboBox1_DropButtonClick()
    ComboBox1.List = TBL
End Sub


Private Sub ComboBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
    recall ComboBox1.Text & Chr(KeyAscii)
    ComboBox1.DropDown
    If Len(ComboBox1.Text & Chr(KeyAscii)) > 2 Then KeyAscii = 0
End Sub

Private Sub ComboBox1_KeyUp(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
    recall ComboBox1.Text
    ComboBox1.DropDown
End Sub

Private Sub UserForm_Activate()
    Dim I&
    TBL = Range("tableau3").Resize(, 4)
    For I = 1 To UBound(TBL): TBL(I, 3) = I: Next
    ComboBox1.List = TBL
End Sub

Sub recall(v)
    Dim I&, tbl2(), a&
    Me.Caption = "*" & Replace(v, " ", "*") & "*"
    ComboBox2.Clear
    For I = 1 To UBound(TBL)
        If " " & TBL(I, 2) & " " Like ("*" & Replace(v, " ", "*") & "*") Then
            a = a + 1: ReDim Preserve tbl2(1 To 3, 1 To a)
            tbl2(1, a) = TBL(I, 1)
            tbl2(2, a) = TBL(I, 2)
            tbl2(3, a) = TBL(I, 3)
        End If
    Next
    ComboBox1.Column = tbl2
    ComboBox1.Text = v
End Sub

pas la peine de dire que l'on peut encore simplifier un petit peu si ça fait trop de lignes de code

LOL
 

patricktoulon

XLDnaute Barbatruc
allez si on simplifie
VB:
Option Explicit
Option Compare Text
Dim TBL

Private Sub ComboBox1_DropButtonClick()
    ComboBox1.List = TBL
End Sub


Private Sub ComboBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
      recall ComboBox1.Text & Chr(KeyAscii)
    ComboBox1.DropDown
    If Len(ComboBox1.Text & Chr(KeyAscii)) > 2 Then KeyAscii = 0
End Sub

Private Sub ComboBox1_KeyUp(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
    recall ComboBox1.Text
    ComboBox1.DropDown
End Sub

Private Sub UserForm_Activate()
    Dim I&
    TBL = Range("tableau3").Resize(, 4)
    For I = 1 To UBound(TBL): TBL(I, 3) = I: Next
    ComboBox1.List = TBL
End Sub

Sub recall(v)
    Dim I&, tbl2(), a&, c&
     For I = 1 To UBound(TBL)
       DoEvents
       If " " & TBL(I, 2) & " " Like ("*" & Replace(v, " ", "*") & "*") Then
            a = a + 1: ReDim Preserve tbl2(1 To ubound(tbl), 1 To a)
            For c = 1 To 3: tbl2(c, a) = TBL(I, c): Next
        End If
    Next
    If a > 0 Then ComboBox1.Column = tbl2: ComboBox1.Text = v
End Sub
on remarquera que dès que l'on tape une lettre de plus et que ca correspond a rien on a le tableau complet et le .text reste a ce qui est valable
voila messieurs ;) nul besoins de sortir l'artillerie lourde pour jouer a faire un fifiltre
 

Dudu2

XLDnaute Barbatruc
Bonjour à tous,
Eh ben, heureusement que @patricktoulon est passé par là pour faire le ménage et donner une solution simple qui fonctionne ! 🥸

Sinon, autre choix, si on ne veut rester basique sans afficher toutes les colonnes en zone texte de la ComboBox comme ci-dessus, il y a toujours la ressource VBA - Saisie filtrée (alias saisie intelligente) en ComboBox qui gère le multi-colonnes. D'une simplicité enfantine. Suffit de lire !
 

Discussions similaires

Statistiques des forums

Discussions
314 862
Messages
2 113 632
Membres
111 927
dernier inscrit
kavelar