I. L'idée▲
On confectionne d'abord un document type dans lequel les portions variables à personnaliser sont représentées par des symboles précédés de « |* » et suivi de « *| », comme ceci :
D'autre part, on a le formulaire fParametres qui permet de rechercher ce document type :
Quand l'utilisateur a choisi, le formulaire se présente ainsi :
L'utilisateur complète chaque champ orange avec la valeur correspondant au symbole, par exemple :
et un clic sur le bouton
ouvre ce document :
L'utilisateur reçoit alors la main sur Word pour apporter les retouches éventuelles.
II. Une fonction pour trouver les symboles contenus dans un fichier Word (utilisation des expressions régulières)▲
![]() |
Ces fonctions ont été écrites par Arkham46. |
Note d'Arkham46
J'ai tout mis en late binding (Object et createObject au lieu de typer les variables et d'ajouter les références), ça évite bien des soucis lors de l'exécution sur d'autres PC.
II-A. getTagInContent() - une fonction pour trouver les tags dans un contenu texte quelconque▲
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
Public Function getTagInContent(pContent As String)
Dim oReg As Object ' VBScript_RegExp_55.RegExp
Dim oResult As Object ' IMatchCollection
Dim oTag As Object
Dim sTag As String
Dim lRetColl As Collection
Set lRetColl = New Collection
Set oReg = CreateObject("VBScript.RegExp")
oReg.Pattern = "\|\*(.+?)\*\|"
oReg.MultiLine = True
oReg.Global = True
If oReg.Test(pContent) Then
Set oResult = oReg.Execute(pContent)
For Each oTag In oResult
sTag = oTag.subMatches(0)
On Error Resume Next
lRetColl.Add sTag, sTag
On Error GoTo 0
Next oTag
Else
MsgBox "Il n'y a pas de correspondance dans le document"
End If
Set oReg = Nothing
' Et on retourne la collection
Set getTagInContent = lRetColl
End Function
|
N° d'instruction |
Commentaires du code |
|
9 |
Nous recherchons les chaînes de caractères de la forme |*Quelque chose*| qui se trouvent dans tout le texte. ![]()
« Quelque chose », dans les faits, c'est n'importe quel caractère en groupe de n'importe quelle longueur.
![]() Exprimé ainsi, nous allons récupérer tout le texte compris entre le premier « |* » et le dernier « *| ». Pour dire : arrêtez-vous chaque fois au premier « *| » rencontré, ou en d'autres mots, pour dire « relevez les plus petites correspondances », la syntaxe est d'ajouter un point d'interrogation (« ? »). Finalement : ![]() |
|
10 |
Pour activer la recherche sur plusieurs lignes à la fois. |
|
11 |
Pour préciser que la recherche porte sur toutes les occurrences. |
|
12 |
On vérifie qu'il existe des correspondances. |
|
13 |
Si oui, on déclenche la recherche. |
|
14-19 |
On parcourt les résultats de la recherche. |
|
21 |
Message pour signaler qu'il n'y a pas de correspondance. |
|
25 |
On affecte la collection des symboles à la fonction. |
Si vous voulez presque tout savoir au sujet de l'utilisation des expressions régulières (regex) avec Access, voyez le tutoriel de cafeine : Les Expressions Rationnelles appliquées en VBA Access.
II-B. Une fonction pour appeler getTagInContent() avec un document Word▲
Public Function getTagInWord(poDoc As Object) ' Word.Document
Set getTagInWord = getTagInContent(poDoc.Content)
End FunctionII-C. Un exemple d'utilisation▲
Public Function Test()
Dim oWord As Object ' Word.Application
Dim oDoc As Object ' Word.Document
Dim oTagColl As Collection
Dim vTag As Variant
Set oWord = CreateObject("Word.Application")
oWord.Visible = True
Set oDoc = oWord.Documents.Open(CurrentProject.Path & "\doc1.docx", , True) ' doc1.docx est ici logé dans le même répertoire que l'appli
Set oTagColl = getTagInWord(oDoc)
oWord.Quit False
Set oDoc = Nothing
Set oWord = Nothing
For Each vTag In oTagColl
Debug.Print vTag
Next vTag
End FunctionIII. fParamètres, le formulaire qui permet de piloter la manœuvre ▲
À l'ouverture, il se présente comme ceci :

