Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Apprendre Introduction aux UserForms | Interaction Utilisateur
VBA Excel Pour l'Automatisation des Entreprises

Introduction aux UserForms

Glissez pour afficher le menu

Note
Remarque

Les UserForms disposent de fonctionnalités limitées ou absentes dans Excel pour Mac — l’IDE VBA sur Mac ne prend pas entièrement en charge la conception de UserForms dans de nombreuses versions, ce qui peut entraîner ce type de comportement inexpliqué.

MsgBox et InputBox conviennent pour des questions simples oui/non et des réponses sur une seule ligne, mais l’ajout d’un client nécessite souvent plusieurs champs à la fois — un nom d’entreprise, un contact, une ville, un statut. C’est à cela que sert un UserForm : une petite fenêtre personnalisée avec ses propres étiquettes, zones de texte, listes déroulantes et boutons, créée dans le VBE et entièrement contrôlée par votre code.

Création d’un formulaire

Dans le VBE, faites un clic droit sur votre projet dans l’Explorateur de projet et choisissez Insertion → UserForm. Une surface de conception vierge apparaît, accompagnée d’une boîte à outils flottante contenant des contrôles que vous pouvez y faire glisser.

Figure 5.3

Étiquettes, zones de texte, listes déroulantes et boutons

Chaque contrôle que vous faites glisser sur le formulaire reçoit un nom par défaut comme TextBox1 ou CommandButton1 — fonctionnel, mais dénué de sens dès qu’un formulaire comporte six ou sept contrôles. L’habitude la plus importante dans cette section est visible dans la fenêtre Propriétés : renommer chaque contrôle immédiatement après l’avoir ajouté, en utilisant un préfixe court qui identifie son type (txt pour TextBox, cbo pour ComboBox, cmd pour CommandButton, opt pour OptionButton, chk pour CheckBox, lst pour ListBox) suivi d’un nom descriptif. txtCompanyName reste clair dans le code même trois semaines plus tard ; TextBox1 ne l’est pas.

Les étiquettes sont de simples légendes textuelles non interactives (« Nom de l’entreprise ») — l’utilisateur peut les voir mais ne peut jamais y saisir de texte ni cliquer dessus. Les zones de texte servent à saisir du texte libre. Les listes déroulantes présentent une liste de choix, ce qui correspond exactement à l’utilisation de cboCity et cboStatus — restreindre Ville et Statut à une liste connue plutôt que de laisser un utilisateur saisir librement « chicago », « Chicago,IL » et « CHI » pour la même chose dans différents enregistrements.

Flux de création de formulaire

Écriture du code derrière le formulaire

Double-cliquer sur n'importe quel contrôle dans la zone de conception permet d'accéder directement à son code — VBA crée automatiquement une procédure d'événement nommée ControlName_EventName, et le code saisi à l'intérieur s'exécutera chaque fois que cet événement spécifique se produit sur ce contrôle. L'événement par défaut d'un bouton est Click :

Private Sub UserForm_Initialize()
    ' runs once, automatically, when the form is first shown
    cboCity.AddItem "Chicago"
    cboCity.AddItem "Boston"
    cboCity.AddItem "Austin"
    cboCity.AddItem "Seattle"
    cboCity.AddItem "Denver"
 
    cboStatus.AddItem "Active"
    cboStatus.AddItem "Inactive"
    cboStatus.AddItem "Prospect"
End Sub
 
Private Sub cmdCancel_Click()
    Unload Me
End Sub

UserForm_Initialize est une procédure d'événement spéciale qui se déclenche automatiquement au chargement du formulaire — avant que l'utilisateur ne voie quoi que ce soit — ce qui en fait l'endroit idéal pour remplir les ComboBox avec .AddItem plutôt que de saisir les choix manuellement dans la fenêtre Propriétés, surtout si ces choix peuvent évoluer ou provenir d'une feuille de calcul. Unload Me dans cmdCancel_Click ferme entièrement le formulaire ; Me fait toujours référence au formulaire dans lequel le code s'exécute actuellement, donc cette ligne fonctionne sans modification, quel que soit le nom que vous donnez ensuite au formulaire.

