Cours sur les éléments d'interface visuelle en
VBA
Table des matières
1. Introduction aux interfaces visuelles en VBA
2. UserForms - Création et manipulation
3. Contrôles communs et leurs propriétés
4. Gestion des événements
5. Techniques avancées d'interface
6. Exemples pratiques
Introduction aux interfaces visuelles en VBA
Qu'est-ce qu'une interface utilisateur en VBA?
Une interface utilisateur en VBA permet d'interagir avec l'utilisateur au-delà des fonctions natives d'Excel ou
des autres applications Office. Cela inclut des formulaires personnalisés, des boîtes de dialogue et des
contrôles interactifs.
Types d'interfaces en VBA
1. Boîtes de dialogue intégrées : MsgBox, InputBox
2. UserForms : Formulaires personnalisés
3. Contrôles ActiveX : Sur les feuilles Excel
4. Contrôles de formulaire : Sur les feuilles Excel (plus limités)
Avantages d'une interface visuelle
Facilite l'interaction avec l'utilisateur
Permet une saisie contrôlée des données
Améliore l'expérience utilisateur
Protège les données sous-jacentes
Simplifie les processus complexes
UserForms - Création et manipulation
Création d'un UserForm
1. Dans l'éditeur VBA (Alt+F11)
2. Cliquez-droit sur le projet > Insérer > UserForm
3. Un nouveau UserForm vide apparaît avec:
L'éditeur visuel
La fenêtre Propriétés
La boîte à outils
Propriétés principales du UserForm
vb
' Nom du formulaire (pour les références en code)
UserForm1.Name = "frmSaisie"
' Titre dans la barre de titre
UserForm1.Caption = "Formulaire de saisie"
' Dimensions
UserForm1.Width = 400
UserForm1.Height = 300
' Position à l'ouverture
UserForm1.StartUpPosition = 0 '0=Manuel, 1=CenterOwner, 2=CenterScreen, 3=WindowsDefault
UserForm1.Left = 100
UserForm1.Top = 100
' Apparence
UserForm1.BackColor = RGB(240, 240, 240)
UserForm1.ForeColor = RGB(0, 0, 0)
UserForm1.Font.Name = "Arial"
UserForm1.Font.Size = 10
' Comportement
UserForm1.ShowModal = True ' True=Modal, False=Modeless
Afficher et fermer un UserForm
vb
' Afficher le formulaire
Sub AfficherFormulaire()
frmSaisie.Show
End Sub
' Fermer le formulaire (dans un événement du formulaire)
Private Sub btnFermer_Click()
Unload Me
End Sub
' Alternative: masquer sans décharger
Private Sub btnMasquer_Click()
Me.Hide
End Sub
Cycle de vie d'un UserForm
vb
' Initialisation - se produit avant l'affichage
Private Sub UserForm_Initialize()
' Code d'initialisation
txtNom.Value = ""
cboOptions.AddItem "Option 1"
cboOptions.AddItem "Option 2"
End Sub
' Activation - se produit quand le formulaire devient actif
Private Sub UserForm_Activate()
' Focus sur le premier champ
txtNom.SetFocus
End Sub
' Fermeture - se produit quand le formulaire est déchargé
Private Sub UserForm_Terminate()
' Nettoyage
End Sub
Contrôles communs et leurs propriétés
Label (Étiquette)
vb
' Création en code
Dim lbl As MSForms.Label
Set lbl = Me.Controls.Add("Forms.Label.1", "lblNom")
' Propriétés essentielles
lbl.Caption = "Nom :" ' Texte affiché
lbl.Font.Bold = True ' Mise en forme
lbl.ForeColor = RGB(0,0,128) ' Couleur du texte
lbl.BackColor = RGB(240,240,240) ' Couleur de fond
lbl.TextAlign = fmTextAlignRight ' Alignement: 1=Gauche, 2=Centre, 3=Droite
lbl.WordWrap = True ' Retour à la ligne automatique
TextBox (Zone de texte)
vb
' Propriétés essentielles
txtNom.Value = "Valeur initiale" ' Valeur/contenu
txtNom.Text = "Valeur initiale" ' Alternative
txtNom.MultiLine = True ' Multi-lignes
txtNom.WordWrap = True ' Retour à la ligne
txtNom.PasswordChar = "*" ' Pour mot de passe
txtNom.MaxLength = 50 ' Limite de caractères
txtNom.Enabled = True ' Actif/inactif
txtNom.Locked = False ' Verrouillé en lecture seule
txtNom.EnterKeyBehavior = True ' True=Retour à la ligne, False=Tab
txtNom.TabIndex = 0 ' Ordre de tabulation
txtNom.SelStart = 0 ' Position du curseur
txtNom.SelLength = 5 ' Longueur de sélection
' Méthodes utiles
txtNom.SetFocus ' Donner le focus
txtNom.SelText = "Nouveau texte" ' Remplacer la sélection
CommandButton (Bouton)
vb
' Propriétés essentielles
btnValider.Caption = "Valider" ' Texte affiché
btnValider.Default = True ' Bouton par défaut (Entrée)
btnValider.Cancel = False ' Bouton d'annulation (Échap)
btnValider.Picture = LoadPicture("C:\chemin\image.jpg") ' Image
btnValider.TakeFocusOnClick = True ' Garder le focus après clic
btnValider.Accelerator = "V" ' Touche d'accès rapide (Alt+V)
CheckBox (Case à cocher)
vb
' Propriétés essentielles
chkOption.Caption = "Activer l'option"
chkOption.Value = True ' True=Coché, False=Décoché, Null=Indéterminé
chkOption.TripleState = True ' Permet l'état indéterminé (grisé)
OptionButton (Bouton d'option)
vb
' Propriétés essentielles
optChoix1.Caption = "Option 1"
optChoix1.GroupName = "Groupe1" ' Regroupement (un seul sélectionnable par groupe)
optChoix1.Value = True ' True=Sélectionné
ComboBox (Liste déroulante)
vb
' Propriétés essentielles
cboListe.Style = fmStyleDropDownList ' 0=DropDown, 2=DropDownList (non modifiable)
cboListe.Value = "Sélection" ' Valeur sélectionnée/affichée
cboListe.Text = "Sélection" ' Alternative
cboListe.ListIndex = 0 ' Index sélectionné (base 0)
cboListe.ListCount ' Nombre d'éléments
cboListe.List(0) ' Accès à un élément par index
cboListe.MatchEntry = fmMatchEntryFirstLetter ' Recherche pendant la frappe
' Méthodes pour ajouter des éléments
cboListe.AddItem "Option 1" ' Ajouter un élément
cboListe.List = Array("Opt1", "Opt2", "Opt3") ' Définir toute la liste
' Pour les listes à deux colonnes
cboListe.ColumnCount = 2 ' Nombre de colonnes
cboListe.ColumnWidths = "100;50" ' Largeurs en points
cboListe.Column(0) = Array("Code1", "Code2") ' Définir la première colonne
cboListe.Column(1) = Array("Libellé1", "Libellé2") ' Définir la deuxième colonne
cboListe.TextColumn = 2 ' Colonne affichée (base 1)
' Effacer la liste
cboListe.Clear
ListBox (Liste de sélection)
vb
' Propriétés essentielles (similaires à ComboBox avec quelques ajouts)
lstElements.MultiSelect = fmMultiSelectMulti ' 0=Single, 1=Multi, 2=Extended
lstElements.Selected(0) = True ' Sélectionner un élément par index
lstElements.ListStyle = fmListStyleOption ' Style visuel
' Pour sélection multiple, vérification
Dim i As Integer
For i = 0 To lstElements.ListCount - 1
If lstElements.Selected(i) Then
Debug.Print lstElements.List(i)
End If
Next i
Frame (Cadre)
vb
' Propriétés essentielles
frmGroupe.Caption = "Options" ' Titre du cadre
frmGroupe.BorderStyle = fmBorderStyleSingle ' Style de bordure
Image (Contrôle d'image)
vb
' Propriétés essentielles
imgLogo.Picture = LoadPicture("C:\chemin\logo.jpg")
imgLogo.PictureSizeMode = fmPictureSizeModeStretch ' Redimensionnement
' 0=Clip, 1=Stretch, 3=Zoom
MultiPage (Pages multiples)
vb
' Propriétés essentielles
mpgOnglets.Value = 0 ' Onglet actif (base 0)
mpgOnglets.Pages.Count ' Nombre d'onglets
mpgOnglets.Pages(0).Caption = "Général" ' Titre d'un onglet
' Ajouter une page en code
Dim nvPage As MSForms.Page
Set nvPage = mpgOnglets.Pages.Add("nvPage")
nvPage.Caption = "Nouvelle page"
ScrollBar (Barre de défilement)
vb
' Propriétés essentielles
scrValeur.Min = 0 ' Valeur minimale
scrValeur.Max = 100 ' Valeur maximale
scrValeur.Value = 50 ' Valeur actuelle
scrValeur.SmallChange = 1 ' Incrément petit
scrValeur.LargeChange = 10 ' Incrément grand
scrValeur.Orientation = fmOrientationVertical ' 0=Horizontal, 1=Vertical
TabStrip (Bande d'onglets)
vb
' Propriétés essentielles
tabOptions.Tabs.Count ' Nombre d'onglets
tabOptions.Value = 0 ' Onglet actif
tabOptions.Tabs(0).Caption = "Onglet 1" ' Texte de l'onglet
' Ajouter un onglet
tabOptions.Tabs.Add "Nouvel onglet", , "Texte onglet"
Gestion des événements
Événements communs des contrôles
TextBox
vb
' Se produit quand le contenu change
Private Sub txtNom_Change()
lblResultat.Caption = "Vous avez saisi : " & txtNom.Value
End Sub
' Se produit quand l'utilisateur appuie sur une touche
Private Sub txtNom_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
If KeyCode = vbKeyF1 Then
MsgBox "Aide: Saisissez votre nom complet"
End If
End Sub
' Se produit quand une touche est relâchée
Private Sub txtNom_KeyUp(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
' Code à exécuter
End Sub
' Se produit quand un caractère est saisi
Private Sub txtNom_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
' Forcer les majuscules
If KeyAscii >= 97 And KeyAscii <= 122 Then
KeyAscii = KeyAscii - 32
End If
' Bloquer les caractères non numériques
If KeyAscii < 48 Or KeyAscii > 57 Then
KeyAscii = 0 ' Annuler la saisie
End If
End Sub
' Se produit quand le contrôle reçoit le focus
Private Sub txtNom_Enter()
txtNom.BackColor = RGB(255, 255, 200) ' Jaune clair
End Sub
' Se produit quand le contrôle perd le focus
Private Sub txtNom_Exit(ByVal Cancel As MSForms.ReturnBoolean)
txtNom.BackColor = RGB(255, 255, 255) ' Blanc
' Validation, si échec on peut empêcher de quitter
If Len(txtNom.Value) < 3 Then
MsgBox "Le nom doit comporter au moins 3 caractères"
Cancel = True ' Empêche de quitter le contrôle
End If
End Sub
ComboBox et ListBox
vb
' Se produit quand la sélection change
Private Sub cboOptions_Change()
lblSelection.Caption = "Sélection: " & cboOptions.Value
End Sub
' Se produit quand un item est cliqué dans une ListBox
Private Sub lstElements_Click()
If lstElements.ListIndex <> -1 Then
txtDetails.Text = "Détails de " & lstElements.Value
End If
End Sub
' Se produit quand un item est double-cliqué dans une ListBox
Private Sub lstElements_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
If lstElements.ListIndex <> -1 Then
MsgBox "Vous avez sélectionné: " & lstElements.Value
End If
End Sub
CommandButton
vb
' Se produit quand on clique sur le bouton
Private Sub btnValider_Click()
' Code de traitement
If ValiderFormulaire() Then
Me.Hide
End If
End Sub
CheckBox et OptionButton
vb
' Se produit quand l'état change
Private Sub chkOption_Click()
If chkOption.Value Then
' La case est cochée
frmOptions.Enabled = True
Else
' La case est décochée
frmOptions.Enabled = False
End If
End Sub
Private Sub optChoix1_Click()
' Ce code s'exécute quand l'option est sélectionnée
lblInfo.Caption = "Vous avez choisi l'option 1"
End Sub
MultiPage et TabStrip
vb
' Se produit quand on change d'onglet
Private Sub mpgOnglets_Change()
lblPage.Caption = "Page " & (mpgOnglets.Value + 1) & " sur " & mpgOnglets.Pages.Count
End Sub
Private Sub tabOptions_Change()
' Afficher le contenu correspondant à l'onglet
Select Case tabOptions.Value
Case 0
frmPage1.Visible = True
frmPage2.Visible = False
Case 1
frmPage1.Visible = False
frmPage2.Visible = True
End Select
End Sub
Événements du UserForm
vb
' Se produit avant l'affichage du formulaire
Private Sub UserForm_Initialize()
' Initialisation des contrôles
RemplirListeOptions()
txtDate.Value = Format(Date, "dd/mm/yyyy")
End Sub
' Se produit quand le formulaire devient actif
Private Sub UserForm_Activate()
' Donner le focus au premier champ
txtNom.SetFocus
End Sub
' Se produit quand l'utilisateur tente de fermer le formulaire (X)
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
If CloseMode = vbFormControlMenu Then
' L'utilisateur a cliqué sur la croix (X)
Dim reponse As VbMsgBoxResult
reponse = MsgBox("Voulez-vous vraiment quitter sans enregistrer ?", vbYesNo)
If reponse = vbNo Then
Cancel = True ' Annule la fermeture
End If
End If
End Sub
' Se produit quand une touche est enfoncée dans le formulaire
Private Sub UserForm_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
' Ctrl+S pour sauvegarder
If Shift = 2 And KeyCode = vbKeyS Then
btnSauvegarder_Click
End If
End Sub
' Se produit quand le formulaire est redimensionné
Private Sub UserForm_Layout()
' Ajuster la position des contrôles
AjusterPositionControles
End Sub
' Se produit quand le formulaire est déchargé
Private Sub UserForm_Terminate()
' Nettoyage
End Sub
Techniques avancées d'interface
Créer des contrôles dynamiquement
vb
Sub CreerControlesDynamiques()
Dim i As Integer
Dim chk As MSForms.CheckBox
' Supprimer d'abord les contrôles existants
For i = Me.Controls.Count - 1 To 0 Step -1
If TypeOf Me.Controls(i) Is MSForms.CheckBox Then
If Left(Me.Controls(i).Name, 12) = "chkDynamique" Then
Me.Controls.Remove Me.Controls(i).Name
End If
End If
Next i
' Créer de nouveaux contrôles
For i = 1 To 5
Set chk = Me.Controls.Add("Forms.CheckBox.1", "chkDynamique" & i)
With chk
.Caption = "Option " & i
.Left = 20
.Top = 50 + (i - 1) * 20
.Width = 100
.Height = 18
.Visible = True
End With
Next i
End Sub
Validation de formulaire complète
vb
Function ValiderFormulaire() As Boolean
Dim erreurs As String
erreurs = ""
' Vérification des champs
If Trim(txtNom.Value) = "" Then
erreurs = erreurs & "- Le nom est obligatoire" & vbCrLf
End If
If Not IsDate(txtDate.Value) Then
erreurs = erreurs & "- La date n'est pas valide" & vbCrLf
End If
If cboOptions.ListIndex = -1 Then
erreurs = erreurs & "- Veuillez sélectionner une option" & vbCrLf
End If
' Afficher les erreurs ou valider
If erreurs <> "" Then
MsgBox "Veuillez corriger les erreurs suivantes :" & vbCrLf & vbCrLf & erreurs,
vbExclamation
ValiderFormulaire = False
Else
ValiderFormulaire = True
End If
End Function
Navigation par tabulation
vb
' Définir l'ordre de tabulation
Sub DefinirOrdreTabulation()
txtNom.TabIndex = 0
txtPrenom.TabIndex = 1
cboOptions.TabIndex = 2
chkOption.TabIndex = 3
btnValider.TabIndex = 4
btnAnnuler.TabIndex = 5
End Sub
Mémoriser la position et taille du formulaire
vb
' Dans Initialize
Private Sub UserForm_Initialize()
' Récupérer la position enregistrée
Dim posLeft As Variant, posTop As Variant
posLeft = GetSetting("MonApplication", "Position", "FormLeft", "")
posTop = GetSetting("MonApplication", "Position", "FormTop", "")
If posLeft <> "" And posTop <> "" Then
Me.Left = posLeft
Me.Top = posTop
Else
' Position par défaut
Me.StartUpPosition = 1 ' CenterOwner
End If
End Sub
' Dans Terminate ou avant Unload
Private Sub SauvegarderPosition()
' Enregistrer la position actuelle
SaveSetting "MonApplication", "Position", "FormLeft", Me.Left
SaveSetting "MonApplication", "Position", "FormTop", Me.Top
End Sub
Formulaires redimensionnables
vb
' Variables au niveau du module
Private OriginalFormWidth As Double
Private OriginalFormHeight As Double
Private ControlsInfo As Collection
' Initialisation
Private Sub UserForm_Initialize()
' Mémoriser les dimensions initiales
OriginalFormWidth = Me.Width
OriginalFormHeight = Me.Height
' Mémoriser les positions et tailles des contrôles
Set ControlsInfo = New Collection
Dim ctrl As MSForms.Control
Dim ctrlInfo As New Dictionary
For Each ctrl In Me.Controls
Set ctrlInfo = New Dictionary
ctrlInfo.Add "Name", ctrl.Name
ctrlInfo.Add "Left", ctrl.Left
ctrlInfo.Add "Top", ctrl.Top
ctrlInfo.Add "Width", ctrl.Width
ctrlInfo.Add "Height", ctrl.Height
ControlsInfo.Add ctrlInfo
Next ctrl
End Sub
' Redimensionnement
Private Sub UserForm_Layout()
If OriginalFormWidth = 0 Then Exit Sub ' Éviter erreur
' Calculer ratio de redimensionnement
Dim ratioW As Double, ratioH As Double
ratioW = Me.Width / OriginalFormWidth
ratioH = Me.Height / OriginalFormHeight
' Redimensionner les contrôles
Dim i As Integer
Dim ctrl As MSForms.Control
Dim ctrlInfo As Dictionary
For i = 1 To ControlsInfo.Count
Set ctrlInfo = ControlsInfo(i)
Set ctrl = Me.Controls(ctrlInfo("Name"))
' Appliquer les nouvelles dimensions
ctrl.Left = ctrlInfo("Left") * ratioW
ctrl.Top = ctrlInfo("Top") * ratioH
ctrl.Width = ctrlInfo("Width") * ratioW
ctrl.Height = ctrlInfo("Height") * ratioH
Next i
End Sub
Drag and Drop (glisser-déposer)
vb
' Activer le drag & drop sur un contrôle
Private Sub ListBox1_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As
Single, ByVal Y As Single)
If Button = 1 Then ' Bouton gauche
ListBox1.Drag vbBeginDrag
End If
End Sub
' Gérer le drop dans un autre contrôle
Private Sub ListBox2_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As
Single, ByVal Y As Single)
If Me.ActiveControl Is Nothing Then Exit Sub
' Si on est en train de glisser depuis ListBox1
If TypeOf Me.ActiveControl Is MSForms.ListBox Then
If Me.ActiveControl.Name = "ListBox1" Then
ListBox2.Drag vbEnterDrag
End If
End If
End Sub
Private Sub ListBox2_DragDrop(ByVal Source As Object, ByVal X As Single, ByVal Y As Single)
If TypeOf Source Is MSForms.ListBox Then
If Source.Name = "ListBox1" And Source.ListIndex <> -1 Then
' Ajouter l'élément à ListBox2
ListBox2.AddItem Source.Value
' Supprimer de ListBox1
Source.RemoveItem Source.ListIndex
End If
End If
End Sub
Exemples pratiques
Exemple 1: Formulaire de recherche client
vb
' Dans le module de code du UserForm
Option Explicit
' Variables au niveau du module
Private clients As Variant ' Tableau de données
Private Sub UserForm_Initialize()
' Initialiser le formulaire
txtRecherche.Value = ""
lstResultats.Clear
' Charger les données des clients
ChargerClients
' Configurer les colonnes
lstResultats.ColumnCount = 3
lstResultats.ColumnWidths = "50;150;100"
' En-têtes
lstResultats.AddItem ""
lstResultats.List(0, 0) = "ID"
lstResultats.List(0, 1) = "Nom"
lstResultats.List(0, 2) = "Téléphone"
' Remplir la liste complète initialement
RemplirListe ""
End Sub
Private Sub ChargerClients()
' Simuler une source de données
' Dans un cas réel, vous récupèreriez cela d'une feuille Excel ou d'une base
clients = Array( _
Array(1, "Dupont Jean", "0123456789"), _
Array(2, "Martin Sophie", "0234567890"), _
Array(3, "Bernard Paul", "0345678901"), _
Array(4, "Petit Marie", "0456789012"), _
Array(5, "Robert Thomas", "0567890123"), _
Array(6, "Richard Julie", "0678901234"), _
Array(7, "Durand Michel", "0789012345"), _
Array(8, "Dubois Françoise", "0890123456"), _
Array(9, "Moreau Philippe", "0901234567"), _
Array(10, "Laurent Isabelle", "0112233445"))
End Sub
Private Sub txtRecherche_Change()
' Recherche dynamique
RemplirListe txtRecherche.Value
End Sub
Private Sub RemplirListe(critere As String)
' Vider la liste sauf l'en-tête
For i = lstResultats.ListCount - 1 To 1 Step -1
lstResultats.RemoveItem i
Next i
' Remplir avec les clients correspondant au critère
Dim i As Integer
Dim critereMin As String
critereMin = LCase(critere)
For i = LBound(clients) To UBound(clients)
If critereMin = "" Or InStr(1, LCase(clients(i)(1)), critereMin) > 0 Then
lstResultats.AddItem ""
lstResultats.List(lstResultats.ListCount - 1, 0) = clients(i)(0)
lstResultats.List(lstResultats.ListCount - 1, 1) = clients(i)(1)
lstResultats.List(lstResultats.ListCount - 1, 2) = clients(i)(2)
End If
Next i
' Afficher le nombre de résultats
lblResultats.Caption = (lstResultats.ListCount - 1) & " client(s) trouvé(s)"
End Sub
Private Sub lstResultats_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
' Double-clic pour sélectionner un client
If lstResultats.ListIndex > 0 Then ' Ignorer l'en-tête
Dim idClient As Integer
idClient = lstResultats.List(lstResultats.ListIndex, 0)
' Retourner l'ID client à la procédure appelante
RetournerClient idClient
' Fermer le formulaire
Unload Me
End If
End Sub
Private Sub btnRechercher_Click()
' Lancer la recherche
RemplirListe txtRecherche.Value
End Sub
Private Sub btnSelectionner_Click()
' Sélectionner le client en cours
If lstResultats.ListIndex > 0 Then
Dim idClient As Integer
idClient = lstResultats.List(lstResultats.ListIndex, 0)
RetournerClient idClient
Unload Me
Else
MsgBox "Veuillez sélectionner un client", vbExclamation
End If
End Sub
Private Sub btnAnnuler_Click()
' Fermer sans sélection
Unload Me
End Sub
Private Sub RetournerClient(idClient As Integer)
' Cette fonction simule le retour de l'ID client
' Dans un cas réel, vous pourriez utiliser une variable globale
' ou écrire directement dans une cellule
MsgBox "Client sélectionné : ID " & idClient, vbInformation
End Sub
Exemple 2: Formulaire de saisie avec onglets (suite)
vb
Private Sub cboCategorie_Change()
' Ajuster l'interface selon la catégorie
If cboCategorie.Value = "Entreprise" Then
lblRaisonSociale.Visible = True
txtRaisonSociale.Visible = True
lblSiret.Visible = True
txtSiret.Visible = True
lblNom.Caption = "Nom du contact :"
Else
lblRaisonSociale.Visible = False
txtRaisonSociale.Visible = False
lblSiret.Visible = False
txtSiret.Visible = False
lblNom.Caption = "Nom :"
End If
End Sub
Private Sub btnSuivant_Click()
' Validation de l'onglet actuel
Select Case mpgOnglets.Value
Case 0 ' Premier onglet (Informations générales)
If Not ValiderOnglet1() Then Exit Sub
Case 1 ' Deuxième onglet (Adresse)
If Not ValiderOnglet2() Then Exit Sub
End Select
' Passer à l'onglet suivant
If mpgOnglets.Value < mpgOnglets.Pages.Count - 1 Then
mpgOnglets.Value = mpgOnglets.Value + 1
AjusterBoutons
End If
End Sub
Private Sub btnPrecedent_Click()
' Revenir à l'onglet précédent
If mpgOnglets.Value > 0 Then
mpgOnglets.Value = mpgOnglets.Value - 1
AjusterBoutons
End If
End Sub
Private Sub mpgOnglets_Change()
' Mettre à jour l'affichage des boutons
AjusterBoutons
End Sub
Private Sub AjusterBoutons()
' Ajuster les boutons selon l'onglet actif
btnPrecedent.Enabled = (mpgOnglets.Value > 0)
If mpgOnglets.Value = mpgOnglets.Pages.Count - 1 Then
btnSuivant.Visible = False
btnTerminer.Visible = True
Else
btnSuivant.Visible = True
btnTerminer.Visible = False
End If
End Sub
Private Function ValiderOnglet1() As Boolean
' Validation du premier onglet
If Trim(txtNom.Value) = "" Then
MsgBox "Le nom est obligatoire", vbExclamation
txtNom.SetFocus
ValiderOnglet1 = False
Exit Function
End If
If cboCategorie.Value = "Entreprise" Then
If Trim(txtRaisonSociale.Value) = "" Then
MsgBox "La raison sociale est obligatoire pour une entreprise", vbExclamation
txtRaisonSociale.SetFocus
ValiderOnglet1 = False
Exit Function
End If
End If
ValiderOnglet1 = True
End Function
Private Function ValiderOnglet2() As Boolean
' Validation du deuxième onglet
If Trim(txtAdresse.Value) = "" Then
MsgBox "L'adresse est obligatoire", vbExclamation
txtAdresse.SetFocus
ValiderOnglet2 = False
Exit Function
End If
If Trim(txtCodePostal.Value) = "" Then
MsgBox "Le code postal est obligatoire", vbExclamation
txtCodePostal.SetFocus
ValiderOnglet2 = False
Exit Function
End If
If Trim(txtVille.Value) = "" Then
MsgBox "La ville est obligatoire", vbExclamation
txtVille.SetFocus
ValiderOnglet2 = False
Exit Function
End If
ValiderOnglet2 = True
End Function
Private Sub btnTerminer_Click()
' Validation du dernier onglet
If Not ValiderOnglet3() Then Exit Sub
' Enregistrer toutes les données
EnregistrerDonnees
' Marquer comme sauvegardé et fermer
donneesSauvegardees = True
Unload Me
End Sub
Private Function ValiderOnglet3() As Boolean
' Validation du troisième onglet
If optFacturation(0).Value = False And optFacturation(1).Value = False And
optFacturation(2).Value = False Then
MsgBox "Veuillez sélectionner un mode de facturation", vbExclamation
ValiderOnglet3 = False
Exit Function
End If
ValiderOnglet3 = True
End Function
Private Sub EnregistrerDonnees()
' Cette fonction simule l'enregistrement des données
' Dans un cas réel, vous écririez dans des cellules ou une base de données
Dim message As String
message = "Client enregistré :" & vbCrLf & vbCrLf
message = message & "Nom: " & txtNom.Value & vbCrLf
If cboCategorie.Value = "Entreprise" Then
message = message & "Raison sociale: " & txtRaisonSociale.Value & vbCrLf
End If
message = message & "Adresse: " & txtAdresse.Value & vbCrLf
message = message & "Code postal: " & txtCodePostal.Value & vbCrLf
message = message & "Ville: " & txtVille.Value & vbCrLf
message = message & "Pays: " & cboPays.Value & vbCrLf
Dim modeFacturation As String
If optFacturation(0).Value Then
modeFacturation = "Mensuel"
ElseIf optFacturation(1).Value Then
modeFacturation = "Trimestriel"
Else
modeFacturation = "Annuel"
End If
message = message & "Mode de facturation: " & modeFacturation
MsgBox message, vbInformation, "Enregistrement réussi"
End Sub
Private Sub btnAnnuler_Click()
' Demander confirmation si des données ont été saisies
If txtNom.Value <> "" Or txtAdresse.Value <> "" Then
Dim reponse As VbMsgBoxResult
reponse = MsgBox("Êtes-vous sûr de vouloir annuler ?", vbQuestion + vbYesNo)
If reponse = vbNo Then
Exit Sub
End If
End If
Unload Me
End Sub
Exemple 3: Formulaire avec liste déroulante en cascade
vb
' Dans le module de code du UserForm
Option Explicit
' Structure de données pour les listes en cascade
Private Type CategorieType
Nom As String
SousCategories() As String
End Type
Private Categories() As CategorieType
Private Sub UserForm_Initialize()
' Initialiser les données en cascade
InitialiserDonnees
' Remplir la première liste
RemplirCategories
' Vider la deuxième liste
cboSousCategorie.Clear
End Sub
Private Sub InitialiserDonnees()
' Initialiser la structure de données
ReDim Categories(1 To 3)
' Catégorie 1
Categories(1).Nom = "Informatique"
ReDim Categories(1).SousCategories(1 To 4)
Categories(1).SousCategories(1) = "Ordinateurs"
Categories(1).SousCategories(2) = "Imprimantes"
Categories(1).SousCategories(3) = "Périphériques"
Categories(1).SousCategories(4) = "Logiciels"
' Catégorie 2
Categories(2).Nom = "Bureautique"
ReDim Categories(2).SousCategories(1 To 3)
Categories(2).SousCategories(1) = "Papeterie"
Categories(2).SousCategories(2) = "Mobilier"
Categories(2).SousCategories(3) = "Fournitures"
' Catégorie 3
Categories(3).Nom = "Téléphonie"
ReDim Categories(3).SousCategories(1 To 3)
Categories(3).SousCategories(1) = "Smartphones"
Categories(3).SousCategories(2) = "Accessoires"
Categories(3).SousCategories(3) = "Forfaits"
End Sub
Private Sub RemplirCategories()
' Remplir la liste des catégories
cboCategorie.Clear
Dim i As Integer
For i = 1 To UBound(Categories)
cboCategorie.AddItem Categories(i).Nom
Next i
End Sub
Private Sub cboCategorie_Change()
' Quand la catégorie change, mettre à jour les sous-catégories
If cboCategorie.ListIndex = -1 Then
cboSousCategorie.Clear
Exit Sub
End If
Dim categorieIndex As Integer
Dim i As Integer
' Trouver l'index dans notre tableau
For i = 1 To UBound(Categories)
If Categories(i).Nom = cboCategorie.Value Then
categorieIndex = i
Exit For
End If
Next i
' Remplir les sous-catégories
cboSousCategorie.Clear
If categorieIndex > 0 Then
For i = 1 To UBound(Categories(categorieIndex).SousCategories)
cboSousCategorie.AddItem Categories(categorieIndex).SousCategories(i)
Next i
End If
' Sélectionner la première sous-catégorie
If cboSousCategorie.ListCount > 0 Then
cboSousCategorie.ListIndex = 0
End If
End Sub
Private Sub btnValider_Click()
' Vérifier si une sélection est faite
If cboCategorie.ListIndex = -1 Then
MsgBox "Veuillez sélectionner une catégorie", vbExclamation
Exit Sub
End If
If cboSousCategorie.ListIndex = -1 Then
MsgBox "Veuillez sélectionner une sous-catégorie", vbExclamation
Exit Sub
End If
' Afficher la sélection
MsgBox "Vous avez sélectionné :" & vbCrLf & _
"Catégorie : " & cboCategorie.Value & vbCrLf & _
"Sous-catégorie : " & cboSousCategorie.Value, _
vbInformation, "Sélection"
Unload Me
End Sub
Private Sub btnAnnuler_Click()
Unload Me
End Sub
Exemple 4: Formulaire avec DataGridView (simulation)
vb
' Dans le module de code du UserForm
Option Explicit
' Structure pour nos données
Private Type ProduitType
ID As Integer
Nom As String
Prix As Double
Stock As Integer
End Type
Private produits() As ProduitType
Private selectedRow As Integer
Private Sub UserForm_Initialize()
' Initialiser les données
ChargerDonnees
' Configurer la ListBox comme une grille
ConfigurerGrille
' Remplir la grille
RemplirGrille
' Désactiver les boutons d'édition
ActiverBoutonsEdition False
' Focus sur la recherche
txtRecherche.SetFocus
End Sub
Private Sub ChargerDonnees()
' Simuler le chargement de données
ReDim produits(1 To 10)
produits(1).ID = 1
produits(1).Nom = "Ordinateur portable"
produits(1).Prix = 899.99
produits(1).Stock = 15
produits(2).ID = 2
produits(2).Nom = "Écran 24 pouces"
produits(2).Prix = 199.5
produits(2).Stock = 8
produits(3).ID = 3
produits(3).Nom = "Clavier sans fil"
produits(3).Prix = 45
produits(3).Stock = 22
produits(4).ID = 4
produits(4).Nom = "Souris ergonomique"
produits(4).Prix = 29.99
produits(4).Stock = 12
produits(5).ID = 5
produits(5).Nom = "Disque dur externe 1TO"
produits(5).Prix = 79.9
produits(5).Stock = 7
produits(6).ID = 6
produits(6).Nom = "Imprimante laser"
produits(6).Prix = 249
produits(6).Stock = 5
produits(7).ID = 7
produits(7).Nom = "Cartouche d'encre noire"
produits(7).Prix = 19.9
produits(7).Stock = 32
produits(8).ID = 8
produits(8).Nom = "Pack papier A4"
produits(8).Prix = 4.5
produits(8).Stock = 50
produits(9).ID = 9
produits(9).Nom = "Webcam HD"
produits(9).Prix = 59.99
produits(9).Stock = 11
produits(10).ID = 10
produits(10).Nom = "Casque audio Bluetooth"
produits(10).Prix = 89
produits(10).Stock = 9
End Sub
Private Sub ConfigurerGrille()
' Configurer la ListBox comme une grille
With lstGrille
.ColumnCount = 4
.ColumnWidths = "40;200;70;50"
' Ajouter les en-têtes
.AddItem ""
.List(0, 0) = "ID"
.List(0, 1) = "Produit"
.List(0, 2) = "Prix"
.List(0, 3) = "Stock"
End With
End Sub
Private Sub RemplirGrille()
' Vider la grille sauf l'en-tête
For i = lstGrille.ListCount - 1 To 1 Step -1
lstGrille.RemoveItem i
Next i
' Remplir avec les produits
Dim filtre As String
filtre = LCase(txtRecherche.Value)
Dim i As Integer
For i = 1 To UBound(produits)
' Appliquer le filtre si nécessaire
If filtre = "" Or InStr(1, LCase(produits(i).Nom), filtre) > 0 Then
lstGrille.AddItem ""
lstGrille.List(lstGrille.ListCount - 1, 0) = produits(i).ID
lstGrille.List(lstGrille.ListCount - 1, 1) = produits(i).Nom
lstGrille.List(lstGrille.ListCount - 1, 2) = Format(produits(i).Prix, "#,##0.00
€")
lstGrille.List(lstGrille.ListCount - 1, 3) = produits(i).Stock
End If
Next i
' Mise à jour du compteur
lblNbResultats.Caption = (lstGrille.ListCount - 1) & " produit(s)"
end Sub
Private Sub lstGrille_Click()
' Ignorer le clic sur l'en-tête
If lstGrille.ListIndex <= 0 Then
ActiverBoutonsEdition False
Exit Sub
End If
' Stocker la ligne sélectionnée
selectedRow = lstGrille.ListIndex
' Activer les boutons d'édition
ActiverBoutonsEdition True
' Remplir le panneau de détails
Dim produitID As Integer
produitID = lstGrille.List(selectedRow, 0)
Dim produitIndex As Integer
For i = 1 To UBound(produits)
If produits(i).ID = produitID Then
produitIndex = i
Exit For
End If
Next i
If produitIndex > 0 Then
txtID.Value = produits(produitIndex).ID
txtNom.Value = produits(produitIndex).Nom
txtPrix.Value = produits(produitIndex).Prix
txtStock.Value = produits(produitIndex).Stock
End If
End Sub
Private Sub ActiverBoutonsEdition(activer As Boolean)
btnModifier.Enabled = activer
btnSupprimer.Enabled = activer
' Panneau de détails
frmDetails.Enabled = activer
End Sub
Private Sub txtRecherche_Change()
' Recherche en temps réel
RemplirGrille
' Réinitialiser la sélection
ActiverBoutonsEdition False
End Sub
Private Sub btnAjouter_Click()
' Vider les champs
txtID.Value = ""
txtNom.Value = ""
txtPrix.Value = ""
txtStock.Value = ""
' Activer le panneau de détails en mode ajout
frmDetails.Enabled = True
frmDetails.Caption = "Ajouter un produit"
txtNom.SetFocus
' Cacher les boutons d'action et afficher les boutons de validation
btnAjouter.Visible = False
btnModifier.Visible = False
btnSupprimer.Visible = False
btnValider.Visible = True
btnAnnulerEdition.Visible = True
' Mode ajout
txtID.Enabled = False
frmDetails.Tag = "AJOUT"
End Sub
Private Sub btnModifier_Click()
If selectedRow <= 0 Then Exit Sub
' Activer le panneau de détails en mode modification
frmDetails.Enabled = True
frmDetails.Caption = "Modifier le produit"
txtNom.SetFocus
' Cacher les boutons d'action et afficher les boutons de validation
btnAjouter.Visible = False
btnModifier.Visible = False
btnSupprimer.Visible = False
btnValider.Visible = True
btnAnnulerEdition.Visible = True
' Mode modification
txtID.Enabled = False
frmDetails.Tag = "MODIF"
End Sub
Private Sub btnSupprimer_Click()
If selectedRow <= 0 Then Exit Sub
' Demander confirmation
Dim produitID As Integer
produitID = lstGrille.List(selectedRow, 0)
Dim reponse As VbMsgBoxResult
reponse = MsgBox("Êtes-vous sûr de vouloir supprimer le produit ID " & produitID & " ?",
_
vbQuestion + vbYesNo, "Confirmation de suppression")
If reponse = vbNo Then Exit Sub
' Simuler la suppression
Dim produitIndex As Integer
For i = 1 To UBound(produits)
If produits(i).ID = produitID Then
' Dans un cas réel, vous supprimeriez l'élément du tableau
' ou de la base de données
produits(i).Nom = produits(i).Nom & " (SUPPRIMÉ)"
Exit For
End If
Next i
' Rafraîchir la grille
RemplirGrille
' Réinitialiser la sélection
ActiverBoutonsEdition False
MsgBox "Produit supprimé avec succès", vbInformation
End Sub
Private Sub btnValider_Click()
' Validation des champs
If Trim(txtNom.Value) = "" Then
MsgBox "Le nom du produit est obligatoire", vbExclamation
txtNom.SetFocus
Exit Sub
End If
If Not IsNumeric(txtPrix.Value) Then
MsgBox "Le prix doit être un nombre", vbExclamation
txtPrix.SetFocus
Exit Sub
End If
If Not IsNumeric(txtStock.Value) Then
MsgBox "Le stock doit être un nombre entier", vbExclamation
txtStock.SetFocus
Exit Sub
End If
' Traiter selon le mode (ajout ou modification)
If frmDetails.Tag = "AJOUT" Then
' Simuler l'ajout
' Dans un cas réel, vous ajouteriez à un tableau redimensionné
' ou une base de données
MsgBox "Produit ajouté avec succès (simulation)", vbInformation
Else
' Simuler la modification
Dim produitID As Integer
produitID = CInt(txtID.Value)
For i = 1 To UBound(produits)
If produits(i).ID = produitID Then
produits(i).Nom = txtNom.Value
produits(i).Prix = CDbl(txtPrix.Value)
produits(i).Stock = CInt(txtStock.Value)
Exit For
End If
Next i
MsgBox "Produit modifié avec succès", vbInformation
End If
' Rafraîchir la grille
RemplirGrille
' Revenir au mode normal
RetourModeNormal
End Sub
Private Sub btnAnnulerEdition_Click()
' Annuler l'édition et revenir au mode normal
RetourModeNormal
End Sub
Private Sub RetourModeNormal()
' Réactiver les boutons d'action
btnAjouter.Visible = True
btnModifier.Visible = True
btnSupprimer.Visible = True
' Cacher les boutons de validation
btnValider.Visible = False
btnAnnulerEdition.Visible = False
' Désactiver le panneau de détails
frmDetails.Enabled = False
frmDetails.Caption = "Détails du produit"
' Réinitialiser la sélection
If selectedRow > 0 Then
ActiverBoutonsEdition True
Else
ActiverBoutonsEdition False
End If
End Sub
Private Sub btnFermer_Click()
Unload Me
End Sub
Astuces et bonnes pratiques
Nommage des contrôles
Utilisez un préfixe pour identifier facilement le type de contrôle :
frm : UserForm
lbl : Label
txt : TextBox
cmd ou btn : CommandButton
chk : CheckBox
opt : OptionButton
cbo : ComboBox
lst : ListBox
img : Image
fra : Frame
tab : TabStrip
mpg : MultiPage
scr : ScrollBar
Organisation du code
Placez les événements Initialize et Terminate en haut du module
Regroupez les gestionnaires d'événements par contrôle
Utilisez des régions ou des commentaires pour séparer les sections
Créez des fonctions auxiliaires pour les tâches répétitives
Raccourcis clavier
Ajoutez des raccourcis clavier pour améliorer l'ergonomie :
vb
Private Sub UserForm_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
' Alt+F pour fermer (Alt = 4)
If Shift = 4 And KeyCode = vbKeyF Then
Unload Me
End If
' Ctrl+S pour sauvegarder (Ctrl = 2)
If Shift = 2 And KeyCode = vbKeyS Then
btnSauvegarder_Click
End If
' F1 pour l'aide
If KeyCode = vbKeyF1 Then
AfficherAide
End If
End Sub
Gestion du focus et de la tabulation
Définissez un ordre de tabulation logique (propriété TabIndex )
Utilisez SetFocus pour placer le curseur au bon endroit
Différenciez visuellement le contrôle actif (par ex. en changeant sa couleur de fond)
Validation de données optimisée
vb
' Valider en temps réel avec KeyPress
Private Sub txtNumerique_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
' N'autoriser que les chiffres et la virgule
Select Case KeyAscii
Case 48 To 57 ' Chiffres 0-9
' Autorisé, ne rien faire
Case 44, 46 ' Virgule ou point
' Vérifier qu'il n'y a pas déjà une virgule
If InStr(txtNumerique.Text, ",") > 0 Or InStr(txtNumerique.Text, ".") > 0 Then
KeyAscii = 0 ' Bloquer
End If
Case 8 ' Touche Retour arrière
' Autorisé, ne rien faire
Case Else
KeyAscii = 0 ' Bloquer les autres caractères
End Select
End Sub
' Validation lors de la perte de focus
Private Sub txtEmail_Exit(ByVal Cancel As MSForms.ReturnBoolean)
If txtEmail.Value <> "" Then
' Expression régulière simple pour valider un email
If Not ValiderEmail(txtEmail.Value) Then
MsgBox "L'adresse email n'est pas valide", vbExclamation
Cancel = True ' Empêcher de quitter le contrôle
End If
End If
End Sub
Private Function ValiderEmail(email As String) As Boolean
' Validation basique (pour une validation plus complète, utiliser RegExp)
ValiderEmail = (InStr(email, "@") > 1) And (InStr(InStr(email, "@") + 1, email, ".") >
0)
End Function
Persistance des données
vb
' Sauvegarder les préférences utilisateur
Sub SauvegarderPreferences()
' Utiliser le registre Windows
SaveSetting "MonApplication", "Preferences", "Langue", cboLangue.Value
SaveSetting "MonApplication", "Preferences", "Theme", cboTheme.Value
SaveSetting "MonApplication", "Position", "FormLeft", Me.Left
SaveSetting "MonApplication", "Position", "FormTop", Me.Top
End Sub
' Charger les préférences utilisateur
Sub ChargerPreferences()
' Récupérer depuis le registre Windows
Dim langue As String, theme As String
langue = GetSetting("MonApplication", "Preferences", "Langue", "Français")
theme = GetSetting("MonApplication", "Preferences", "Theme", "Clair")
' Appliquer les préférences
cboLangue.Value = langue
cboTheme.Value = theme
' Position du formulaire
Dim posLeft As Variant, posTop As Variant
posLeft = GetSetting("MonApplication", "Position", "FormLeft", "")
posTop = GetSetting("MonApplication", "Position", "FormTop", "")
If posLeft <> "" And posTop <> "" Then
Me.Left = posLeft
Me.Top = posTop
End If
End Sub
Documentation du code
vb
'===========================================================================
' Nom du formulaire : frmGestionClients
' Description : Formulaire de gestion des clients
' Auteur : [Votre nom]
' Date de création : 10/05/2023
' Version : 1.2
'===========================================================================
'-----------------------------------------------------------
' Procédure : btnRechercher_Click
' Description : Recherche un client selon les critères saisis
' Paramètres : Aucun
' Retour : Aucun
'-----------------------------------------------------------
Private Sub btnRechercher_Click()
' Code de la recherche
End Sub
Conclusion
Les interfaces visuelles en VBA permettent de créer des applications professionnelles et ergonomiques dans
l'environnement Office. En maîtrisant les UserForms et leurs contrôles, vous pouvez développer des solutions
sur mesure adaptées aux besoins de vos utilisateurs.
Points clés à retenir :
1. Concevez des interfaces intuitives et cohérentes
2. Validez toujours les données saisies
3. Gérez correctement les événements pour une expérience utilisateur fluide
4. Organisez votre code pour faciliter la maintenance
5. Testez régulièrement avec différents scénarios d'utilisation
En appliquant ces principes et en vous appuyant sur les exemples fournis, vous serez en mesure de créer des
interfaces professionnelles qui amélioreront considérablement vos applications VBA.