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
Function
II-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
Function
III. fParamètres, le formulaire qui permet de piloter la manœuvre ▲
À l'ouverture, il se présente comme ceci :
![Image non disponible](./images/M1453.jpg)
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 :
![Image non disponible](./images/M1474.jpg)
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.