Exemple pratique : Enregistrement d'un nouveau client

Voici la procédure associée au bouton Enregistrer — celle qui écrit réellement une nouvelle ligne dans tblCustomers :

Private Sub cmdSave_Click()
    Dim tbl As ListObject
    Dim newRow As ListRow
 
    Set tbl = ThisWorkbook.Worksheets("Customers").ListObjects("tblCustomers")
    Set newRow = tbl.ListRows.Add
 
    newRow.Range(1, 1).Value = "C" & Format(tbl.ListRows.Count + 1, "000")
    newRow.Range(1, 2).Value = txtCompanyName.Value
    newRow.Range(1, 3).Value = txtContact.Value
    newRow.Range(1, 4).Value = txtEmail.Value
    newRow.Range(1, 5).Value = cboCity.Value
    newRow.Range(1, 6).Value = cboStatus.Value
 
    MsgBox txtCompanyName.Value & " was added successfully."
    Unload Me
End Sub
Analyse ligne par ligne
expand arrow
  • L'instruction tbl = ThisWorkbook.Worksheets("Customers").ListObjects("tblCustomers") permet d'accéder depuis le formulaire jusqu'au classeur — un UserForm n'est qu'un autre morceau de code, donc tout ce qui concerne les ListObjects s'applique sans changement ;
  • tbl.ListRows.Add ajoute une nouvelle ligne à l'intérieur des limites du tableau, plutôt que d'écrire manuellement après la dernière cellule utilisée ;
  • txtCompanyName.Value, cboCity.Value et les autres lisent ce que l'utilisateur a actuellement saisi ou sélectionné dans ce contrôle spécifique — .Value est commun à presque tous les types de contrôles, c'est pourquoi le même schéma fonctionne aussi bien pour les TextBox que pour les ComboBox ;
  • La ligne générant l'ID client est un exemple simplifié pour cet exercice — une génération d'ID réelle devrait vérifier les écarts ou les ID réutilisés, ce que cette ligne ne fait pas ;
  • Unload Me à la fin ferme le formulaire uniquement après que la ligne a été écrite — le fermer plus tôt rendrait txtCompanyName.Value et les autres valeurs de contrôle inaccessibles, car les contrôles n'existent plus une fois le formulaire déchargé.
Note
Remarque

L'étiquette « Nom de l'entreprise » du formulaire est simplement une légende plus conviviale pour la colonne Customer de la table — le code écrit la valeur de txtCompanyName.Value dans cette colonne, quel que soit le texte de l'étiquette, car seul le nom du TextBox compte pour VBA, et non sa légende à l'écran.

Note
Remarque

Customer ID n'apparaît pas sur le formulaire car il est généré automatiquement par le code ("C0" & (tbl.ListRows.Count + 100)) plutôt que saisi par l'utilisateur — cela reflète la manière dont les systèmes réels attribuent automatiquement un numéro aux nouveaux enregistrements au lieu de compter sur une personne pour choisir un identifiant unique.

Tâche

  1. Insérer un nouveau UserForm, le nommer frmAddCustomer, et ajouter trois TextBox (txtCompanyName, txtContact, txtEmail) et deux ComboBox (cboCity, cboStatus), chacun avec une étiquette correspondante.
  2. Ajouter deux CommandButtons, cmdSave et cmdCancel, puis écrire les procédures UserForm_Initialize et cmdCancel_Click exactement comme indiqué.
  3. Écrire cmdSave_Click comme montré, puis ajouter un bouton temporaire ailleurs dans le classeur avec le code frmAddCustomer.Show pour tester l'ouverture du formulaire.
  4. Remplir le formulaire pour un sixième client fictif et cliquer sur Enregistrer — vérifier qu'une nouvelle ligne apparaît dans tblCustomers avec les valeurs saisies.
