Accueil    VBA      Communiquer avec un port série (RS232) 

Créer ses propres boîtes de dialogue (le retour !)
ou "Aller un peu plus loin !"



La première partie était destinée à décrire le fonctionnement d'un USERFORM. Cette page est destinée à expliquer comment exploiter les renseignements fourni par l'utilisateur à partir de quelques contrôles de la boite à outils.

Comme indiqué dans la page précédente, chaque objet utilisé dans un USERFORM a des propriétés. Certaines de ces propriétés peuvent être modifiées par l'utilisateur; le programme doit donc être conçu pour exploiter ces valeurs.
 

  1. Les boutons de commandes (CommandButton)
  2. Les cases à cocher (CheckBox)
  3. Les intitulés (Labels)
  4. Les zones de texte (TextBox)
  5. Prévoir et gérer les erreurs de l'utilisateur
  6. Les RefEdit (Sélection de cellules)
  7. Les zones de listes modifiables (ComboBox)
  8. Les zones de listes (ListBox)


Les cases à cocher (CheckBox) et intitulés (labels)

Les CheckBox servent à donner un réponse de type binaire: oui ou non, un ou zéro, vrai ou faux.
Les Labels affichent un texte.
En fonction de l'état de la CheckBox (cochée ou non cochée), sa propriété "Value" est égale à True ou False .
Nous allons créer un petit programme qui devra réagir en fonction de  l'état de la case à cocher.
Si vous avez bien retenu la leçon 1, il faut d'abord créer un module contenant le code ci-dessous dont le rôle est de lancer le USERFORM :

        Sub case_a_cocher()
                userform1.show
        end sub

- sur la grille du USERFORM, posez un label  et enlevez le texte "Label1" ou laissez sa propriété "Caption" vide
- posez une case à cocher
- double cliquez sur la CheckBox et entrez le code suivant:

Private Sub CheckBox1_Click()
                If UserForm1.CheckBox1.Value = True Then
                          UserForm1.Label1.Caption = "La case est cochée! "
                          UserForm1.Repaint

                           Else
                                    UserForm1.Label1.Caption = "La case n'est pas cochée! "
                                   UserForm1.Repaint
                 End If

End Sub

Exécutez la macro "Case_a_cocher". Ca marche ? Chez moi oui !
La commande "Repaint" (redessiner) n'est pas obligatoire dans ce cas mais si d'autres instructions avaient été écrites après la modification de "Label1", VBA aurait d'abord exécuté ces instructions avant de redessiner le Userform.
Notez que vous pouvez stocker  le statut de la CheckBox dans une variable:

    dim reponse as integer
    If Userform1.CheckBox1.Value = true then
            reponse=1
            else
                reponse=0
   End If

Ce petit programme était destiné à décrire le fonctionnement des objets "Labels" et "CheckBox". Il s'agit de "programmation evénementielle" parce que le programme s'exécute dès qu'un evénement particulier  (changement de l'état de la checkbox) se produit. Vous n'êtes pas obligé de lier votre code à l'événement "Click" (Private Sub CheckBox1_Click); vous auriez pu exécuter le code depuis un CommandButton ou dans un module. Le fait de cocher/décocher la checkbox n'aurait pas déclenché d'événement apparent; seule la valeur de la propriété "Value" en aurait été affectée.


Les zones de texte (TextBox)

Elles permettent à l'utilisateur d'entrer un texte que le programme utilisera ultérieurement. Un petit exemple valant mieux qu'un grand discours, nous allons écrire un programme déstiné à entrer des valeurs dans une feuille Excel.

- supprimez la CheckBox et le Label du USERFORM précédent
- posez une zone de texte sur la grille
- poser un bouton, double-cliquez dessus et entrez le code suivant:

            Private Sub CommandButton1_Click()
'teste si un texte a été entré, si non, le programme averti l'utilisateur et s'arrête
               If Userform1.TextBox1.Text = "" then
                        MsgBox "Vous n'avez rien saisi;" & Chr(10) & "fin du programme! "
                     Exit Sub
                        Else
'Si un texte a été entré, le programme le copie dans la cellule active et se déplace d'une cellule vers le bas
                              Activecell.value=Userform1.TextBox1.Text
                              Activecell.Offset(1,0).select
                End If
            End Sub

Exécutez le programme "case_a_cocher".


