XL 2021 Liste déroulante filtrée par les 2 premiers caractères

  • Initiateur de la discussion Initiateur de la discussion YGU1
  • Date de début Date de début

Boostez vos compétences Excel avec notre communauté !

Rejoignez Excel Downloads, le rendez-vous des passionnés où l'entraide fait la force. Apprenez, échangez, progressez – et tout ça gratuitement ! 👉 Inscrivez-vous maintenant !

YGU1

XLDnaute Nouveau
Bonjour,

Je reviens dans la partie, après plusieurs tests sur ma base d'évaluation des juges, on m’a fait remarquer qu’il sera judicieux qu’a partir de ma liste déroulante de juges, si je saisissais les deux premiers caractères dans la zone de la liste, s’affiche seulement ceux qui correspondent aux premiers caractères saisis

J’ai ma base de test avec un onglet Clubs_Juges avec une zone blanche où l'utilisateur peut saisir des données libres et une zone importante le juges en colonne B grisée pour me pas les modifier et classés par ordre alphabétique.

La liste déroulante se trouve sur un autre onglet Données, comment filtrer en tapant par exemple BE et s’affiche seulement les valeurs ci-dessous et je n’ai plus qu’a sélectionner la valeur souhaitée

BEATRIX Julie
BEAUCHENE Aurore
BERENGUER Delphine
BERLAND Laure
BERNARD Aurélie
BERTHET Sandra
BERTHIER-STENGEL Anne
BERTRAND Julie
BEZIERS Charlène



Par la suite, lorsque j'aurai compris l'astuce, je ferais la même chose pour les clubs en colonne A

Cordialement
Yves
 

Pièces jointes

Bonjour
@Dudu2 tu a oublié que quand x classes sont instanciée dans une instance mère
elle ne se détruisent automatiquement pas au terminate de celle ci
VB:
Private Sub Class_Terminate()
Erase TabComboBoxEvents
End Sub
j'ai ajouter une variable index et un msgbox pour que tu puisse voir le phénomène de l'event propagation à fonctionner comme ça
tu va voir le msgbox se répète 2 fois
VB:
Option Explicit

Public WithEvents ComboBox As MSForms.ComboBox
Private TabComboBoxEvents() As Classe_ComboBoxEvents
Public ComboBoxEventsInitial As Classe_ComboBoxEvents
Public CurrentComboBox As ComboBox  'Variable partagée valorisée uniquement dans l'instance invoquée par l'appelant
Public index As Long
Public Sub SetComboBoxEvents(ParamArray TabComboBox() As Variant)
    Dim i As Integer

    'Instance de la Classe invoquée par l'appelant qui seule contient la variable CurrentComboBox valorisée
    'accessible en instance de Classe ComboBox par Me.ComboBoxEventsInitial.CurrentComboBox
    Set ComboBoxEventsInitial = Me
    Me.index = -1
    'Tables des instances de Classe des ComboBox
    ReDim TabComboBoxEvents(LBound(TabComboBox) To UBound(TabComboBox))
    
    For i = LBound(TabComboBox) To UBound(TabComboBox)
        Set TabComboBoxEvents(i) = New Classe_ComboBoxEvents
        Set TabComboBoxEvents(i).ComboBox = TabComboBox(i)
        Set TabComboBoxEvents(i).ComboBoxEventsInitial = Me
    TabComboBoxEvents(i).index = i
    Next i
End Sub

'-----------------
'ComboBox_GotFocus 'NON GÉRÉ PAR LA CLASSE !!!
'-----------------
Private Sub ComboBox_GotFocus()
    Call SaisieFiltréeComboBoxEnter(ComboBox, ThisWorkbook.Worksheets("Listes").ListObjects("TableauJuges").DataBodyRange)
End Sub

Private Sub Class_Initialize()

End Sub

Private Sub Class_Terminate()
Erase TabComboBoxEvents
End Sub

Private Sub ComboBox_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal x As Single, ByVal y As Single)
    MsgBox index & vbCrLf & Me.index
    If Not Me.ComboBoxEventsInitial.ComboBox Is ComboBox Then
        Call SaisieFiltréeComboBoxEnter(ComboBox, ThisWorkbook.Worksheets("Listes").ListObjects("TableauJuges").DataBodyRange)
        Set Me.ComboBoxEventsInitial.ComboBox = ComboBox
    End If
End Sub

'---------------
'ComboBox Change
'---------------
Private Sub ComboBox_Change()
    Call SaisieFiltréeComboBoxChange(ComboBox)
End Sub

'---------------
'ComboBox Scroll
'---------------
Private Sub ComboBox_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal x As Single, ByVal y As Single)
   Call ControlScroll(ComboBox)
End Sub
 
Bonjour @patricktoulon,
Je ne conteste pas que la terminaison de l'instance principale ne détruise pas les instances secondaires, c'est bien possible.
En l'occurrence il n'y a jamais de terminaison de la classe principale puisque toutes les instances secondaires des ComboBoxes sont crées 1 fois sur l'Aut😵pen().
Mais d'une manière générale il faudrait donc faire ce que tu préconises:
VB:
Private Sub Class_Terminate()
    Erase TabComboBoxEvents
End Sub

Par contre je ne comprends pas du tout ce qui se passe par ta démonstration avec l'index car tu soulèves un sacrè lièvre.

Si sur 1 seul évènement on a 2 fois l'exécution de la fonction de l'évènement:
-1ère fois avec l'index de l'instance secondaire de la ComboBox qui est normale
-2ème fois avec l'index de l'instance principale (index = -1) qui pourtant n'a aucune ComboBox associée !
ça veut dire que ce système d'instances secondaires n'est pas judicieux sauf à avoir un système pour ignorer les exécutions d'évènements sur l'instance principale.
 