Astuce
expand arrow

1. Création du formulaire

  • Insertion → UserForm dans le VBE, puis renommez-le via le champ (Name) de la fenêtre Propriétés en frmAddCustomer — et non via le champ Caption, qui ne modifie que le texte de la barre de titre.
  • Faites glisser une paire Label + TextBox pour chacun des champs Nom de l'entreprise, Contact et Email ; une paire Label + ComboBox pour Ville et Statut.
  • Renommez chaque contrôle immédiatement après l'avoir ajouté — c'est l'habitude soulignée dans ce chapitre. Les Labels n'ont pas besoin de noms adaptés au code car ils ne sont jamais référencés dans le code, mais chaque TextBox/ComboBox/Bouton en a besoin.

2. UserForm_Initialize et cmdCancel_Click

  • Double-cliquez sur l'arrière-plan vierge du formulaire (pas sur un contrôle) pour accéder à UserForm_Initialize — double-cliquer sur cmdCancel vous amène directement à cmdCancel_Click.
  • Les deux procédures vous ont été fournies exactement dans le chapitre — saisissez-les sans modification.

3. Test avec un bouton temporaire

  • Ce bouton n'a pas besoin d'être sur le formulaire — placez-le sur n'importe quelle feuille via Développeur → Insérer → Bouton (Contrôle de formulaire), ou lancez simplement une Sub d'une ligne depuis le VBE au lieu d'ajouter un bouton sur la feuille.
  • frmAddCustomer.Show est le seul code nécessaire pour afficher le formulaire.

4. Test d'un enregistrement complet

  • Remplissez tous les champs et sélectionnez des valeurs dans les deux listes déroulantes avant de cliquer sur Enregistrer — une sélection vide dans une ComboBox écrirait une cellule vide.
  • Vérifiez ensuite tblCustomers pour une nouvelle ligne avec un identifiant de type C00x.
Solution
expand arrow
Private Sub UserForm_Initialize()
    ' runs once, automatically, when the form is first shown
    cboCity.AddItem "Chicago"
    cboCity.AddItem "Boston"
    cboCity.AddItem "Austin"
    cboCity.AddItem "Seattle"
    cboCity.AddItem "Denver"

    cboStatus.AddItem "Active"
    cboStatus.AddItem "Inactive"
    cboStatus.AddItem "Prospect"
End Sub

Private Sub cmdCancel_Click()
    Unload Me
End Sub

Private Sub cmdSave_Click()
    Dim tbl As ListObject
    Dim newRow As ListRow

    Set tbl = ThisWorkbook.Worksheets("Customers").ListObjects("tblCustomers")
    Set newRow = tbl.ListRows.Add

    newRow.Range(1, 1).Value = "C0" & (tbl.ListRows.Count + 100)
    newRow.Range(1, 2).Value = txtCompanyName.Value
    newRow.Range(1, 3).Value = txtContact.Value
    newRow.Range(1, 4).Value = txtEmail.Value
    newRow.Range(1, 5).Value = cboCity.Value
    newRow.Range(1, 6).Value = cboStatus.Value

    MsgBox txtCompanyName.Value & " was added successfully."
    Unload Me
End Sub

Pour le tester, exécutez ceci depuis n'importe quel module standard (pas dans le code du UserForm) :

Sub ShowAddCustomerForm()
    frmAddCustomer.Show
End Sub

Appuyez sur F5 avec le curseur à l'intérieur de ShowAddCustomerForm — le formulaire devrait s'ouvrir, et le remplir puis cliquer sur Enregistrer devrait ajouter une nouvelle ligne à tblCustomers.

Test du formulaire
Tout était clair ?

Comment pouvons-nous l'améliorer ?

Merci pour vos commentaires !

Section 5. Chapitre 2

