Préambule :
Cette contribution fait suite à ce sujet, dont la question est :
Les différentes méthodes décrites dans cette discussion ne sont, dans l'état, soit, pas fiables, soit, pas génériques, soit incomplets.Je souhaiterais empêcher toute saisie si le texte entrant dans la ComboBox ne correspond pas à la liste initiale du contrôle.
Je me permets donc de décrire ici une autre méthode, pour le cas où, l’internaute que vous êtes, ne trouverait pas son bonheur dans la susdite discussion.
- Description du contrôle ComboBox :
Un contrôle ComboBox est composé de deux éléments :
- Une partie texte (similaire à un contrôle TextBox) qui est la zone de saisie du contrôle,
- Une partie liste (similaire à un contrôle ListBox) qui est la zone de liste (déroulante) de ce contrôle.
Cette description est à conserver dans un coin de votre mémoire, nous nous en servirons plus tard dans cette contribution.
- Les propriétés intéressantes :
La totalité de ces détails sont issus de l'aide VBA (qui en comporte encore de nombreux, n'hésitez pas à la consulter).
Je n'invente donc rien.
- La propriété Style.
Pour un contrôle ComboBox, spécifie de quelle façon l'utilisateur va utiliser le contrôle.
Les valeurs de fmStyle sont les suivantes :
- fmStyleDropDownCombo (Valeur : 0) : Le contrôle ComboBox se comporte comme une liste modifiable déroulante.
L'utilisateur peut saisir une valeur dans la zone d'édition ou en sélectionner une dans la liste déroulante (par défaut).- fmStyleDropDownList (Valeur : 2) : Le contrôle ComboBox se comporte comme une zone de liste.
L'utilisateur doit choisir une valeur dans la liste.- La propriété MatchEntry.
Nous ne l'utiliserons pas ici, mais elle mérite d'être connue.
Renvoie ou définit une valeur indiquant la façon dont un contrôle ListBox ou ComboBox fait des recherche dans ses listes pendant la saisie de l'utilisateur.
- fmMatchEntryFirstLetter (Valeur : 0) : Correspondance de base. Le contrôle recherche l'entrée suivante qui commence par le caractère saisi.
La frappe répétée de la même lettre parcourt toutes les entrées commençant par cette lettre.- fmMatchEntryComplete (Valeur : 1) : Correspondance étendue.
Pour la frappe de chaque caractère, le contrôle recherche une entrée correspondant à tous les caractères saisis (par défaut).- fmMatchEntryNone (Valeur : 2) : Aucune correspondance.
- La propriété MatchRequired.
Spécifie si une valeur saisie dans la partie texte d'un contrôle ComboBox doit correspondre à une entrée de la partie liste existante du contrôle. L'utilisateur peut taper des valeurs non correspondantes, mais ne peut pas quitter le contrôle sans qu'une valeur correspondante soit saisie.- Démarche :
- Premier cas : Utilisation de la liste comme une liste déroulante modifiable, la propriété Style réglée sur fmStyleDropDownCombo.
Ici, l’utilisateur peut saisir exactement ce qu’il souhaite.
Pour obtenir le résultat escompté ici, il nous faut donc ajouter une autre propriété l’empêchant de faire n’importe quoi. La propriété MatchRequired est idéale pour cela : L'utilisateur peut taper des valeurs non correspondantes, mais ne peut pas quitter le contrôle sans qu'une valeur correspondante soit saisie.
Parfait !
Le code est donc :
Ce code est fonctionnel, mais voilà, l’utilisateur se plaint qu’il n’y a pas de vérification en cours de saisie et qu'en cas d'erreur, il ne le sait qu'à la fin...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 With ComboBox1 .Style = fmStyleDropDownCombo .MatchRequired = True End With
- Second cas : Utilisation de la liste comme une zone de liste, la propriété Style réglée sur fmStyleDropDown.
Eh bien, dans ce cas, rien à ajouter. Le code est donc :
Le gros bémol de cette méthode réside dans le fait que, dès que l’utilisateur saisi un caractère correct, la zone de texte est complétée par le premier item correspondant dans la liste.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 With ComboBox1 .Style = fmStyleDropDownList End With
L’utilisateur ne visualise plus ou il en est de sa saisie.
Les contrôles ComboBox ne disposant pas des propriétés SelLenght et SelStart, ce souci ne peut être résolu.- Particularité à prendre en compte absolument :
Ces codes, extrêmement simples, ne sont pas applicables tels quels selon les types de données entrées dans la liste.
J’en reviens à ma description.
La zone de saisie renvoie systématiquement une donnée de type String (VarType = 8).
La zone de liste, elle, est de type Variant/Variant (VarType = 8204 [8192 (Variant Tableau) + 12 (Variant)].
Lorsque cette liste contient des items numériques, des dates, des valeurs de type Currency (etc…), le type de chacun de ses items est Variant/Type de l’item.
Soit, pour une date, de type Variant/Date.
Lors de l’utilisation des codes donnés plus haut, si vos données ne sont pas de type String, la comparaison entre la zone de texte et la zone de liste ne trouvera aucune correspondance.
Il convient donc, pour tous les types de données cités ci-dessous, de convertir toute la liste avant de l’attribuer au contrôle ComboBox.
Types de données à convertir absolument :
Integer
Long
Single
Double
Currency
Date
Byte
LongLong- Codes à appliquer pour ces cas :
Note : Je ne m’attarde pas ici sur les variables tableaux et utilise des bornes figées. A vous d’adapter cela à votre contexte.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 Private Sub UserForm_Activate() Dim L(364) As String, v As Variant, i As Long ' transfert des données en mémoire v = Range("C1:C365").Value ' Conversion des données en String For i = 1 To 365 L(i - 1) = v(i, 1) Next With ComboBox1 .List = L .Style = fmStyleDropDownCombo .MatchRequired = True End With End Sub
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 Private Sub UserForm_Activate() Dim L(364) As String, v As Variant, i As Long ' transfert des données en mémoire v = Range("C1:C365").Value ' Conversion des données en String For i = 1 To 365 L(i - 1) = v(i, 1) Next With ComboBox1 .List = L .Style = fmStyleDropDownList End With End Sub- Cas très particulier :
L'alimentation du contrôle ComboBox via sa propriété rowSource.
Cela ne pose pas de problème pour des données numériques ou du texte. Les codes donnés ci-dessus restent fonctionnels.
Cependant, si vous entrez, par cette propriété, des données de type Date, dans votre ComboBox, ces codes ne fonctionneront pas, les Dates étant stockées sous forme numérique dans la feuille.
Il existe très certainement des petits soucis, dus principalement à une méconnaissance de l'utilisation de ce contrôle, mais vous devriez pouvoir satisfaire vos utilisateurs.
Certaines touches sont appréciables : Echap, flèche vers le haut (ou vers le bas)...
A vous lire.
Partager