Comment créer un document basé sur du texte issu d'une base de données, d'une série d'autres documents ou en utilisant des morceaux d'un document.
Cet article est destiné à tous les publics et plus spécialement les débutants.

- Titre : Créer un document à tiroir

- Auteur : Olivier Lebeau

- Parution : 20 décembre 2010

- Licence : Copyright © 2010 Olivier Lebeau. CDATA[Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 € de dommages et intérêts. Droits de diffusion permanents accordés à Developpez LLC. Cette page est déposée à la SACD.

Sommaire

- 1. Introduction

- 2. Word

- 2-A. Les paragraphes

- 2-B. Un tableau

- 3. Excel

- 4. Access

- 5. Ajout d'images

- 6. Liens utiles

- 7. Conclusions et Remerciements

1 - Introduction

Un souci qui revient souvent est la possibilité de créer un document "complexe" basé sur des choix de l'utilisateur lors de la création du document.

La création d'un contrat en fonction des clauses utiles est un exemple concret.

La liste des solutions possible n'est pas exhaustive mais devrait couvrir une grande partie de vos besoins. Les logiciels que nous allons utiliser sont Word, Excel et Access.

Les versions 2007 et 2010 possèdent un outil semblable, les blocs de construction. Ce que je vous propose dans ce tutoriel est une alternative aux blocs de construction. L'avantage est que cette méthode alternative est utilisable pour toutes les versions de Word et que le fichier contenant les données peut se trouver dans un répertoire partagé du réseau avec une mise à jour des données très facile.
De plus, il est possible soit d'avoir un fichier de données spécifique par modèle soit un fichier global avec un tri des données en fonction du document.

Pour ces opérations, nous allons utiliser le VBA. Il n'est pas possible d'obtenir un résultat satisfaisant sans utiliser du code.

Pour les différentes solutions proposées dans ce tutoriel, nous allons pour chacune d'entre elle, utiliser un modèle de document qui contiendra un UserForm. C'est ce UserForm qui ira récupérer les données.

Dans tous les cas passés en revue il n'est pas nécessaire de maîtriser le VBA pour modifier ou augmenter la quantité de données.

Vous pouvez n'utiliser qu'une partie de ce tutoriel pour aboutir rapidement à votre document à tiroir.

Dans tous les exemples abordés, les données sont insérées sur l'objet Selection qui représente le point d'insertion et est représenté par le curseur de la souris. L'utilisation d'un signet est aussi possible mais pas abordée.
Par facilité, le UserForm est appelé lors de l'ouverture du document mais il est possible d'appeler ce UserForm en cours d'édition du document en ajoutant par exemple un bouton sur une barre d'outils ou dans la barre d'outils Accès rapide de Word 2007, avec l'ajout d'un bouton dans le ruban de votre document.

2 - Word

L'utilisation de Word comme source de données permet un stockage des données assez simple. Vous avez plusieurs solutions.

- Des paragraphes

- Des tableaux

- D'autres documents

2-A - Les paragraphes

Pour l'utilisation de paragraphes pour le stockage de texte est rudimentaire, nous retiendrons comme format du texte précédé d'un identifiant. Pour l'identifiant, nous avons deux possibilités, soit sa longueur sera toujours la même, soit on le fait suivre d'un caractère spécifique ou d'une combinaison de caractère.

Si nous optons pour une longueur de texte, la récupération de l'identifiant est assez simple, il suffit d'utiliser une fonction texte permettant l'extraction d'une portion de texte.

Dim intP As Integer
Dim stIdentifiant As String

stIdentifiant = Left(ActiveDocument.Paragraphs(intP).Range.Text, 8)

Le plus simple serait de faire un boucle sur tous les paragraphes, en récupérer l'identifiant ainsi que l'index du paragraphe. Avec l'index, il sera plus facile de récupérer le paragraphe.

Prenons un texte avec quatre paragraphes précédés d'un identifiant de 5 lettres.

Cl001 - Les chiens doivent être tenus en laisse
Cl002 - Les chats doivent être stérilisés
Cl003 - Les rats doivent être vaccinés contre la leptospirose
Cl004 - Les écureuils ne peuvent être relâchés dans la nature

Pour permettre un choix facile pour l'utilisateur, nous allons travailler avec un UserForm simple qui contiendra une liste de choix et deux boutons, l'un pour valider la saisie et le second pour fermer le UserForm lorsque le choix sera fait.

Création de notre UserForm :
Alt + F11 pour ouvrir le VBE

A notre projet, nous allons ajouter un UserForm.

Sur ce UserForm, nous allons placer une zone de liste et deux boutons, l'u pour valider le choix et le second pour fermer le UserForm lorsque les choix sont terminés.

Dès que nous avons inséré les contrôles, nous allons en modifier les propriétés par facilité.

Les propriétés des différents objets sont modifiées dans le volet propriétés. Les propriétés affichées correspondent à l'objet sélectionné.

La liste aura comme nom lstChoix possèdera 2 colonnes et la largeur des colonnes sera de 1 cm pour la première et 5 pour la seconde. VBE va changer ces mesures en points.

On fera la même chose pour les boutons, le premier aura comme nom cmdValider et le second cmdFermer et comme étiquette Valider et Fermer.

Après avoir créé notre UserForm, nous allons remplir la liste de choix lors du chargement de ce UF. Pour y parvenir, nous utiliserons l'évènement Initialize.
Dans cette procédure, nous allons parcourir le document pour en récupérer les paragraphes et scinder ces paragraphes en utilisant le caractère "-" et la fonction Split.
Nous allons avoir besoin de deux variables tableaux, une variable document et un entier qui servira pour l'index du paragraphe.

L'étape suivant sera l'affectation du document contenant les paragraphes à l'objet document. J'ai mis ce document dans le répertoire Temp du disque C par facilité.

À l'aide d'une boucle, nous allons récupérer le contenu des paragraphes pour remplir la liste.

Private Sub UserForm_Initialize()
'Déclaration des variables
Dim oDoc As Document
Dim tblListe() As String 'tableau pour le remplissage de la liste
Dim tblTemp() As String 'Tableau temporaire pour la fonction split
Dim intP As Integer 'Entier pour l'index des paragraphes

'Affectation des données aux objets
Set oDoc = Application.Documents.Open("c:\temp\data.docm")

'redimensionnement du tableau en fonction du nombre de paragraphes
'contenus dans le document
ReDim tblListe(oDoc.Paragraphs.Count, 1)
'Boucle sur le paragraphes du document
For intP = 1 To oDoc.Paragraphs.Count
'remplissage du tableau temporaire
tblTemp() = Split(oDoc.Paragraphs(intP).Range.Text, " - ")
'transfert des données du tableau temporaire vers la table de remplissage
tblListe(intP, 0) = tblTemp(0)
tblListe(intP, 1) = tblTemp(1)

Next intP
'transfert des données vers la liste du UserForm
Me.lstChoix.List = tblListe
'Fermeture et libération des objets
oDoc.Close
Set oDoc = Nothing

End Sub

Si nous exécutons le UserForm, le liste se trouve remplie avec les données du document.

Nous allons maintenant afficher le UserForm lors de la création d'un nouveau document basé sur ce modèle. L'évènement que nous allons utiliser est Document_New. Cette procédure sera placée dans le module ThisDocument du modèle.

Private Sub Document_New()
'Affichage du UserForm
UserForm1.Show

End Sub

Si vous avez correctement travaillé, lors de la création d'un nouveau document basé sur ce modèle, vous obtiendrez l''affichage du UserForm avec la liste déroulante remplie.

L'étape suivante sera l'envoi de la donnée dans le document. Nous pourrions utiliser un évènement lié à la liste de choix, mais cette voie ne permet pas à l'utilisateur de changer d'avis lorsque le UserForm est affiché. Nous utiliserons le bouton valider. Le code qui sera associé à ce bouton est très simple, il écrira les données sur l'objet sélection du document représenté par le curseur de la souris.

Private Sub cmdValider_Click()
'envoi de la données dans le document
Selection.TypeText Me.lstChoix.Column(1)

End Sub

On obtient le code de la procédure vide en double cliquant sur le contrôle du UserForm en mode création. Il ne vous reste qu'à la remplir.

La dernière étape est l'ajout de code à notre bouton Fermer pour fermer le UserForm et retourner au document. Le code à utiliser est très simple, il va masquer le UserForm avec la méthode Hide

Private Sub cmdFermer_Click()
Me.Hide
End Sub

Pour augmenter les données de la liste, il suffit d'ajouter des lignes supplémentaires dans le document source et il n'est pas nécessaire de modifier le code du modèle.

2-B - Un tableau

Nous allons utiliser un tableau situé dans un autre document, comme pour l'exemple précédent, nous allons utiliser un UserForm qui chargera les données issues du document. Nous utiliserons des portions de texte plus importantes pouvant contenir plusieurs paragraphes.
Les tableaux sont assez facile d'utilisation, on peut les trier, rapidement ajouter des lignes. La visualisation des données est plus aisée et rapide.

Dans cet exemple, nous n'allons pas charger les données dans le UserForm mais les laisser dans le document et les récupérer juste avant de les injecter dans le document. Nous aurons donc besoin de connaître l'endroit où elles se trouvent.

Le document source contiendra un tableau de deux colonnes, pour chaque ligne du tableau, la première cellule contiendra un identifiant et la seconde les données qui seront utilisées. L'exemple que je vais utiliser pour les données est un extrait du RGPT (Règlement Général sur la Protection du Travail), nous aurons dans la première cellule l'article et dans la seconde le texte du règlement. Ce texte peut comporter plusieurs paragraphes et certains caractères pour la mise en forme comme les tabulations.

Selon que vous utiliserez ou non un titre pour vos colonnes, n'oubliez pas d'en tenir compte pour l'extraction de vos données.

Voilà l'aspect qu'ont les données situées dans un tableau :

Une colonne contenant l'identifiant et une colonne contenant les données.

Je vous propose d'utiliser le même modèle que pour l'exemple précédent, il contient déjà un UserForm, il suffit de simplement changer le nom du modèle.

Nous allons utiliser un nouveau code pour la récupération des données de notre document. Comme nous allons travailler avec des lignes de tableau, nous tiendrons compte de l'index de chaque ligne, la récupération des données en sera facilitée.
Lorsque les données d'un tableau sont récupérées, elles contiennent deux caractères supplémentaires que nous ne souhaitons pas, nous utiliserons une fonction maison pour nettoyer cette chaîne.

Commençons par la fonction de nettoyage, comme ce sont les deux derniers caractères que nous devons éliminer, la solution qui s'impose est l'utilisation de la Fonction Left(). Pour rager un peu notre projet, nous allons ajouter un module qui contiendra notre fonction.

Et pour faire propre, appelons le "Utilitaires".

Function NetText(stToBeCl As String) As String
'Récupération du début de la chaîne
NetText = Left(stToBeCl, Len(stToBeCl) - 2)

End Function

Comment tester votre code ?
En utilisant la fenêtre exécution de l'éditeur, vous pouvez facilement tester des portions ou la totalité de votre code. Il suffit de faire précéder le nom de la fonction ou de la procédure d'un "?".

Le résultat est affiché juste en dessous après avoir pressé la touche Entrée.

Maintenant que nous avons notre fonction de nettoyage, nous allons charger une partie des données du tableau pour remplir notre liste.

Par facilité et portabilité, j'ai placé les documents contenant les données dans le C:\Temp

Si vous avez utilisé une copie de votre premier modèle, le UserForm contient déjà du code. Ce code est à modifier ou à remplacer par celui-ci :

Private Sub UserForm_Initialize()
'Ce code s'exécute lors de l'initialisation du UserForm
'Déclaration des variables
Dim oDoc As Document
Dim oTbl As Table
Dim tblListe() As String 'tableau pour le remplissage de la liste

Dim intR As Integer 'Entier pour l'index des lignes de la table

'Affectation des données aux objets
'Le document
Set oDoc = Application.Documents.Open("c:\temp\datas_table.docm")
'La table
Set oTbl = oDoc.Tables(1)

'redimentionnement du tableau en fonction du nombre de lignes
'de la table contenue dans le document
ReDim tblListe(oTbl.Rows.Count, 1)
tblListe(0, 0) = "Index"
tblListe(0, 1) = "Article"
'Boucle sur le paragraphes du document
For intR = 1 To oTbl.Rows.Count
'transfert des données du tableau temporaire vers la table de remplissage
tblListe(intR, 0) = intR
'Utilisation de la fonction de nettoyage
'Remplissage de la seconde colonne de la liste
tblListe(intR, 1) = NetText(oTbl.Cell(intR, 1).Range.Text)

Next intR
'transfert des données vers la liste du UserForm
Me.lstChoix.List = tblListe
'Fermeture et libération des objets
Set oTbl = Nothing
oDoc.Close
Set oDoc = Nothing

End Sub

Si vous n'avez pas commis d'erreur, lors de l'affichage de votre UserForm, vous devriez avoir ceci :

J'ai volontairement laisse l'index de la ligne dans la liste pour des raisons visuelles. Cette donnée peut-être masquée mais doit être présente.

Si l'index de la ligne n'est pas disponible, pour chaque choix, vous devrez lancer une recherche dans le document contenant les données et quand la donnée est trouvée, récupérer l'index de la ligne pour obtenir les données de la seconde colonne.

Pour l'instant, la valeur qui est renvoyée par le contrôle lstChoix est l'index de la ligne. Il ne nous reste qu'à récupérer le contenu de la table pour l'injecter dans le document. Nous allons utiliser le bouton de commande Valider.

Notre fonction de nettoyage sera à nouveau utilisée pour la récupération des données avant de les injecter dans le document.

Private Sub cmdValider_Click()
Dim oDoc As Document
Dim oTbl As Table
Dim stTemp As String

'Affectation des données aux objets
'Le document
Set oDoc = Application.Documents.Open("c:\temp\datas_table.docm")
'La table
Set oTbl = oDoc.Tables(1)
'envoie de la données dans une variable

stTemp = Me.lstChoix.Column(1) & vbCrLf & NetText(oTbl.Cell(Me.lstChoix, 2).Range.Text) & vbCrLf

'Fermeture et libération des objets
Set oTbl = Nothing
oDoc.Close
Set oDoc = Nothing
'Écriture des données de la variable dans le document
'au point d'insertion
Selection.TypeText stTemp

End Sub

Dans ce code, nous ouvrons une nouvelle fois le document contenant les données pour le stocker dans une variable Document.
Set oDoc = Application.Documents.Open("c:\temp\datas_table.docm")
Pour pouvoir utiliser la table et son contenu en les stockant aussi dans une variable Table. Set oTbl = oDoc.Tables(1) Pour ne pas rencontrer de problème avec ActiveDocument, c'est via une variable que les données sont injectées dans le document.

Le bouton Fermer n'est pas modifié, il sert juste à fermer le UserForm.

3 - Excel

Excel est probablement le logiciel le plus populaire pour le stockage des données et cela même si ce n'est pas le but de cette application.
Même si ça semble évident, les données seront stockées par lignes, une ligne représentant un enregistrement.

Excel limitant le nombre de caractères 32 767 par cellule, vous devez être certain de ne pas dépasser cette taille.

Un fichier Excel ne peut pas être ouvert par plusieurs personnes simultanément.

Pour éviter de recréer un document de toute pièce, nous allons utiliser notre premier document, il contient déjà un UserForm.

À l'heure du recyclage maximum, je ne pouvais faire autrement !

Nous utiliserons les mêmes données que pour l'exercice précédent, un extrait du RGPT.

Voilà une image de l'agencement des données dans la feuille de données.

On retrouve une disposition des données très proche de la disposition des tables Word.

Alors que pour les deux méthodes précédentes, toutes les données se trouvaient dans des documents, pour cet exemple, nous allons devoir utiliser un autre logiciel de la suite Office. Pour pouvoir utiliser les objets Excel, nous allons utiliser dans notre projet sa bibliothèque.

dans le VBE : Outils => Références => Microsoft Excel 14.0 Object Library

Et le choix de la bibliothèque

Cette façon de procéder est le Early Binding, méthode avec laquelle on lie la bibliothèque au projet, elle rend tous les objets de la bibliothèque disponibles pour notre projet.

Dans l'exemple ci-dessus, l'Intellisense (auto complétion du code) est disponible parce que la bibliothèque est liée au projet. L'écriture du code sera facilitée et certaines erreurs pourront être évitées.

Passons à l'écriture de notre code. La première chose à faire est la déclaration des différentes variables objets dans le module du UserForm et les objets seront libérés lors de la fermeture (Action sur le bouton Fermer) du UserForm. De cette manière, ces variables seront disponibles tant que le UserForm sera visible.

Option Explicit
Option Base 0
'Déclaration des variables
Dim xlApp As Excel.Application 'Application Excel pour ouvrir un fichier XLS
Dim xlWb As Excel.Workbook 'Classeur Excel
Dim xlWs As Excel.Worksheet 'Feuille du classeur

Les différentes procédures suivront ces quelques lignes.

Pour la récupération des données, nous avons besoin d'ouvrir le fichier Excel. En même temps que les données, nous allons "indexer" les lignes de notre liste de choix pour qu'elles correspondent aux lignes de notre fichier Excel.
Comme pour les exemples précédents, nous allons charger une partie des données lors de l'initialisation du UserForm.

Private Sub UserForm_Initialize()
'Ce code s'exécute lors de l'initialisation du UserForm
'Déclaration des variables propres à cette procédure
Dim intL As Integer 'Récupération de l'index de la ligne
Dim tblListe() As String 'tableau pour le remplissage de la liste

'Affectation des données aux objets
'Affectation de Excel en créant un nouvelle instance
Set xlApp = New Excel.Application
'Ouverture du fichier
Set xlWb = xlApp.Workbooks.Open("c:\temp\data.xlsm")
'Utilisation de la première feuille
Set xlWs = xlWb.Worksheets(1)
'Boucle pour déterminer le nombre de lignes contenant des
'données dans le fichier Excel
intL = 1
Do Until Len(xlWs.Range(Cells(intL, 1), Cells(intL, 1))) = 0
intL = intL + 1
Loop

'redimensionnement du tableau en fonction du nombre de lignes
'remplies dans le feuille de données
ReDim tblListe(intL, 1)
tblListe(0, 0) = "Index"
tblListe(0, 1) = "Article"
'Boucle sur les cellules de la feuille Excel
intL = 1
Do Until Len(xlWs.Range(Cells(intL, 1), Cells(intL, 1))) = 0
'Index de la ligne
tblListe(intL, 0) = intL
'Contenu de la première colonne de la feuille de données
tblListe(intL, 1) = xlWs.Range(Cells(intL, 1), Cells(intL, 1))
'Debug.Print intL & " --- " &  & " --- " &
intL = intL + 1
Loop
'transfert des données vers la liste du UserForm
Me.lstChoix.List = tblListe
'Fermeture et libération des objets

End Sub

Si vous exécutez votre UserForm, les données seront ajoutées à la liste de choix. Mais dans l'état actuel des choses, vous allez créer une instance d'Excel qui ne sera pas fermée.
Pour fermer et libérer les objets, nous allons utiliser le bouton Fermer.

Private Sub cmdFermer_Click()
'Fermeture du classeur
xlWb.Close
'Libération de l'objet
Set xlWb = Nothing
'Fermeture d'Excel
xlApp.Quit
'Liberation
Set xlApp = Nothing
'Fermeture du UserForm
Me.Hide
End Sub

Nous allons augmenter les fonctionnalités du UserForm par l'utilisation d'un TextBox pour afficher le texte contenu dans la seconde colonne.
Nous allons ajouter un TextBox et lui donner comme nom txtPreview. N'oubliez pas de valider le multiligne.

Nous allons remplir ce contrôle sur l'évènement Click de la liste de choix. Comme nos objets sont disponibles, il suffit de prendre les données.

Private Sub lstChoix_Click()
'Test sur le choix

If lstChoix = "Index" Then
'Si la première ligne st choisie
Me.txtPreview = "Ceci n'est pas un choix valide"
Exit Sub
End If
'Affectation de la donnée au TextBox
Me.txtPreview = xlWs.Range(Cells(lstChoix, 2), Cells(lstChoix, 2))

End Sub

Le résultat :

Pour l'injection du texte dans le document, nous avons maintenant deux possibilités, la première, l'utilisation de la donnée contenue dans le fichier source ou la seconde, l'utilisation du contenu du contrôle txtPreview.

Nous allons utiliser la seconde solution, puisque pour la première, il suffit de simplement utiliser le code de remplissage du txtPreview mais au lieu de l'affecter au contrôle, on l'affecte à la sélection du document actif.

ActiveDocument.Selection = xlWs.Range(Cells(lstChoix, 2), Cells(lstChoix, 2))

Le code qui affectera le contenu du txtPreview n'est pas plus compliqué, mais il va ajouter une possibilité supplémentaire à l'utilisateur qui pourra éventuellement modifier le texte avant de l'envoyer dans le document.
Après validation, le contrôle est vidé de son contenu.

Private Sub cmdValider_Click()
'Écriture dans le document
Selection.TypeText Me.txtPreview
'Vidange du contrôle
Me.txtPreview = ""
End Sub

Comme dans une cellule Excel, il n'y a pas de saut de paragraphe à la fin du texte, vous devrez en ajouter un dans votre code.

Private Sub cmdValider_Click()
'Écriture dans le document
Selection.TypeText Me.txtPreview
Selection.TypeParagraph

'Vidange du contrôle
Me.txtPreview = ""

End Sub

4 - Access

Je pense que c'est la solution la plus aboutie. Si vous possédez Access dans votre version d'Office, c'est Access que vous devez utiliser pour stocker vos données. Comme un fichier Access peut être utilisé simultanément pas plusieurs personnes, son utilisation en réseau est recommandée.
Pour accéder aux données, nous utiliserons du DAO accès aux données avec le DAO

Avec le principe du recyclage, nous allons utiliser notre dernier modèle et notre fichier Excel pour remplir la table de notre base de données.

Pour importer la feuille de données, c'est assez simple, créez une base de données vide dans le répertoire C:\Temp, nommez la data.
L'importation des données de la feuille est assez simple, Access possède un assistant qui fait ça très bien.

Il ne vous reste qu'à vous laisser guider étape par étape et vous obtiendrez une nouvelle table contenant vos données et une clé primaire.
Cette clé primaire est un identifiant unique, exactement comme l'index que nous avions "fabriqué" pour le fichier Excel. Elle va nous servir de la même manière que l'index du fichier Excel.

La première étape sera la récupération des données pour remplir la liste lstChoix de notre UserForm. Comme dans l'exemple avec Excel, nous allons utiliser une bibliothèque dans notre projet, vous devez l'ajouter.

Et choisir la référence Microsoft DAO.

Nous pouvons maintenant utiliser les objets DAO dans notre projet.

Comme pour Excel, nous allons déclarer nos variables au début de notre module et hors de nos procédures pour pouvoir les utiliser dans tout notre UserForm.

Option Explicit
Option Base 0
'Déclaration des variables pour tout le module
Dim oDb As DAO.Database 'Declaration d'un objet DataBase
Dim rs As DAO.Recordset 'Objet RecordSet

Voilà le code que nous allons utiliser pour remplir notre liste de choix.

Private Sub UserForm_Initialize()
'Ce code s'exécute lors de l'initialisation du UserForm
'Déclaration des variables propres à cette procédure
Dim tblListe() As String 'tableau pour le remplissage de la liste

'Affectation de notre DB
Set oDB = DAO.OpenDatabase("C:\temp\data.mdb")
'création d'un objet recordset
'le SQL dans e cas récupère tous les enregistrements de la table
Set rs = oDB.OpenRecordset("SELECT * From tbl_Datas")
'Déplacement sur le dernière enregistrement pour connaître
'la taille de la table
rs.MoveLast
'Dimension de la table
ReDim tblListe(rs.RecordCount, 1)
'Retour sur le premier enregistrement
rs.MoveFirst
'Titre des colonnes
tblListe(0, 0) = "Index"
tblListe(0, 1) = "Article"
'Boucle sur les enregistrements de la table
While Not rs.EOF
'Remplissage du tableau
tblListe(rs.Fields(0).Value, 0) = rs.Fields(0).Value
tblListe(rs.Fields(0).Value, 1) = rs.Fields(1).Value
rs.MoveNext
Wend
'transfert des données vers la liste du UserForm
Me.lstChoix.List = tblListe

End Sub

Si vous exécutez le UserForm, la vitesse d'exécution est supérieure à tous les exemples précédents.

Nous allons permettre à l'utilisateur d'avoir une prévisualisation des données dans le contrôle txtPreview. Pour y parvenir, nous allons utiliser notre RecordSet, mais au lieu d'ouvrir tous les enregistrements, nous n'allons ouvrir que l'enregistrement choisi.
C'est la sentence SQL qui sera modifiée.

Tous les enregistrements

SELECT * FROM tbl_Datas ;

Pour "filtrer" les enregistrements, nous allons ajouter un critère qui sera l'index de l'enregistrement contenu et renvoyé par le contrôle lstChoix.

l'enregistrement choisi

"SELECT * FROM tbl_Datas Where ID = " & Me.lstChoix & ";"

Nous obtiendrons donc ce code :

Private Sub lstChoix_Click()

'Test sur le choix

If lstChoix = "Index" Then
'Si la première ligne st choisie
Me.txtPreview = "Ceci n'est pas un choix valide"
Exit Sub
End If
'Affectation de la donnée au TextBox
Set rs = oDb.OpenRecordset("Select * From tbl_Datas Where Id  = " & Me.lstChoix & ";")
Me.txtPreview = rs.Fields(2).Value
rs.Close

End Sub

Le contrôle txtPreview contient donc les données qui seront envoyées dans les documents. Si l'utilisateur souhaite modifier ces données, il peut le faire dans ce contrôle et ce sont les données modifiées qui seront inscrites dans le document.

Private Sub cmdValider_Click()
'Écriture dans le document
Selection.TypeText Me.txtPreview
Selection.TypeParagraph

'Vidange du contrôle
Me.txtPreview = ""

End Sub

Lors de la fermeture du formulaire, vous devrez fermer et libérer les objets.

Private Sub cmdFermer_Click()
'Fermeture et libération des objets
rs.Close
Set rs = Nothing
oDb.Close
Set oDb = Nothing

Me.Hide
End Sub

5 - Ajout d'images

Pour cette partie, une fois de plus utiliser notre modèle de document. L'image choisie sera envoyée sur un signet situé dans l'en-tête du document.
Pour les images, nous utiliserons un répertoire contenant les images souhaitées et nous les récupèrerons à l'aide de la bibliothèque File Scripting Runtime .

Comme pour les modèles précédents, nous aurons besoin d'une bibliothèque supplémentaire, il suffit de l'ajouter à la liste des références du projet.

Profitons pour supprimer du projet les bibliothèques que nous n'utilisons pas : Microsoft DAO et Microsoft Excel.

Commençons par modifier notre UserForm, supprimons le TextBox et remplaçons-le par une zone Image que nous appellerons imgBox.

C'est dans cette zone que nous afficherons un aperçu de l'image choisie dans la liste.

Les variables objets seront définies en début de module et hors des procédures pour être disponibles dans tous le UserForm.

Option Explicit
Option Base 0
'Déclaration des variables pour tout le module
Dim oFSO As FileSystemObject
Dim oFol As Folder
Dim oFil As File

Lors du chargement du UserForm, une boucle sera exécutée sur tous les fichiers du répertoires pour en récupérer le nom.

Private Sub UserForm_Initialize()
'Ce code s'exécute lors de l'initialisation du UserForm
'Déclaration des variables propres à cette procédure
Dim tblListe() As String 'tableau pour le remplissage de la liste
Dim intF As Integer

Set oFSO = New FileSystemObject
Set oFol = oFSO.GetFolder("c:\temp\images")
ReDim tblListe(oFol.Files.Count)
intF = 1
tblListe(0) = "Fichier"

'Boucle sur les fichiers du répertoire
For Each oFil In oFol.Files
tblListe(intF) = oFil.Name
intF = intF + 1
Next oFil

'transfert des données vers la liste du UserForm
Me.lstChoix.List = tblListe

End Sub

Les fichiers seront affichés dans la liste de choix.
Nous allons maintenant sur l'évènement Clic de la liste de choix afficher un aperçu de l'image dans le contrôle image que nous avons ajouté au UserForm.

Private Sub lstChoix_Click()
'Test de contrôle de choix
If Me.lstChoix = "Image" Then
MsgBox "Ce choix n'est pas valide !"
Exit Sub
End If
'Affichage de l'image dans la zone
Me.imgBox.Picture = LoadPicture("C:\temp\images\" & Me.lstChoix)
'Mode d'affichage pour tout afficher
Me.imgBox.PictureSizeMode = fmPictureSizeModeStretch

End Sub

À la méthode LoadPicture, nous avons ajouté le chemin du fichier qui n'a pas été extrait.
Pour avoir un affichage complet de l'image, nous utilisons : Me.imgBox.PictureSizeMode = fmPictureSizeModeStretch.
L'envoi de l'image dans le document se fait sur un signet "S1" qui sera sélectionné par le code juste avant.

Private Sub cmdValider_Click()
'Sélection du signet
ActiveDocument.Bookmarks("S1").Select
'Ajout de l'image
Selection.InlineShapes.AddPicture "c:\temp\images\" & Me.lstChoix

End Sub

Les images peuvent être ajoutées dans un champ IncludePicture, soit ce champ existe, soit vous l'ajoutez.
Dans le cas où le champ existe, nous allons tester le champ pour déterminer si c'est bien un champ IncludePicture qui renvoie le type 67.
En plus du type, fous devez spécifier l'endroit où se trouve le champ, si vous souhaitez l'atteindre alors qu'il est dans l'en-tête du document, vous devez utiliser cet emplacement.
En supposant que ce champ soit le premier.

Private Sub cmdValider_Click()
'Déclaration d'une variable champ
Dim myFld As Field
'Affectation d'un objet à la variable
Set myFld = ActiveDocument.Sections(1).Headers(wdHeaderFooterPrimary).Range.Fields(1)
'Test sur le champ
If myFld.Type = 67 Then
'Modification du contenu du champ
'les \ doivent être doublés !
myFld.Code.Text = "INCLUDEPICTURE " & Chr(34) & "C:\\Temp\\images\\" & Me.lstChoix & Chr(34)
End If
'Mise à jour du champ
myFld.Update
'Libération
Set myFld = Nothing

End Sub

Sur la fermeture du document, on libère les objets.

Private Sub cmdFermer_Click()
Set oFol = Nothing
Set oFSO = Nothing
Me.Hide
End Sub

6 - Liens utiles

Débuter en VBA
Débuter en VBA pour Word
Les tableaux en VBA
L'utilisation du DAO
L'utilisation du File System Object
Les champs et leur utilisation

Les exemples de cet article

7 - Conclusions et Remerciements

Toutes les possibilités n'ont pas été explorées, mais les bases ont été jetées pour vous permettre l'utilisation de données externes pour la réalisation d'un document.

Créer un document à tiroir

Auteur

Olivier Lebeau