Demandez à l'IA

expand

Demandez à l'IA

ChatGPT

Posez n'importe quelle question ou essayez l'une des questions suggérées pour commencer notre discussion

Introduction aux UserForms

Note
Remarque

Les UserForms disposent de fonctionnalités limitées ou absentes dans Excel pour Mac — l’IDE VBA sur Mac ne prend pas entièrement en charge la conception de UserForms dans de nombreuses versions, ce qui peut entraîner ce type de comportement inexpliqué.

MsgBox et InputBox conviennent pour des questions simples oui/non et des réponses sur une seule ligne, mais l’ajout d’un client nécessite souvent plusieurs champs à la fois — un nom d’entreprise, un contact, une ville, un statut. C’est à cela que sert un UserForm : une petite fenêtre personnalisée avec ses propres étiquettes, zones de texte, listes déroulantes et boutons, créée dans le VBE et entièrement contrôlée par votre code.

Création d’un formulaire

Dans le VBE, faites un clic droit sur votre projet dans l’Explorateur de projet et choisissez Insertion → UserForm. Une surface de conception vierge apparaît, accompagnée d’une boîte à outils flottante contenant des contrôles que vous pouvez y faire glisser.

Figure 5.3

Étiquettes, zones de texte, listes déroulantes et boutons

Chaque contrôle que vous faites glisser sur le formulaire reçoit un nom par défaut comme TextBox1 ou CommandButton1 — fonctionnel, mais dénué de sens dès qu’un formulaire comporte six ou sept contrôles. L’habitude la plus importante dans cette section est visible dans la fenêtre Propriétés : renommer chaque contrôle immédiatement après l’avoir ajouté, en utilisant un préfixe court qui identifie son type (txt pour TextBox, cbo pour ComboBox, cmd pour CommandButton, opt pour OptionButton, chk pour CheckBox, lst pour ListBox) suivi d’un nom descriptif. txtCompanyName reste clair dans le code même trois semaines plus tard ; TextBox1 ne l’est pas.

Les étiquettes sont de simples légendes textuelles non interactives (« Nom de l’entreprise ») — l’utilisateur peut les voir mais ne peut jamais y saisir de texte ni cliquer dessus. Les zones de texte servent à saisir du texte libre. Les listes déroulantes présentent une liste de choix, ce qui correspond exactement à l’utilisation de cboCity et cboStatus — restreindre Ville et Statut à une liste connue plutôt que de laisser un utilisateur saisir librement « chicago », « Chicago,IL » et « CHI » pour la même chose dans différents enregistrements.

Flux de création de formulaire

Écriture du code derrière le formulaire

Double-cliquer sur n'importe quel contrôle dans la zone de conception permet d'accéder directement à son code — VBA crée automatiquement une procédure d'événement nommée ControlName_EventName, et le code saisi à l'intérieur s'exécutera chaque fois que cet événement spécifique se produit sur ce contrôle. L'événement par défaut d'un bouton est Click :

Private Sub UserForm_Initialize()
    ' runs once, automatically, when the form is first shown
    cboCity.AddItem "Chicago"
    cboCity.AddItem "Boston"
    cboCity.AddItem "Austin"
    cboCity.AddItem "Seattle"
    cboCity.AddItem "Denver"
 
    cboStatus.AddItem "Active"
    cboStatus.AddItem "Inactive"
    cboStatus.AddItem "Prospect"
End Sub
 
Private Sub cmdCancel_Click()
    Unload Me
End Sub

UserForm_Initialize est une procédure d'événement spéciale qui se déclenche automatiquement au chargement du formulaire — avant que l'utilisateur ne voie quoi que ce soit — ce qui en fait l'endroit idéal pour remplir les ComboBox avec .AddItem plutôt que de saisir les choix manuellement dans la fenêtre Propriétés, surtout si ces choix peuvent évoluer ou provenir d'une feuille de calcul. Unload Me dans cmdCancel_Click ferme entièrement le formulaire ; Me fait toujours référence au formulaire dans lequel le code s'exécute actuellement, donc cette ligne fonctionne sans modification, quel que soit le nom que vous donnez ensuite au formulaire.

