🚀The world's best VBA AI has evolved. ExcelMaster is now an autonomous Agent.Read more →
Back to Blog

VBA ComboBox dans Excel — Remplir une liste déroulante, lire le choix et le piège ListIndex = -1

|

VBA ComboBox dans Excel — Remplir une liste déroulante, lire le choix et le piège ListIndex = -1

TL;DR — Un ComboBox est une liste déroulante : choisissez un élément, ou (par défaut) saisissez le vôtre. Remplissez-le avec ComboBox1.List = Range("A2:A50").Value. Il répond à deux questions à la fois — quel élément via .ListIndex (base 0, -1 quand le texte n'est pas dans la liste) et quel texte via .Value. Le piège : .Value <> "" prouve seulement que la boîte n'est pas vide, pas que l'utilisateur a choisi un véritable élément. S'il vous faut un choix de liste valide, testez .ListIndex >= 0, ou interdisez la saisie avec .Style = fmStyleDropDownList.

' Lire un choix de ComboBox - exiger qu'il vienne de la liste
Private Sub cmdOK_Click()
    If ComboBox1.ListIndex = -1 Then
        MsgBox "Please choose an item from the list."
        Exit Sub
    End If
    MsgBox "You chose " & ComboBox1.Value       ' un vrai choix issu de la liste
End Sub

Un ComboBox est un contrôle sur un UserForm, et il suit la même règle que tout autre contrôle : vous lisez le choix à travers une propriété, non sur la boîte elle-même. La différence avec un ListBox, c'est qu'un ComboBox affiche une seule ligne et peut accepter la saisie — c'est exactement là que se niche le bug intéressant.

Ce que vous allez apprendre

  • Pourquoi un ComboBox est un ListBox replié sur une seule ligne, et se lit presque de la même façon
  • Le remplir avec .List = Range.Value en un coup, ou .AddItem pour les éléments calculés
  • Les deux questions auxquelles il répond : quelle ligne (.ListIndex) et quel texte (.Value)
  • La propriété .Style — fmStyleDropDownCombo laisse l'utilisateur saisir, fmStyleDropDownList non
  • Le piège numéro un : .Value <> "" n'est pas un choix valide ; testez .ListIndex >= 0
  • Quand un ComboBox est le bon contrôle et quand un ListBox convient mieux

Le modèle mental : un ListBox sur une seule ligne qui vous laisse aussi saisir

Un ComboBox est un ListBox plié en une seule ligne avec une flèche déroulante. Vous le remplissez de la même façon, et vous le lisez avec les deux mêmes propriétés — mais parce qu'il peut aussi accepter du texte libre, il répond toujours à deux questions à la fois :

ComboBox1.ListIndex   ' QUELLE ligne est choisie (base 0, -1 = le texte n'est pas dans la liste)
ComboBox1.Value       ' QUEL texte est dans la boite (un element de liste, OU ce qui a ete saisi)

Tenez ces deux-là séparées et le contrôle prend sens. .Value est ce que dit la boîte. .ListIndex est si cela venait de la liste. Quand l'utilisateur choisit dans la liste déroulante, les deux concordent. Quand l'utilisateur saisit quelque chose de neuf, .Value contient le texte saisi et .ListIndex vaut -1 — le signal que le texte n'est pas un élément de la liste.

Remplir un ComboBox

Le remplissage est identique à celui d'un ListBox. Affectez une colonne entière d'un coup, c'est le chemin rapide :

Private Sub UserForm_Initialize()
    ComboBox1.List = Sheet1.Range("A2:A50").Value   ' un seul coup depuis une colonne
End Sub

Range.Value est un tableau 2D et .List en accepte un, si bien qu'une seule ligne charge la liste déroulante (voyez VBA Range). N'utilisez .AddItem que pour des éléments construits un à un :

Dim i As Long
For i = 1 To 12
    ComboBox1.AddItem "Month " & i     ' ajouter des elements calcules un a un
Next i

Appelez ComboBox1.Clear pour la vider avant de la remplir à nouveau. Si vous voulez que la boîte affiche d'emblée une valeur par défaut, mettez .ListIndex = 0 après le remplissage, ou affectez .Value à un élément connu.

Style : décider si l'utilisateur peut saisir

C'est la propriété que les gens ratent. Un ComboBox a un .Style qui gouverne tout son caractère :

ComboBox1.Style = fmStyleDropDownCombo   ' defaut : choisir dans la liste OU saisir le sien
ComboBox1.Style = fmStyleDropDownList    ' verrouille : l'utilisateur ne peut QUE choisir un element

fmStyleDropDownCombo est la valeur par défaut — l'utilisateur peut saisir n'importe quoi. fmStyleDropDownList transforme le ComboBox en un sélecteur strict : la saisie ne fait que sauter vers les éléments correspondants, et la valeur finale est toujours l'une des vôtres. Si votre formulaire ne doit pas accepter de texte libre, réglez le .Style — n'essayez pas de le valider après coup.

Le piège numéro un : une boîte non vide n'est pas un choix valide

Voici le bug qui laisse passer les mauvaises données. Avec le style par défaut, l'utilisateur peut saisir une valeur qui n'est pas dans votre liste. Si votre code vérifie seulement que la boîte n'est pas vide, il accepte volontiers la faute de frappe :

' WRONG - accepts anything the user typed
If ComboBox1.Value <> "" Then ProcessOrder ComboBox1.Value