car il n'a pas de source et sa section Détail est invisible.
Quand l'utilisateur clique sur le bouton
, le code suivant se déclenche :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
Private Sub BtChoisir_Click()
Dim oWord As Object ' Word.Application
Dim oDoc As Object ' Word.Document
Dim oTagColl As Collection
Dim vTag As Variant
Set oWord = CreateObject("Word.Application")
Me.txtCheminType = ChoisirUnFichier(Me.hwnd, "Parcourir", 1, "Word", "docx")
Me.txtCheminPerso = Left(Me.txtCheminType, Len(Me.txtCheminType) - 5) & "_PERSO.docx"
Set oWord = CreateObject("Word.Application")
With oWord
.Visible = True
Set oDoc = .Documents.Open("""" & Me.txtCheminType & """", , True)
Set oTagColl = getTagInWord(oDoc)
.Quit
End With
Set oDoc = Nothing
Set oWord = Nothing
'Vidanger et repeupler la table
DoCmd.SetWarnings False
DoCmd.RunSQL "Delete * from tParametres;"
For Each vTag In oTagColl
DoCmd.RunSQL "INSERT INTO tParametres ( Symbole ) SELECT """ & vTag & """ AS Expr1;"
Next
DoCmd.SetWarnings True
Me.RecordSource = "tParametres"
Me.Section("Détail").Visible = True
Me.txtCheminPerso.Visible = True
Me.etqCheminPerso.Visible = True
Me.txtNbreSymboles.Visible = True
End Sub
|
N° d'instruction |
Commentaires du code |
|
7 |
On déclenche l'ouverture d'une fenêtre de sélection de fichier et on loge le chemin dans le champ txtCheminType. |
|
8 |
On construit le chemin qui sera affecté au document personnalisé (l'utilisateur pourra éventuellement le modifier). |
|
9-12 |
Ouverture du .docx choisi à l'instruction 7. |
|
13 |
Collecte des symboles contenus dans le document. |
|
14-17 |
Fermeture de la session Word. |
|
19-20 |
On vidange le contenu (éventuel) de la table tParametres. |
|
21-24 |
On lance une boucle pour peupler la table tParametres : un enregistrement pour chaque tag trouvé dans le document. |
|
25 |
On affecte tParametres comme source du formulaire. |
|
26-29 |
On rend visibles les contrôles cachés à l'origine dans le formulaire. |
Ce qui donne ceci pour notre exemple :
Au fur et à mesure que l'utilisateur saisira la valeur du symbole, le champ txtValeur passera au vert (mise en forme conditionnelle) :
Notez qu'il est possible d'encoder une valeur sur plusieurs lignes : il suffit de saisir <CTRL + ENTER> pour passer à la ligne :

Quand tout est complet, un clic sur le bouton
déclenche ce code :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
Private Sub btCreerDoc_Click()
Dim oWord As Object ' Word.Application
Dim sNomDoc As String
Dim rs As DAO.Recordset
On Error GoTo GestionErreurs
Me.Refresh
FileCopy Me.txtCheminType, Me.txtCheminPerso
'Créer un RecordSet avec tParametres
Set rs = CurrentDb.OpenRecordset("tParametres")
rs.MoveFirst
'Démarrer Word
Set oWord = CreateObject("Word.Application")
With oWord
.Visible = True
'Ouvrir le document à personnaliser
.Documents.Open """" & Me.txtCheminPerso & """"
'Remplacer le symbole par sa valeur
Do While Not rs.EOF
.Selection.Find.Execute FindText:="|*" & rs("Symbole") & "*|", _
ReplaceWith:=" " & rs("Valeur"), Replace:=2 '=wdReplaceAll
rs.MoveNext
Loop
'Sauvegarder
.ActiveDocument.Save
'Fermer et libérer les objets
.Quit
End With
Set oWord = Nothing
rs.Close
Set rs = Nothing
' Ouvrir le doc perso
Call Ouvrir_fichier(Me.txtCheminPerso)
GestionErreurs:
Select Case err.Number
Case 0 ' pas d'erreur
Case Else
MsgBox "Erreur dans Sub btCreerDoc_Click" & Chr(13) & Chr(10) _
& "N° " & err.Number & " " & err.Description & "."
Set oWord = Nothing
rs.Close
Set rs = Nothing
End Select
End Sub
|
N° d'instruction |
Commentaires du code |
|
6 |
Pour s'assurer que la dernière intervention est enregistrée. |
|
7 |
On prend une copie du document type original. |
|
9-10 |
On crée un recordset de la table tParametres pour accéder à chacun des enregistrements. |
|
12-16 |
On crée une session Word et on ouvre le document à personnaliser. |
|
18-22 |
On lance une boucle pour lire chaque enregistrement du recordset et remplacer le symbole par sa valeur. |
|
24-28 |
On sauvegarde le document personnalisé et on clôt la session Word. |
|
29-30 |
On referme le recorset. |
|
32 |
On affiche le document personnalisé. |
IV. Une variante pour la recherche des symboles : Split() au lieu des regex▲
Le code associé au clic de
devient :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
Private Sub BtChoisir_Click()
Dim oWord As Object ' Word.Application
Dim oDoc As Object ' Word.Document
Dim sDocType As String
Dim sTab() As String
Dim i As Integer
Dim iPos As Integer
Dim sTexteType As String
'Choisir le fichier type
sDocType = ChoisirUnFichier(Application.hWndAccessApp, "Parcourir", 1, "Fichier Word", "docx")
'Afficher dans le formulaire
Me.txtCheminType = sDocType
'Proposer un chemin pour le fichier personnalisé
Me.txtCheminPerso = Left(Me.txtCheminType, Len(Me.txtCheminType) - 5) & "_PERSO.docx"
'Ouvrir Word pour lire le document type
Set oWord = CreateObject("Word.Application")
oWord.Visible = True
Set oDoc = oWord.Documents.Open(sDocType, , True)
sTexteType = oDoc.content
'Refermer Word
oWord.Quit False
Set oDoc = Nothing
Set oWord = Nothing
'Isoler les parties du texte qui commencent par la balise de début |*
sTab = Split(sTexteType, "|*")
'Vidanger la table tParametres
DoCmd.SetWarnings False
DoCmd.RunSQL "Delete * from tParametres;"
'Repeupler la table tParametres
For i = 1 To UBound(sTab)
iPos = InStr(sTab(i), "*|")
DoCmd.RunSQL "INSERT INTO tParametres ( Symbole ) SELECT """ & Left(sTab(i), iPos - 1) & """ AS Expr1;"
Next i
DoCmd.SetWarnings True
'Afficher le formulaire en entier
Me.RecordSource = "tParametres"
Me.Section("Détail").Visible = True
Me.txtCheminPerso.Visible = True
Me.etqCheminPerso.Visible = True
Me.txtNbreSymboles.Visible = True
End Sub
|
N° d'instruction |
Commentaires du code |
|
1-18 |
Ces instructions sont semblables à celles décrites au chapitre III. |
|
19 |
On loge le contenu du .docx dans la variable sTexteType. |
|
21-23 |
On ferme la session Word. |
|
25 |
On applique la fonction Split() à sTexteType avec comme délimiteur la balise début « |* » du symbole. |
|
30-33 |
On lance une boucle pour lire à partir de la deuxième colonne [stab(1)] jusqu'à la dernière. ![]() |
|
34-Fin |
Ces instructions sont semblables à celles décrites au chapitre III. |
V. Téléchargement▲
Deux bases (version regex et version Split) peuvent être téléchargées ici.
N.B. Le code a été adapté pour le rendre compatible avec les versions 64 bits. Voyez le tutoriel d'Arkham46 à ce sujet : Développer avec Office 64 bits.
VI. Remerciements▲
Merci à Arkham46, chrtophe, Loufab et User pour leur contribution à la réalisation de cet article.
Merci à jacques_jean pour la relecture orthographique.



