Exemple pratique : Enregistrement d'un nouveau client

Voici la procédure associée au bouton Enregistrer — celle qui écrit réellement une nouvelle ligne dans tblCustomers :

Private Sub cmdSave_Click()
    Dim tbl As ListObject
    Dim newRow As ListRow
 
    Set tbl = ThisWorkbook.Worksheets("Customers").ListObjects("tblCustomers")
    Set newRow = tbl.ListRows.Add
 
    newRow.Range(1, 1).Value = "C" & Format(tbl.ListRows.Count + 1, "000")
    newRow.Range(1, 2).Value = txtCompanyName.Value
    newRow.Range(1, 3).Value = txtContact.Value
    newRow.Range(1, 4).Value = txtEmail.Value
    newRow.Range(1, 5).Value = cboCity.Value
    newRow.Range(1, 6).Value = cboStatus.Value
 
    MsgBox txtCompanyName.Value & " was added successfully."
    Unload Me
End Sub
Analyse ligne par ligne
expand arrow
  • L'instruction tbl = ThisWorkbook.Worksheets("Customers").ListObjects("tblCustomers") permet d'accéder depuis le formulaire jusqu'au classeur — un UserForm n'est qu'un autre morceau de code, donc tout ce qui concerne les ListObjects s'applique sans changement ;
  • tbl.ListRows.Add ajoute une nouvelle ligne à l'intérieur des limites du tableau, plutôt que d'écrire manuellement après la dernière cellule utilisée ;
  • txtCompanyName.Value, cboCity.Value et les autres lisent ce que l'utilisateur a actuellement saisi ou sélectionné dans ce contrôle spécifique — .Value est commun à presque tous les types de contrôles, c'est pourquoi le même schéma fonctionne aussi bien pour les TextBox que pour les ComboBox ;
  • La ligne générant l'ID client est un exemple simplifié pour cet exercice — une génération d'ID réelle devrait vérifier les écarts ou les ID réutilisés, ce que cette ligne ne fait pas ;
  • Unload Me à la fin ferme le formulaire uniquement après que la ligne a été écrite — le fermer plus tôt rendrait txtCompanyName.Value et les autres valeurs de contrôle inaccessibles, car les contrôles n'existent plus une fois le formulaire déchargé.
Note
Remarque

L'étiquette « Nom de l'entreprise » du formulaire est simplement une légende plus conviviale pour la colonne Customer de la table — le code écrit la valeur de txtCompanyName.Value dans cette colonne, quel que soit le texte de l'étiquette, car seul le nom du TextBox compte pour VBA, et non sa légende à l'écran.

Note
Remarque

Customer ID n'apparaît pas sur le formulaire car il est généré automatiquement par le code ("C0" & (tbl.ListRows.Count + 100)) plutôt que saisi par l'utilisateur — cela reflète la manière dont les systèmes réels attribuent automatiquement un numéro aux nouveaux enregistrements au lieu de compter sur une personne pour choisir un identifiant unique.

Tâche

  1. Insérer un nouveau UserForm, le nommer frmAddCustomer, et ajouter trois TextBox (txtCompanyName, txtContact, txtEmail) et deux ComboBox (cboCity, cboStatus), chacun avec une étiquette correspondante.
  2. Ajouter deux CommandButtons, cmdSave et cmdCancel, puis écrire les procédures UserForm_Initialize et cmdCancel_Click exactement comme indiqué.
  3. Écrire cmdSave_Click comme montré, puis ajouter un bouton temporaire ailleurs dans le classeur avec le code frmAddCustomer.Show pour tester l'ouverture du formulaire.
  4. Remplir le formulaire pour un sixième client fictif et cliquer sur Enregistrer — vérifier qu'une nouvelle ligne apparaît dans tblCustomers avec les valeurs saisies.
