Pour partager cette vidéo sur les réseaux sociaux ou sur un site, voici son url :
Sujets que vous pourriez aussi aimer :
Remplir un document avec un formulaire
L'un des intérêts majeurs du VBA Word est de pouvoir automatiser des traitements mais aussi des tâches utilisateur.
Dans l'exemple finalisé présenté par la capture, l'utilisateur débouche sur un document modèle prêt à remplir. Mais pour éviter les mauvaises manipulations, c'est un formulaire qui se dresse au premier plan. Tous les renseignements attendus doivent être inscrits dans les zones de saisie et choisis dans les listes déroulantes. Une fois toutes les informations fournies et après avoir cliqué sur le bouton de validation, ces données s'insèrent dans le document précisément là où elles sont attendues. Ce document est automatiquement enregistré sous un nom personnalisé pour préserver le modèle. Il ne reste plus qu'à exploiter la fiche du courrier ainsi conçue automatiquement.
Document source
Nous proposons de débuter l'étude à partir d'un document Word offrant une ébauche de courrier modèle ainsi qu'un formulaire programmé pour se déclencher à l'ouverture.
Double cliquer sur le fichier réceptionné pour l'ouvrir dans Word,
Cliquer sur le bouton Activer la modification du bandeau de sécurité,
Puis, cliquer sur le bouton Activer le contenu du nouveau bandeau de sécurité,
Dès lors et comme vous pouvez le voir, le formulaire de saisie surgit effectivement. Tous ses champs doivent être renseignés puisque toutes ces informations sont attendues dans le document modèle situé à l'arrière-plan.
Cliquer sur le bouton Annuler pour fermer le formulaire,
Le Userform en conception
La main est rendue au document Word. Le courrier est très dépouillé mais il est volontairement allégé pour simplifier la mise en place de la solution.
Réaliser le raccourci clavier Alt + F11 pour basculer dans l'éditeur VBA Word,
Dans l'explorateur de projet sur la gauche de l'écran, déployer le dossier Feuilles,
Puis, double cliquer sur l'élément Renseignements,
Il s'agit du UserForm, soit du formulaire. Et cette action a pour effet de l'afficher au centre de l'écran, dans sa vue en conception.
C'est le bouton Créer que nous allons devoir principalement développer.
L'ouverture automatique du formulaire
Nous l'avons évoqué, des fragments de code existent déjà. Ce n'est pas par magie que le formulaire surgit automatiquement à l'activation du document.
Toujours dans l'explorateur de projet, double cliquer cette fois sur l'élément thisDocument,
Nous affichons ainsi la feuille de code VBA associée au document actif, soit au courrier modèle. Et nous y trouvons une petite procédure événementielle.
Private Sub Document_Open()
On Error Resume Next
Renseignements.Show
End Sub
Son code se déclenche à l'ouverture du document. C'est donc cette procédure qui affiche le formulaire au démarrage grâce à sa méthode Show. Vous notez la présence d'une instruction pour ignorer les erreurs (On Error Resume Next). Avec Word, dans un tel cas de figure, elles sont susceptibles de se déclencher. Nous choisissons donc d'ignorer les messages d'alerte.
Les actions du formulaire
Nous l'avons constaté précédemment, un clic sur le bouton Annuler permet de fermer le formulaire. Mais ce n'est pas le seul code VBA déjà présent.
Dans l'explorateur de projet, double cliquer de nouveau sur l'élément Renseignements,
Sur le formulaire en conception, double cliquer sur le bouton Annuler,
Nous basculons ainsi sur la feuille de code entre les bornes de la procédure Annuler_Click.
Private Sub Annuler_Click()
Renseignements.Hide
End Sub
Son code se déclenche au clic sur le bouton. Et c'est la méthode Hide de l'objet Formulaire qui permet de masquer ce dernier. Plus bas dans la feuille, la procédure UserForm_Activate remplit les listes déroulantes au chargement du formulaire.
Ces listes déroulantes se nomment respectivement Civilite et texteType. Une autre procédure et une fonction existent mais elles sont vides pour l'instant. Nous y reviendrons.
Les noms des contrôles
Pour remplir le document Word des informations saisies dans les champs du formulaire, nous allons avoir besoin de piloter ces derniers. Et pour cela, nous devons connaître leurs noms d'objets.
Dans l'explorateur de projet, double cliquer sur l'élément Renseignements,
Sur le formulaire en conception, cliquer sur la deuxième zone de texte, celle du nom,
En consultant sa propriété (Name) dans sa feuille de propriétés, vous remarquez que ce champ est intitulé Nom. Si cette fenêtre de propriétés n'est pas visible dans votre environnement, vous devez cliquer sur le menu Affichage et choisir Fenêtre Propriétés.
En sélectionnant tour à tour les zones du formulaire, vous pouvez constater qu'elles sont respectivement nommées Civilite, Nom, Prenom, Adresse, CP, Ville, Sujet et texteType.
Les marques d'insertion dans le document
C'est précisément dans l'ordre de ces contrôles que les informations sont attendues sur le courrier modèle du document Word. Une astuce va permettre de considérablement simplifier l'implémentation du code VBA. Nous avons marqué les zones à enrichir par des repères invisibles. Ces repères invisibles sont des signets. Ces signets sont des objets que le code VBA Word peut piloter pour y insérer les informations attendues issues du formulaire.
Revenir sur le document Word,
En haut de la fenêtre, cliquer sur l'onglet Insertion pour activer son ruban,
Dans la section Liens de ce ruban, cliquer alors sur le bouton Signet,
Le signet Zone1 pointe sur le texte Civilité à remplacer par l'information définie par l'utilisateur depuis le formulaire. Ils suivent le même ordre que ceux des zones sur le UserForm (Zone2 pour le texte Nom, Zone3 pour le texte Prénom etc..). Et c'est judicieusement que nous leur avons attribué des intitulés identiques simplement différenciés par un numéro incrémenté. Grâce à cette astuce, en même temps que nous parcourrons toutes les zones du formulaire avec une boucle for each, nous pointerons sur les signets correspondants sur le document. C'est ainsi que nous allons pouvoir simplifier et optimiser le code VBA.
Cliquer sur le bouton Annuler de la boîte de dialogue pour revenir sur le document,
Dernière remarque, vous avez sans doute noté la présence de deux signets ne respectant pas cette chronologie, Nom et Prénom. Ces informations sont répétées en bas du document. C'est la raison de leur présence. Nous les traiterons à part.
Vérifier si les champs sont bien renseignés
Il est temps maintenant de plonger les mains dans la programmation VBA. Toutes les informations du formulaire sont requises. Avant d'enclencher tout traitement, nous devons donc nous assurer que l'utilisateur a bien renseigné tous les champs. Et pour cela, nous devons les parcourir tous à l'aide d'une boucle afin de vérifier les contenus respectifs.
Revenir dans l'éditeur VBA Word (Alt + Tab ou Alt + F11),
Sur le formulaire en conception, double cliquer sur le bouton Annuler,
Dans la feuille de code, cliquer entre les bornes (Function et End Function) de la fonction test,
Puis, ajouter les déclarations et affectations de variables suivantes :
Function test() As Boolean Dim zone As Control: Dim compteur As Byte
test = True: compteur = 1
End Function
La variable Zone est définie comme un objet de type Control au sens large. C'est elle que nous allons utiliser dans une boucle pour parcourir tous les objets du formulaire. La variable compteur est définie comme un entier court (Byte). Nous l'incrémenterons à chaque passage dans la boucle pour mettre fin à cette dernière à l'indice 8, soit à partir de la dernière zone de saisie. Les boutons ne sont en effet pas concernés par ce contrôle et ne disposent pas des mêmes propriétés. Ensuite, nous initialisons la valeur de la fonction booléenne à True. Par défaut et jusqu'à preuve du contraire, nous considérons que tous les champs du formulaire sont renseignés. Puis, nous initialisons la variable compteur sur le chiffre 1.
Nous devons maintenant parcourir tous les contrôles du formulaire.
Pour cela, à la suite du code VBA, créer la boucle For Each comme suit :
Function test() As Boolean
Dim zone As Control: Dim compteur As Byte
test = True: compteur = 1
For Each zone In Me.Controls
Next zone
End Function
L'objet VBA Me désigne le formulaire actif. Controls est une propriété qui renvoie la collection des contrôles hébergés par le formulaire. Il s'agit en quelques sortes d'un tableau énumérant tous ces éléments. Et comme nous avons déclaré notre objet Zone sur le même type, grâce à la boucle For Each, nous pouvons tous les parcourir un à un.
Nous devons maintenant nous assurer que chaque zone est bien renseignée. Pour cela, une instruction conditionnelle est nécessaire. A chaque passage dans la boucle, elle doit vérifier que le contenu du contrôle en cours d'analyse n'est pas vide.
Dans les bornes de la boucle For Each, ajouter les instructions VBA suivantes :
Function test() As Boolean
Dim zone As Control: Dim compteur As Byte
test = True: compteur = 1
For Each zone In Me.Controls If (zone.Value = "") Then
test = False
Exit For
End If
Next zone
End Function
Grâce à la propriété Value, nous vérifions l'état du contenu pour chaque zone. Dès que l'une d'entre elles n'est pas renseignée (""), nous basculons l'état de la fonction à False pour informer son appelant et nous quittons la boucle (Exit For). Donc nous stoppons le traitement.
Dans le cas où toutes les zones ont correctement été renseignées et donc que le critère n'est jamais vérifié, nous devons stopper le traitement avant d'atteindre l'indice 9. Car après les zones de texte et les listes déroulantes, les boutons ne proposent pas de propriété Value. En conséquence, le test ferait déjouer le code VBA.
A la suite et dans les bornes de la boucle, ajouter les instructions VBA suivantes :
Function test() As Boolean
Dim zone As Control: Dim compteur As Byte
test = True: compteur = 1
For Each zone In Me.Controls
If (zone.Value = "") Then
test = False
Exit For
End If If (compteur = 8) Then Exit For
compteur = compteur + 1
Next zone
End Function
Lorsque la dernière zone d'information est atteinte (compteur = 8), nous mettons fin au traitement de la boucle. Sinon, nous n'oublions pas d'incrémenter la variable compteur pour continuer de suivre la chronologie du traitement.
Pour être utile, cette fonction doit être appelée depuis la procédure principale, soit au clic sur le bouton Créer. Sa procédure existe déjà.
Dans les bornes de la procédure Créer_Click, ajouter le code VBA suivant :
Private Sub Creer_Click()
If test = False Then
MsgBox "Tous les champs doivent être renseignés"
Exit Sub
End If
End Sub
C'est une instruction conditionnelle qui se charge de lancer la fonction test. Si son verdict est négatif (false), nous en informons l'utilisateur par le biais d'une boîte de message grâce à la fonction VBA MsgBox. Puis, nous mettons fin au traitement de la procédure (Exit Sub).
Le cas échéant, nous devrons de nouveau parcourir tous les contrôles en même temps que les signets du document pour entreprendre les injections automatisées et croisées.
Enregistrer les modifications (CTRL + S) puis exécuter le code (F5),
Sans renseigner les champs, cliquer directement sur le bouton Créer du formulaire,
Comme vous pouvez le voir, la route est barrée. Le message de la boîte de dialogue en informe effectivement l'utilisateur.
En revanche, si vous remplissez tous les champs et que vous cliquez sur le bouton Créer, aucune alerte ne surgit.
Cliquer sur le bouton Annuler du formulaire puis revenir dans l'éditeur VBA Word,
Insérer les données dans le document
Il est temps maintenant de remplir automatiquement le document Word en établissant la correspondance entre les zones de signet et les zones de texte du formulaire.
Dans la procédure Créer_Click, ajouter les déclarations de variables suivantes :
Private Sub Creer_Click() Dim zone As Control: Dim compteur As Byte
Dim Signet As Bookmarks: Dim plage As Word.Range
If test = False Then
MsgBox "Tous les champs doivent être renseignés"
Exit Sub
End If
End Sub
Pour parcourir tous les contrôles du formulaire comme précédemment, nous déclarons de nouveau les variables zone et compteur. Ensuite, nous déclarons la variable Signet comme un objet de type Bookmarks, soit comme un signet. Puis, nous déclarons la variable plage comme un objet de type Word.Range. Cet objet va nous permettre de pointer sur les emplacements définis par les signets du document pour y insérer les informations respectives du formulaire.
Ces objets doivent instancier les classes qu'ils pointent pour hériter de leurs méthodes et propriétés. Il est donc temps de passer à l'affectation de quelques variables.
Après le test sur l'appel de la fonction test, ajouter les deux affectations suivantes :
Private Sub Creer_Click()
Dim zone As Control: Dim compteur As Byte
Dim Signet As Bookmarks: Dim plage As Word.Range
If test = False Then
MsgBox "Tous les champs doivent être renseignés"
Exit Sub
End If
compteur = 1
Set Signet = ActiveDocument.Bookmarks
End Sub
Classiquement,nous initialisons tout d'abord le compteur de boucle. Puis, nous exploitons la propriété Bookmarks de l'objet VBA Word ActiveDocument. Elle renvoie la collection des signets. Désormais, ils sont tous représentés dans un tableau stocké dans la variable Signet.
La suite des affectations se fera à chaque passage dans la boucle pour redéfinir les signets sur les nouveaux emplacements. Grâce à cette collection de signets stockée dans la variable Signet, nous allons maintenant pouvoir les parcourir tous très simplement, en même temps que les contrôles du formulaire. Souvenez-vous, ils sont disposés dans le même ordre.
A la suite du code de la procédure Créer_Click, créer la boucle de parcours, comme suit :
Private Sub Creer_Click()
Dim zone As Control: Dim compteur As Byte
Dim Signet As Bookmarks: Dim plage As Word.Range
If test = False Then
MsgBox "Tous les champs doivent être renseignés"
Exit Sub
End If
compteur = 1
Set Signet = ActiveDocument.Bookmarks
For Each zone In Me.Controls
If compteur = 8 Then Exit For
compteur = compteur + 1
Next zone
End Sub
Nous exploitons la même technique que pour la fonction test. Lorsque le huitième contrôle est atteint, nous mettons fin à l'analyse récursive.
Maintenant, à chaque passage dans cette boucle, nous devons pointer sur le signet en cours d'analyse et faire la correspondance avec l'information contenue dans la zone de texte du formulaire.
Dans les bornes de la boucle, avant l'instruction If, ajouter les deux lignes VBA suivantes :
Private Sub Creer_Click()
Dim zone As Control: Dim compteur As Byte
Dim Signet As Bookmarks: Dim plage As Word.Range
If test = False Then
MsgBox "Tous les champs doivent être renseignés"
Exit Sub
End If
compteur = 1
Set Signet = ActiveDocument.Bookmarks
For Each zone In Me.Controls Set plage = Signet("Zone" & compteur).Range
plage.Text = zone.Value
If compteur = 8 Then Exit For
compteur = compteur + 1
Next zone
End Sub
Nous initialisons (set) la variable plage, sur la zone reconnue par le signet en cours (Signet("Zone" & compteur)), grâce à sa propriété Range. Maintenant que l'emplacement est défini, il ne reste plus qu'à y insérer l'information attendue. C'est ce que nous réalisons par affectation (plage.Text = zone.Value).
Bien sûr pour la dernière zone soit, celle de la seconde liste déroulante, il conviendrait de faire correspondre un texte modèle à insérer. Il suffirait de l'importer depuis le disque dur comme nous l'avons démontré au cours des astuces VBA Word précédentes.
A ce stade donc, tous les éléments attendus sur le document Word sont susceptibles d'être renseignés, à l'exception du rappel sur le nom et le prénom en conclusion du courrier. Nous devons donc les enrichir indépendamment.
Après la boucle, ajouter les instructions VBA suivantes :
Private Sub Creer_Click()
Dim zone As Control: Dim compteur As Byte
Dim Signet As Bookmarks: Dim plage As Word.Range
If test = False Then
MsgBox "Tous les champs doivent être renseignés"
Exit Sub
End If
compteur = 1
Set Signet = ActiveDocument.Bookmarks
For Each zone In Me.Controls
Set plage = Signet("Zone" & compteur).Range
plage.Text = zone.Value
If compteur = 8 Then Exit For
compteur = compteur + 1
Next zone
Set plage = Signet("Nom").Range
plage.Text = Nom.Value
Set plage = Signet("Prenom").Range
plage.Text = Prenom.Value
End Sub
Nous répliquons le même principe d'instanciation et d'affectation que celui de la boucle, mais cette fois en version statique.
Pour parfaire la solution, il ne nous reste plus qu'à enregistrer cette fiche individuelle de renseignement sous un nom unique. Pour cela, nous pouvons rassembler l'information sur le nom et le prénom et l'associer à l'indication sur la date en cours.
A la fin de la procédure, ajouter l'instruction VBA suivante :
Private Sub Creer_Click()
Dim zone As Control: Dim compteur As Byte
Dim Signet As Bookmarks: Dim plage As Word.Range
If test = False Then
MsgBox "Tous les champs doivent être renseignés"
Exit Sub
End If
compteur = 1
Set Signet = ActiveDocument.Bookmarks
For Each zone In Me.Controls
Set plage = Signet("Zone" & compteur).Range
plage.Text = zone.Value
If compteur = 8 Then Exit For
compteur = compteur + 1
Next zone
Set plage = Signet("Nom").Range
plage.Text = Nom.Value
Set plage = Signet("Prenom").Range
plage.Text = Prenom.Value
La méthode SaveAs de l'objet VBA Word ThisDocument attend le chemin complet en argument. Nous désignons l'emplacement du document actuel grâce à la propriété Path de ce même objet ThisDocument. Puis, nous lui associons les informations sur le nom, le prénom et la date séparées de tirets, pour livrer un nom bien formé. Notez l'emploi en cascade de la fonction VBA Replace afin de purger les caractères interdits dans les noms de fichiers comme le symbole du slash ou celui des deux points.
Si vous exécutez le code, que vous remplissez le formulaire et cliquez sur le bouton Créer, vous notez avec plaisir que le document Word est parfaitement rempli. Dans le même temps, il est parfaitement archivé sur le disque dur à l'emplacement du courrier type. Sur ces copies, pour que le formulaire ne se déclenche par à l'ouverture, il suffit simplement d'ajouter une gestion d'exception sur le nom du fichier dans la procédure événementielle Document_Open :
If(ThisDocument.Name = "courrier-type.docm") Then
Renseignements.Show End if
★ Le saviez-vous ? La traduction américaine de Octet est : Byte.