re
et voila tu commence a observer le truc c'est bien pour ça que j'ai utilisé ce stratagème de msgbox avec l'index original et celui qui est dynamique
en reconditionnant ton me.(classemère).combobox tu réinitialise et ça déclenche forcement l'event
de la même manière que le changement de valeur d'un control par vba déclenche son click ou autre de ses event attachés

et il faut y faire attention car l'event qui se déclenche 2 fois peut donner une valeur différente dans certains cas

connaissant très bien le phénomène depuis fort longtemps il y a des choses que j’évite de faire avec les classe controls
c'est le genre de truc qui parfois te renvoie une erreur " mémoire insufisante" ( je suppose que tu a du l'avoir un certain nombre de fois ce message)et vont parfois jusqu’à planter le fichier
A bon entendeur 😉
Patrick
 
Si j'ai utilisé ce système assez innocemment, c'est parce que je te l'ai vu faire 😉.
Donc quelque soit la méthode, tableau ou collection d'instances de classe, ce système d'instanciation ne fonctionne pas.

je précise quand te donnant cet exemple avec "index" je t'ai donné la solution par la même occasion
Oui je l'ai déjà indiqué: "sauf à avoir un système pour ignorer les exécutions d'évènements sur l'instance principale." en utilisant l'Index pour ignorer l'évènement. Mais c'est quand même limite comme approche.
 
Et franchement ça:

-2ème fois avec l'index de l'instance principale (index = -1) qui pourtant n'a aucune ComboBox associée !
ça le laisse pantois !
et bien sur que si
relis ton event doucement c'est toi qui le crée

et oui c'est le phénomène event propagation que l'on retrouve dans tout les langages
sauf quand dans certains langage on a des fonctions qui le stop
par exemple en JS on a e.StopEventpropagation(e=event) ou event.StopEvent pour les vielle version html

c'est assez simple à comprendre
 
C'est assez compliqué.
Je n'ai plus les doubles appels d'évènements et je ne sais pas pourquoi, peu importe. Code mieux maîtrisé on dira...
Toujours est-il qu'il faut avoir en tête les points suivants:
  1. Si la L'instance principale (initialisation) qui a lancé la création des instances secondaires (ComboBoxes) se termine => Toutes les instances secondaires se terminent automatiquement. Vérifié !

  2. Une instance ne peut pas se terminer tant qu'elle est référencée dans une autre instance.

  3. Il est possible d'instancier l'instance principale (initialisation) au niveau d'un Module ou au niveau d'une Fonction.

    Au niveau Module (recommandé):
    VB:
    Private ComboBoxEvents As New Classe_ComboBoxEvents
    Sub InitComboBoxes()
        Call ComboBoxEvents.Initialisation
    End Sub

    Au niveau Fonction:
    VB:
    Sub InitComboBoxes()
        Dim ComboBoxEvents As New Classe_ComboBoxEvents
        Call ComboBoxEvents.Initialisation
    End Sub

    La déclaration au niveau Module est recommandée car sa portée permet d'y faire référence dans une autre fonction du Module qui pourra par exemple être utilisée pour terminer l'instance principale.

  4. Si on instancie l'instance principale (initialisation) au niveau d'une Fonction, elle est sensée s'éteindre à la fin de la Fonction.
    Sauf si on la référence dans les instances secondaires (ComboBoxes) qui par conséquent continueront à exister avec elle (voir points #1 et #2). On doit donc référencer l'instance principale (initialisation) dans les instances secondaires (ComboBoxes) pour maintenir ce petit monde en vie même après la fin de la Fonction !

    Si nécessaire on peut alors en profiter pour placer dans l'instance principale les variables à partager entre toutes les instances car l'instance principale étant référencée dans les instances secondaires, les instances secondaires ont accès à ses variables.

  5. Si on instancie l'instance principale (initialisation) au niveau d'un Module il n'est pas utile de référencer l'instance principale (initialisation) dans les instances secondaires (ComboBoxes) car l'instance principale ne s'éteindra pas après l'initialisation à la fin de la Fonction.

    Si nécessaire on peut alors choisir soit l'instance principale soit n'importe quelle instance secondaire (par exemple la 1ère) pour héberger les variables à partager entre toutes les instances à condition évidemment de référencer cette instance principale ou secondaire dans toutes les instances secondaires pour avoir accès à ses variables.

    Dans la mesure où l'utilisation de l'instance principale pour héberger les variables partagées s'applique aux 2 options d'instanciation de l'instance principale (niveau Module et niveau Fonction), il vaut mieux l'utiliser dans ce but.
    Ça permet en plus de ne pas avoir à reporter dans une instance secondaire des initialisations de variables partagées qu'on fait par commodité sur l'instance principale.

  6. Problème lié au référencement de l'instance de Classe dédiée à l'hébergement des variables partagées si utilisée.
    Quelque soit cette instance, principale ou secondaire, selon le principe du point #2, son référencement dans les autres instances empêchera sa terminaison. Par conséquent, avant de terminer l'instance principale:
    VB:
    Set ComboBoxEvents = Nothing
    il faut passer par une fonction Public de la Classe qui dé-référence l'instance de classe dédiée à l'hébergement des variables partagées de toutes les instances.
    Code:
    Call ComboBoxEvents.DereferenceSharedVariablesInstance
    Set ComboBoxEvents = Nothing
    Alors, selon le point #1, toutes les instances se termineront.
 

Pièces jointes

Dernière édition:
- Navigue sans publicité
- Accède à Cléa, notre assistante IA experte Excel... et pas que...
- Profite de fonctionnalités exclusives
Ton soutien permet à Excel Downloads de rester 100% gratuit et de continuer à rassembler les passionnés d'Excel.
Je deviens Supporter XLD
Retour