Dans la pratique, le programme précédent est rarement utilisé par l'auteur. Si l'utilisateur n'est pas l'auteur, il faut prévoir un maximum d'erreurs d'utilisation. Voici une version un peu plus sécurisée:

            Private Sub CommandButton1_Click()
'teste si un texte a été entré, si non, le programme averti l'utilisateur et s'arrête
               If Userform1.TextBox1.Text = "" then
                        MsgBox "Vous n'avez rien saisi;" & Chr(10) & "Recommencez! "
                    Exit Sub
                   End If

'teste le nombre de caractères saisis; si il est supérieur à 10, l'utilisateur est prévenu et le programme s'arrête
            If Len(userform1.TextBox1.Text) > 10 then
                    MsgBox("Il y a plus de 10 caractères dans le texte saisi;" & Chr(10) & "Recommencez! ")
                    Exit Sub
              End If

'teste le n° de ligne de la cellule active; si on est sur la dernière ligne (XL97,98 ou 2K), le programme prévient l'utilisateur
                If ActiveCell.Row = 65536 Then
                        MsgBox("La cellule active est sur la dernière ligne de la feuille;" &  Chr(10) & _
                                    " Vous devrez  sélectionner une autre cellule et relancer le programme")
                  End If

'tant que la cellule active n'est pas vide, le programme demande ce qu'il doit faire
             Do While Activecell.Value <> ""
                choix = MsgBox("La cellule contient déjà une valeur, voulez-vous la remplacer ?", VBYesNo)
                 IF choix = 6 Then
                        Activecell.value=Userform1.TextBox1.Text
                End If

'gestion de l'erreur: "on ne peut pas  se déplacer d'une cellule vers le bas!"
                    On Error GoTo fin
               Activecell.Offset(1,0).Select
                   Loop

'Si un texte a été entré, le programme le copie dans la cellule active et se déplace d'une cellule vers le bas
                              Activecell.Value=Userform1.TextBox1.Text
                              On Error GoTo fin
                              Activecell.Offset(1,0).Select

        fin:
        End Sub

La mise en place de ces tests alourdi considérablement le code mais c'est le prix à payer pour éviter les pièges les plus sommaires !


Le RefEdit (Sélection de cellules)

Cet objet ne présente pas de difficultés particulières si ce n'est son absence de la boîte à outils standard. Si vous n'avez pas de RefEdit dans la boîte à outils:
- cliquez avec le bouton droit sur celle-ci
- sélectionnez "Contrôles suplémentaires"
- cochez "RefEdit.Ctrl" dans la liste

Nous allons nous intéresser à sa propriété "Value" qui permet de récupérer les références des cellules sélectionnées par l'utilisateur en réalisant un programme qui colorie les cellules sélectionnées. quand le programme est exécuté, une boîte de dialogue invite l'utilisateur à sélectionner une plage de cellules. L'utilisateur clique sur un bouton "Exécuter", le programme colorie les cellules et se ferme.
votre document Excel doit comprendre un module et un Userform.

- Posez un bouton de commande, un RefEdit et un intitulé sur la grille
- dans la propriété Caption de l'intitulé, mettez un texte invitant l'utilisateur à sélectionner une plage
   de cellules et à cliquez sur le bouton pour exécuter le programme
- double-cliquez sur le bouton de commande et entrez le code suivant:

   Private Sub CommandButton1_Click()
        Dim plage As String

        plage = UserForm1.RefEdit1.Value
        If plage = "" Then
           MsgBox "vous n'avez rien sélectionné, recommencez !"
            Exit Sub
        End If
'coloration en jaune (6) de l'arrière plan des cellules
        Range(plage).Interior.ColorIndex = 6
'déchargement du Userform
      Unload Me

    End Sub



Les zones de listes modifiables (ComboBox)

Elle permettent à l'utilisateur de sélectionner une seule valeur dans une liste ou d'en entrer une nouvelle. La valeur sélectionnée affecte la propriété Value de la combobox; c'est donc cette propriété qui permettra de récupérer la sélection.

