Compléter un document Word à l’aide d’un UserForm
Qu’est-ce qu’un UserForm ?
Un UserForm est une boîte de dialogue destinée à servir d’interface utilisateur personnalisée dans une application. Dans l’interface utilisateur Word, il existe déjà de nombreuses boîtes de dialogue (Police, Paragraphe, Mise en page, etc.).
On y trouve de nombreux boutons, des listes déroulantes, des cases à cocher, des zones de texte à remplir, du texte et des images d’explication… Tous ces objets s’appellent des contrôles. Les contrôles sont disposés sur la feuille qui sert de fenêtre à la boîte de dialogue.
Voici maintenant une autre boîte de dialogue pouvant s’ouvrir dans Word :
Cet exemple permet de comprendre qu’un UserForm est un objet complexe qui comporte toujours les trois éléments suivants :
- La feuille : c’est la fenêtre qui s’affiche.
- Les contrôles : ce sont tous les objets présents dans la feuille et pouvant interagir avec l’utilisateur.
- Le code : c’est ce qui décide des actions déclenchées par l’utilisateur.
Un mot encore sur le code. L’essentiel en est la gestion des événements. Une fois ouverte et affichée, le UserForm doit réagir à un certains nombre d’actions de l’utilisateur. Ainsi cliquer sur le bouton OK est un événement. Par cette action on s’attend que le code valide toutes les données entrées et réalise le propos de la boîte de dialogue comme ici lancer une impression au moment de refermer le UserForm lui-même.
Exemple de UserForm pour compléter un document
Créer un nouveau UserForm
- Créer un document vierge.
- Ouvrez VBE via Alt+F11.
- Dans la fenêtre de l’explorateur de projets, sélectionner le projet du document créé
- Menu Insertion => Userform
Avant de commencer à remplir notre UserForm1, jetons un coup d’œil sur son code en cliquant sur le bouton ‘Afficher le code’ de la fenêtre Projet ou avec F7 pour constater que ce code est vide pour l’instant. Revenons à l’objet UserForm avec Maj+F7.
Placer des contrôles
Notre exemple comportera les contrôles suivants :
- Deux radio-boutons s’excluant l’un l’autre dans un contrôle Cadre par leur propriété (sexe du questionneur).
- Deux zones de texte : l’une pour la question, l’autre pour la date.
- Une liste déroulante ComboBox
- Deux boutons : l’un pour annuler l’autre pour valider (OK)
- Enfin trois Intitulés ou labels, simples contrôles passifs pour la lisibilité du formulaire.
Au total donc 12 contrôles sur notre UserForm une fois construit :
Le code du UserForm
Afficher et fermer le UserForm
Le Userform doit d’abord être chargé en mémoire avec tous ses objets. C’est le rôle de la commande Load. Par la suite notre objet UserForm désigné par son nom pourra être affiché par sa méthode Show et refermé par sa méthode Hide. VBA accepte d’exécuter implicitement la commande Load si on l’oublie avant l’exécution d’un Show.
Dans notre exemple le chargement et l’affichage de notre UserForm est exécuté dans une macro automatique à chaque ouverture du document (Sub Document_Open).
Nous y ajouterons la réouverture du UserForm pour éventuelle correction à l’aide d’un bouton « Cliquez ici pour lancer le formulaire ». Ce bouton exécute la macro Formulaire qui se contente d’exécuter à nouveau Show. Un autre bouton « Cliquez ici pour vider le document » lance la macro RAZ et vide le contenu ajouté.
Initialiser le UserForm
Il s’agit dans cette phase de renseigner les diverses propriétés du UserForm et de ses contrôles avant qu’il ne s’ouvre. Dans notre exemple il faut notamment renseigner la liste des répondeurs dans la combobox et ajuster la zone de texte Date la date du jour.
Le code d’initialisation d’une UserForm peut être très complexe surtout s’il faut rechercher des données dans le document lui-même ou dans des fichiers externes. On aurait pu imaginer par exemple que la liste des répondeurs de la combobox soit à chercher dans une feuille excel, laquelle contiendrait également pour chacun le délai moyen de réponse à appliquer au calendrier.
Toute cette phase d’initialisation peut être placée dans le code d’appel entre Load et Show ou mieux dans le code de l’événement Initialize du UserForm lui-même. Cet événement est lancé à chaque Load. Notez que Show ne provoque pas un événement Initialize.
Le code des contrôles
C’est tout le code événementiel dictant comment doit réagir chaque contrôle aux actions de l’utilisateur. Les événements possibles sont très nombreux pour chaque contrôle mais il suffit de coder uniquement ceux qui doivent déclencher une réponse. Un bon nombre de contrôles n’a pas besoin de code. Ce sont surtout les clics sur les boutons qu’il faut coder.
On accède facilement au code d’un contrôle en double-cliquant dessus : la fenêtre de code affiche en haut le contrôle et les divers événements qu’il est possible de coder.
Le bouton Annuler referme le UserForm par un Hide sans rien faire d’autre.
C’est le bouton de validation qui est le plus important. L’événement Click sur le bouton OK doit en effet :
1) collecter les données du UserForm
2) vérifier leur cohérence en refusant au besoin de refermer la UserForm
3) exécuter le propos de la UserForm
et enfin
4) fermer la UserForm.
L’étape de vérification des données peut aussi s’effectuer au niveau d’un contrôle par exemple avec son événement Change chaque fois que sa valeur est modifiée.
Dans notre exemple après vérification des zones de texte et de la date, la validation de la saisie doit provoquer l’insertion des données dans le document.
Le code de l’application
Ici on range le code spécialisé, les macros, les procédures et fonctions du projet pour lequel on a généralement développé précisément la UserForm. Ce code est généralement placé dans un ou plusieurs modules de façon à ne pas surcharger le code événementiel de la Userform qui y fera appel.
Dans notre exemple nous plaçons un module Signets chargé de traiter la mise à jour des signets dans un document. En effet le simple remplacement du texte d’un signet par un autre efface le signet en vba. La procédure RemplirSignet(Signet, Texte) remplace le contenu d’un Signet par Texte sans détruire ce signet, que ce dernier soit initialement vide ou non. Cette procédure est utilisée par notre UserForm pour remplir le document. Voir cet article concernant cette problématique de signet).
Placé dans le même projet ce code est appelé par le code événementiel des contrôles de la Userform.
Le code VBA final de l’exemple
Tout l’exemple est téléchargeable dans l’exemple fourni. En allant dans VBE avec Alt+F11 on y trouvera la UserForm décrite plus haut ainsi que tout le code reproduit ci après :
Dans ThisDocument
Call Formulaire
End Sub
Private Sub CommandButton2_Click()
raz
End Sub
Sub Formulaire()
' Réaffiche la UserForm
UserForm1.Show
End Sub
Private Sub Document_Open()
' Lancement automatique à chaque nouveau document
Load UserForm1
UserForm1.Show
End Sub
Dans le module Signets
' *******************************
' *** Utilisation des signets ***
' *******************************
Public Sub RemplirSignet(S As String, T As String)
' Remplit le signet S avec le texte T sans détruire S
On Error GoTo rien
Dim Place As Long
Place = ActiveDocument.Bookmarks(S).Range.Start
ActiveDocument.Bookmarks(S).Range.Text = T
ActiveDocument.Bookmarks.Add Name:=S, _<br> Range:=ActiveDocument.Range(Place, Place + Len(T))
rien:
End Sub
Sub raz()
Dim T As String ' Titre
Dim Q As String ' Question
Dim R As String ' Répondeur
Dim D As String ' Date
RemplirSignet "Titre", T
RemplirSignet "Question", Q
RemplirSignet "Répondeur", R
RemplirSignet "Date", D
End Sub
Dans le Userform
Option Explicit
Dim T As String ' Titre
Dim Q As String ' Question
Dim R As String ' Répondeur
Dim D As String ' Date
Private Sub UserForm_Initialize()
' Lors du chargement de la UserForm : opérations d'initialisations
' 1 - Remplissage de la liste déroulante
With Me.ComboBox1
.AddItem "Claude"
.AddItem "Argitxu"
.AddItem "Geo"
.AddItem "m@rina"
End With
' 2 - Initialisation de la date : aujourd'hui + 1 jour
Me.TextBox2.Value = Date + 1
' 3 - Initialisation du focus
Me.TextBox1.SetFocus
End Sub
Private Sub CommandButton1_Click()
' = Bouton Annuler
' Lui affecter la propriété Cancel à True
' pour bénéficier de la touche Echap (ESC)
'me.Hide conserve les données entrées si on relance le formulaire
Me.Hide
End Sub
Private Sub CommandButton2_Click()
Dim madate As Date
' = Bouton OK
' Les données du UserForm :
'Dim T As String ' Abonné m ou f
'Dim Q As String ' Question
'Dim R As String ' Répondeur
'Dim D As String ' Date
' 1 - Récupérer les données
If Me.OptionButton1 = True Then
T = "Cher abonné"
Else: T = "Chère abonnée"
End If
Q = Me.TextBox1.Text
R = Me.ComboBox1.Value
D = Me.TextBox2.Value
' 2 - Vérifier la cohérence des données
If Me.TextBox1.Value = "" Then
MsgBox "Il manque la question !", vbExclamation, "Erreur"
Exit Sub
End If
Me.TextBox2.Value = Format(TextBox2.Value, "dd mmmm yyyy")
madate = Date + 1
If Me.TextBox2.Value < madate Then
MsgBox "On ne peut répondre avant demain !", vbExclamation, "Erreur"
Me.TextBox2.Value = Date + 1
Exit Sub
End If
' 3 - Placer les données dans le document
RemplirSignet "Titre", T
RemplirSignet "Question", Q
RemplirSignet "Répondeur", R
RemplirSignet "Date", D
With ActiveDocument
.Fields.Update ' màj des champs pour le renvoi sur Titre
'ajout de couleur pour le répondeur et la date
.Bookmarks("Répondeur").Range.Font.ColorIndex = wdRed
.Bookmarks("Date").Range.Font.ColorIndex = wdRed
End With
' 4 - Fermer la Userform et la supprime de la mémoire
Unload Me
End Sub