Compléter un document Word à l’aide d’un UserForm

Qu’est-ce qu’un UserForm ?
Exemple de UserForm pour compléter un document
Créer un nouveau UserForm
Placer des contrôles
Le code du UserForm
Le code VBA final de l’exemple

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 :

Inutile de chercher celle-ci dans votre Word, c’est un UserForm ! Si elle ressemble à ce que vous avez l’habitude de voir, elle commande à l’évidence des fonctions inhabituelles pour Word : ajouter à l’impression un filigrane non présent dans le document, gérer un compteur des copies imprimées ou tenir un journal des impressions.

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.
La feuille est désignée par le nom de l’objet UserForm lui-même. Les contrôles sont des objets incorporés dans le UserForm : ils font partie de ses propriétés. Le code enfin, sans lequel un UserForm n’aurait aucune action est contenu également dans l UserForm au même titre qu’un module dans un projet.

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

Nous choisirons un exemple simple de Userform utilisé comme formulaire pour compléter un document. Supposons un modèle de document ainsi constitué :
Nous voulons qu’à la création d’un nouveau document basé sur ce modèle s’ouvre un formulaire facilitant la saisie rapide des textes placés ici entre guillemets, lesquels sont en réalité des signets dans le document.

Créer un nouveau UserForm

La création d’un UserForm est très simple dans VBE l’éditeur visual-basic :
  • 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
 
C’est tout : le document contient désormais un UserForm. Son nom est UserForm1 par défaut. Affichons au besoin les propriétés de UserForm1 avec F4. Nous pouvons redimensionner UserForm1 et modifier ses propriétés. Nous pouvons changer son nom et changer son titre (caption). Gardons le nom UserForm1 mais changeons le titre en Formulaire.

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

C’est un simple petit jeu de construction graphique ! Il suffit d’utiliser la boîte à outils des contrôles : Affichage => Boîte à outils, de choisir parmi les contrôles disponibles et de les dessiner sur la UserForm.
La boîte à outils contrôles
 
 Affichons aussi la barre d’outils UserForm qui contient de quoi faciliter la mise en place des contrôles. Pour chaque contrôle, il convient dès sa création d’en définir les propriétés initiales en utilisant très largement la fenêtre Propriétés. Si vous hésitez à modifier une de ces propriétés, sélectionnez-là et voyez avec F1 dans l’Aide VBA à quoi elle correspond. À tout moment il sera possible de redéfinir les propriétés d’un contrôle.

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.
La fenêtre des propriétés
Notez ici la propriété GroupName commune aux deux boutons d’option. En définissant le même nom de groupe, les deux options (M/F) s’excluent mutuellement sans avoir besoin de code supplémentaire.

Au total donc 12 contrôles sur notre UserForm une fois construit :
Il est important de bien prévoir et disposer ses contrôles avant de passer à l’étape d’écriture du code.

Le code du UserForm

Reste maintenant à écrire tout le code VBA pour notre UserForm ! Plus le UserForm disposera de contrôles plus le code sera compliqué. À l’aide de notre petit exemple nous en distinguerons 4 parties classiques :

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

Private Sub CommandButton1_Click()
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 "Anacoluthe"
    .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

= Me.TextBox1.Text

= Me.ComboBox1.Value

= 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