Exemple 1 (utilisation de données de la feuille Excel):
- dans les cellules A1 à A3 de la feuille Excel, entrez les textes Alpha, Beta et Gamma
- posez un intitulé sur la grille et modifiez sa propriété Caption en entrant un texte invitant l'utilisateur à sélectionner une occurence dans la liste
- poser une zone de liste modifiable sur la grille
- recherchez la propriété RowSource de la ComboBox1 et entrez les références à la feuille Excel comme ceci: Feuil1!A1:A3 ( Il s'agit tout simplement de la source des données affichées dans la ComboBox)
- (facultatif) recherchez la propriété Value et donnez lui comme valeur: Choisir
- poser un bouton de commande et entrez le code suivant:

    Private Sub CommandButton1_Click()
            Label1.Caption = ComboBox1.Value
    End Sub
- exécuter le programme
 

Exemple 2 (utilisation de valeurs entrées "en dur" dans le code du programe)

- sélectionnez la combobox1 et supprimer les références de la propriété Rowsource
- double-cliquez sur la grille pour accèder au code
- entrez le code suivant

Private Sub UserForm_Initialize()
    ComboBox1.AddItem "Alpha"
    ComboBox1.AddItem "Beta"
    ComboBox1.AddItem "Gamma"
End Sub
- exécuter le programme

A chaque clic sur le bouton, l'intitulé affiche la valeur sélectionnée. Si l'utilisateur ne trouve pas son bonheur dans la liste, il peut taper une valeur.


Les zones de listes (ListBox)

 Cet objet permet à l'utilisateur de sélectionner une ou plusieurs  valeurs dans une liste (propriété MultiSelect). La liste pouvant elle même contenir une ou plusieurs colonnes (propriété ColumnCount).Avant d'être utilisé, le contrôle doit être initialisé. La source des données de la liste peut être écrite "en dur" dans le code du programme ou issue d'une feuille Excel (voir les ComboBox pour cette partie).
Contrairement aux ComboBox, il n'existe pas de propriété Value dans une ListBox et pour cause: la sélection pouvant être multiple, une seule propriété ne pourrait les accueillir. On repére les éléments sélectionnés en fonction de leur état:
ils sont sélectionnés (Selected) ou non ce qui oblige à les passer en revue les un après les autres.

- dans les cellules A1 à A3 de la feuille Excel, entrez les textes Alpha, Beta et Gamma
- dans les cellules B1 à B3, entrez les valeurs 1, 2, 3
- posez un  intitulé sur la grille et modifiez sa propriété Caption pour qu'elle soit vide
- poser une zone de liste modifiable sur la grille
- recherchez la propriété ColumnCount de la ListBox1 et entrez: 2
- recherchez la propriété MultiSelect de la ListBox1 et sélectionnez 2-fmMultiSelectExtended
- recherchez la propriété RowSource de la ListBox1 et entrez les références à la feuille Excel comme ceci: Feuil1!A1:B3
- poser un bouton de commande et entrez le code suivant:

Private Sub CommandButton1_Click()

    Dim element_select As Boolean
    Dim nb_elements , i  As Integer

    element_select = False
    nb_elements = UserForm1.ListBox1.ListCount
'Vérifie si un élément est sélectionné
'le 1er item (élément) est indexé à zéro, raison pour laquelle la boucle for démarre à zéro
    For i = 0 To nb_elements - 1
        If UserForm1.ListBox1.Selected(i) = True Then
            element_select = True
            Exit For
       End If
    Next
 ' si aucun item n'a été sélectionné, il est inutile d'aller plus loin !
    If element_select = False Then
        MsgBox "Vous n'avez rien sélectionné; fin du programme"
        Exit Sub
    End If

'Affiche le nombre de sélections dans l'intitulé
    Label1.Caption = "Il y a " & nb_elements & " éléments sélectionnés"

'sélectionne la cellule devant recevoir la 1ère valeur
    Range("C1").Select

'Ecriture des valeurs sélectionnés dans la feuille Excel
    For i = 0 To nb_elements - 1
'affecte à la cellule active la valeur sélectionnée de la colonne un de la ListeBox
'l'index des colonnes commançant à zéro, on utilise la valeur 0
            ActiveCell.Value = ListBox1.List(i, 0)
'affecte à la cellule immédiatement à droite de la cellule active la valeur sélectionnée de la colonne deux
'l'index des colonnes commançant à zéro, on utilise la valeur 1
            ActiveCell.Offset(0, 1).Value = ListBox1.List(i, 1)
'se déplace d'une cellule vers le bas
            ActiveCell.Offset(1, 0).Select
        End If
    Next i
 

End Sub

- exécutez le programme. Ouf, ça marche !
Si vous avez compris tous les exemples de cette page, vous êtes armés pour développer de belles applications.