' RIGHT - insist the choice came from the list
If ComboBox1.ListIndex >= 0 Then
    ProcessOrder ComboBox1.Value
Else
    MsgBox "Please choose an item from the list, not free text."
End If

.Value <> "" ne prouve que quelque chose est dans la boîte. .ListIndex >= 0 prouve que l'utilisateur a choisi un véritable élément de liste — car .ListIndex vaut -1 dès que le texte est saisi plutôt que choisi. La règle est simple : quand un choix de liste valide compte, testez .ListIndex, jamais .Value <> "". Si le texte libre ne doit jamais être possible du tout, le correctif le plus propre est en amont — réglez .Style = fmStyleDropDownList et le piège ne peut plus se produire. (Il existe aussi une propriété .MatchRequired qui rejette une saisie sans correspondance quand la boîte perd le focus, mais régler le .Style est l'outil le plus radical et le plus sûr.)

Value ou Text, et réagir à un changement

Pour un ComboBox, .Value et .Text renvoient d'ordinaire la même chaîne. Celle que vous utiliserez est .Value. .Text compte quand vous vous souciez de ce qui est affiché pendant la frappe, avant que l'entrée ne soit validée. Pour réagir à l'instant où l'utilisateur change la sélection, gérez l'événement Change :

Private Sub ComboBox1_Change()
    ' se declenche a chaque frappe et a chaque choix - restez leger
    Label1.Caption = "Current: " & ComboBox1.Value
End Sub

Comme Change se déclenche à chaque frappe dans un ComboBox où l'on peut saisir, gardez ce gestionnaire économe — ne lancez pas une recherche en base de données à chaque caractère.

ComboBox ou ListBox ? Choisissez selon la place et la multiplicité

Un ComboBox et un ListBox partagent leurs propriétés de remplissage et de lecture, alors choisissez selon la façon dont le choix doit se comporter. Utilisez un ComboBox quand la réponse est une valeur unique, que la place est comptée et qu'une liste déroulante repliée fait plus net — ou quand vous voulez autoriser la saisie libre. Utilisez un ListBox quand les options doivent être visibles d'un coup d'œil ou que l'utilisateur peut en choisir plus d'une ; la multi-sélection est une fonctionnalité propre au ListBox. Un ComboBox ne peut jamais renvoyer plusieurs éléments.

Comment ExcelMaster vous aide

L'échec discret ici, c'est un ComboBox qui accepte tout ce que l'utilisateur saisit parce que le code a vérifié .Value <> "" au lieu de .ListIndex >= 0 — si bien qu'un nom de produit mal orthographié file droit dans vos données.

ExcelMaster vous laisse décrire le contrôle en mots simples — « une liste déroulante de codes produits parmi lesquels l'utilisateur doit choisir, sans texte libre » — et il règle le bon .Style, remplit la liste depuis vos données, et lit le choix en testant .ListIndex pour que seules les vraies sélections passent. Vous gardez le classeur et le code.

Questions fréquentes

Comment remplir un ComboBox depuis une plage en VBA ?

Affectez la plage à .List en une seule instruction : ComboBox1.List = Sheet1.Range("A2:A50").Value. Comme Range.Value est un tableau 2D et que .List en accepte un, cela charge toute la colonne d'un coup. N'utilisez .AddItem que pour des éléments que vous construisez un à un, et appelez .Clear avant de remplir à nouveau une boîte qui a déjà des lignes.

Comment obtenir la valeur sélectionnée d'un ComboBox en VBA ?

Lisez .Value pour le texte de l'entrée courante et .ListIndex pour la ligne (base 0) d'où elle vient. .ListIndex vaut -1 quand le texte a été saisi plutôt que choisi dans la liste, donc si vous exigez un vrai choix de liste, testez .ListIndex >= 0 avant d'agir sur .Value.

Comment empêcher l'utilisateur de saisir du texte libre dans un ComboBox ?

Mettez ComboBox1.Style = fmStyleDropDownList. Cela verrouille le contrôle aux seuls éléments de liste — la saisie ne fait que sauter vers les entrées correspondantes et la valeur finale est toujours l'une des vôtres. La valeur par défaut, fmStyleDropDownCombo, autorise la saisie libre, et c'est pourquoi valider avec .ListIndex >= 0 compte quand vous la conservez.

Que signifie ListIndex = -1 sur un ComboBox ?

Cela signifie que le texte courant n'est pas l'un des éléments de la liste — soit la boîte est vide, soit l'utilisateur a saisi quelque chose qui ne correspond pas. Un choix valide dans la liste déroulante donne toujours un .ListIndex de 0 ou plus, donc .ListIndex = -1 est votre signal pour rejeter l'entrée ou redemander.

Quelle est la différence entre un ComboBox et un ListBox ?

Un ComboBox affiche une seule ligne avec une liste déroulante, renvoie une valeur unique et peut autoriser la saisie libre ; un ListBox affiche plusieurs lignes à la fois et peut autoriser plusieurs sélections. Choisissez un ComboBox pour un choix unique compact, un ListBox quand les options doivent être visibles ou que l'utilisateur en choisit plus d'une.

Testé dans

Testé dans : Excel 365 (Windows 11), VBA 7.1 — vérifié le 25/09/2026.

Guides associés : VBA ListBox · VBA CheckBox · VBA UserForm · VBA Range · VBA InputBox