Astuce
expand arrow

1. Création du formulaire

  • Insertion → UserForm dans le VBE, puis renommez-le via le champ (Name) de la fenêtre Propriétés en frmAddCustomer — et non via le champ Caption, qui ne modifie que le texte de la barre de titre.
  • Faites glisser une paire Label + TextBox pour chacun des champs Nom de l'entreprise, Contact et Email ; une paire Label + ComboBox pour Ville et Statut.
  • Renommez chaque contrôle immédiatement après l'avoir ajouté — c'est l'habitude soulignée dans ce chapitre. Les Labels n'ont pas besoin de noms adaptés au code car ils ne sont jamais référencés dans le code, mais chaque TextBox/ComboBox/Bouton en a besoin.

2. UserForm_Initialize et cmdCancel_Click

  • Double-cliquez sur l'arrière-plan vierge du formulaire (pas sur un contrôle) pour accéder à UserForm_Initialize — double-cliquer sur cmdCancel vous amène directement à cmdCancel_Click.
  • Les deux procédures vous ont été fournies exactement dans le chapitre — saisissez-les sans modification.

3. Test avec un bouton temporaire

  • Ce bouton n'a pas besoin d'être sur le formulaire — placez-le sur n'importe quelle feuille via Développeur → Insérer → Bouton (Contrôle de formulaire), ou lancez simplement une Sub d'une ligne depuis le VBE au lieu d'ajouter un bouton sur la feuille.
  • frmAddCustomer.Show est le seul code nécessaire pour afficher le formulaire.

4. Test d'un enregistrement complet

  • Remplissez tous les champs et sélectionnez des valeurs dans les deux listes déroulantes avant de cliquer sur Enregistrer — une sélection vide dans une ComboBox écrirait une cellule vide.
  • Vérifiez ensuite tblCustomers pour une nouvelle ligne avec un identifiant de type C00x.
Solution
expand arrow
Private Sub UserForm_Initialize()
    ' runs once, automatically, when the form is first shown
    cboCity.AddItem "Chicago"
    cboCity.AddItem "Boston"
    cboCity.AddItem "Austin"
    cboCity.AddItem "Seattle"
    cboCity.AddItem "Denver"

    cboStatus.AddItem "Active"
    cboStatus.AddItem "Inactive"
    cboStatus.AddItem "Prospect"
End Sub

Private Sub cmdCancel_Click()
    Unload Me
End Sub

Private Sub cmdSave_Click()
    Dim tbl As ListObject
    Dim newRow As ListRow

    Set tbl = ThisWorkbook.Worksheets("Customers").ListObjects("tblCustomers")
    Set newRow = tbl.ListRows.Add

    newRow.Range(1, 1).Value = "C0" & (tbl.ListRows.Count + 100)
    newRow.Range(1, 2).Value = txtCompanyName.Value
    newRow.Range(1, 3).Value = txtContact.Value
    newRow.Range(1, 4).Value = txtEmail.Value
    newRow.Range(1, 5).Value = cboCity.Value
    newRow.Range(1, 6).Value = cboStatus.Value

    MsgBox txtCompanyName.Value & " was added successfully."
    Unload Me
End Sub

Pour le tester, exécutez ceci depuis n'importe quel module standard (pas dans le code du UserForm) :

Sub ShowAddCustomerForm()
    frmAddCustomer.Show
End Sub

Appuyez sur F5 avec le curseur à l'intérieur de ShowAddCustomerForm — le formulaire devrait s'ouvrir, et le remplir puis cliquer sur Enregistrer devrait ajouter une nouvelle ligne à tblCustomers.

Test du formulaire
Tout était clair ?

Comment pouvons-nous l'améliorer ?

Merci pour vos commentaires !

Section 5. Chapitre 2
some-alt