1. Introduction▲
Lorsque l'on souhaite faire une recherche dans le contenu d'un document Word, la première idée qui nous traverse l'esprit est de faire une boucle sur tous les objets du document pour trouver celui qui correspond à nos critères. Cette façon de faire n'est à utiliser qu'en dernier recours. Elle est très lente et très gourmande en ressource.
Word possède une fonction de recherche et remplacement intégrée très performante qui peut vous faire gagner du temps, c'est cette fonction que nous allons aborder dans ce tutoriel.
Que vous l'utilisiez pour effectuer une recherche ou un remplacement, c'est toujours la même fonction, seuls les arguments diffèrent.
Elle correspond à la boîte de dialogue Rechercher Remplacer de l'interface graphique. Vous pouvez trouver un tutoriel détaillé sur cette fonction ici : Rechercher Remplacer
Elle peut être utilisée indifféremment sur un objet Selection ou sur objet Range. Dans les exemples, je n'utiliserai cette fonction que sur des objets Selection qui englobent la majorité des besoins.
Un objet Range représente une portion du document qui peut être l'intégralité du document tandis qu'un objet Selection représente le texte que l'on peut sélectionner à l'aide de la souris.
Pour les exemples, j'ai simplement utilisé un EasterEgg afin de remplir mes pages de textes. Si vous n'en avez jamais utilisé, c'est très simple, vous saisissez au clavier : =lorem(10,10) suivi de Entrée, votre page sera remplie par 10 paragraphes et de 10 phrases par paragraphe contenant Lorem ipsum...
2. Rechercher - Remplacer▲
L'objet Find peut être utilisé avec un objet Range ou un objet Selection, il permet de faire une recherche et d'effectuer le cas échéant un remplacement.
Selection.Find.Execute
FindText:=
"moi"
Dim
myR As
Range
Set
myR =
ActiveDocument.StoryRanges
(
wdMainTextStory)
myR.Find.Execute
FindText:=
"moi"
Que ce soit sur une plage ou sur une sélection, l'utilisation reste la même. Cependant, l'utilisation sur une plage ne permet pas de manipuler le résultat de la recherche, si vous souhaitez manipuler le résultat de la recherche, vous devez l'utiliser sur un objet Selection.
Cette fonction de recherche n'est pas la meilleure solution pour atteindre un point précis de votre document. Pour atteindre un point précis, je préfère utiliser la fonction GoTo ou encore les signets ("Bookmarks") qui sont plus facile à manipuler.
Nous allons l'aborder sous deux utilisations différentes, l'une en ligne et l'autre en bloc. Les résultats obtenus sont identiques, seules les possibilités d'utilisation et l'écriture du code diffèrent.
2-A. En Ligne▲
Pour l'utilisation en ligne, les arguments sont utilisés sur la même ligne que la fonction.
Selection.Find.Execute
FindText:=
"moi"
, Forward:=
True
2-B. En Bloc▲
Pour l'utilisation en bloc, il est plus facile de faire appel à l'instruction With, qui permet l'application d'une série d'instructions à un objet.
With
Selection.Find
.Text
=
"moi"
.Forward
=
True
End
With
Cette écriture est équivalente à :
Selection.Find.Text
=
"moi"
Selection.Find.Forward
=
True
Il est plus facile d'écrire et de lire le code lorsque l'on utilise l'instruction "With [...] End With".
2-C. Propriétés▲
Les propriétés détaillées dans ce tutoriel ne sont pas exhaustives. Seules les plus courantes sont détaillées.
Certaines options sont incompatibles entre elles, par exemple, rechercher en tenant compte de la casse est incompatible avec une recherche sur toutes les formes d'un mot.
Certaines propriétés sont persistantes entre deux utilisations, c'est le cas de la recherche pour toutes les formes d'un mot, si vous passez cette propriété à True, elle le restera pour toutes les autres utilisations. Vous devrez pour ne pas fausser le résultat, modifier la valeur de cette propriété. C'est le cas pour la recherche sur toutes les formes d'un mot.
2-C-1. Font▲
Permet de spécifier la police de caractères à rechercher. Comme c'est l'objet Font qui est utilisé, toutes les propriétés de cette police peuvent être utilisées.
Selection.HomeKey
unit:=
wdStory
With
Selection.Find
.ClearFormatting
With
.Font
.Bold
=
True
.Name
=
"Arial"
End
With
.Forward
=
True
.Text
=
"auctor"
.Execute
Debug.Print
.Found
End
With
Dans ce code, nous recherchons le mot "auctor" qui est écrit en gras et en Arial. Le Debug.Print devant la propriété .Found permet d'afficher le résultat de la recherche dans la fenêtre d'exécution.
Le Debug.Print inséré devant la méthode .Execute aurait eu le même résultat. La seule différence est que .Found peut être utilisé un grand nombre de fois, alors que .Execute lancera la recherche chaque fois qu'elle sera appelée.
2-C-2. Format▲
Cette propriété spécifie si le format du texte doit être pris en compte pour exécuter la recherche. Si l'on prend l'exemple précédent, cette propriété doit être placée après le .Font, placée avant, elle n'aura aucun effet.
Si elle est utilisée avec une valeur False, le format ne sera pas pris en compte.
Selection.HomeKey
unit:=
wdStory
With
Selection.Find
.ClearFormatting
With
.Font
.Bold
=
True
.Name
=
"Arial"
End
With
.Format
=
True
.Forward
=
True
.Text
=
"auctor"
.Execute
Debug.Print
.Found
End
With
Elle est surtout intéressante si vous souhaitez dialoguer avec l'utilisateur pour prendre ses choix en compte.
2-C-3. Forward▲
Cette propriété indique à la fonction si la recherche doit se faire du début à la fin du document ou inversement. La valeur par défaut est True.
With
Selection.Find
.Forward
=
True
.Text
=
"auctor"
.Execute
End
With
Si vous souhaitez commencer la recherche par le début du document, vous devrez insérer :
Selection.HomeKey Unit:=wdStory
2-C-4. Found▲
Cette propriété est très importante si vous souhaitez utiliser le résultat de votre recherche. C'est le cas si vous effectuez une boucle basée sur ce résultat.
With
Selection.Find
.ClearFormatting
.Forward
=
True
.Text
=
"auctor"
.Execute
Debug.Print
.Found
End
With
Si la recherche est fructueuse, vous aurez l'affichage True dans la fenêtre d'exécution (Debug.Print .Found).
2-C-5. Highlight▲
Permet de rechercher un texte surligné lors qu'elle est à True.
With
Selection.Find
.ClearFormatting
.Highlight
=
True
'Recherche d'un texte surligné
.Forward
=
True
.Text
=
"auctor"
.Execute
Debug.Print
.Found
End
With
Dans l'exemple ci-dessus, c'est ce mot surligné en rouge qui sera trouvé par la recherche.
2-C-6. IgnorePunct▲
Cette propriété lorsqu'elle est True permet d'ignorer la ponctuation dans une recherche. Si le texte recherché se trouve dans le document mais séparé par un signe de ponctuation, il sera trouvé.
With
Selection.Find
.ClearFormatting
.IgnorePunct
=
True
.Forward
=
True
.Text
=
"sapien auctor"
.Execute
Debug.Print
.Found
End
With
Dans l'exemple ci-dessus, les textes suivants seront trouvés par la recherche : "sapien auctor" ainsi que "sapien. auctor", bien que ces deux mots soient séparés dans le second cas par un signe de ponctuation.
2-C-7. IgnoreSpace▲
Cette propriété permet de rechercher des expressions dans un document, même si elles contiennent un ou plusieurs espaces consécutifs.
With
Selection.Find
.ClearFormatting
.IgnoreSpace
=
True
.Forward
=
True
.Text
=
"sapienauctor"
.Execute
Debug.Print
.Found
End
With
Dans l'exemple ci-dessus, le texte suivant sera trouvé par la recherche : "sapien auctor".
2-C-8. LanguageID▲
Permet de limiter la recherche à une langue. Cette propriété prend comme argument une constante wdLanguageId.
With
Selection.Find
.ClearFormatting
.LanguageId
=
wdBelgianDutch
.Forward
=
True
.Text
=
"sapienauctor"
.Execute
Debug.Print
.Found
End
With
Pour certaines langues, il est important d'identifier clairement la langue d'édition. Pour la Belgique, nous avons wdBelgianDutch et wdBelgianFrench qui sont tous deux différents de wdDutch et wdFrench.
2-C-9. MatchAllWordForms▲
Propriété très intéressante. Elle permet de trouver toutes les formes d'un même mot. Prenons l'exemple de cheval qui au pluriel devient chevaux. Si cette propriété est utilisée, lors de la recherche de "cheval", "chevaux" sera également trouvé.
With
Selection.Find
.ClearFormatting
.MatchAllWordForms
=
True
.Forward
=
True
.Text
=
"cheval"
.Execute
Debug.Print
.Found
End
With
C'est valable pour les pluriels, les formes conjuguées d'un verbe, si vous recherchez "être", vous trouverez toutes ses formes conjuguées : "suis", "es"\x{0085}
Dans l'interface graphique il est précisé que cette option ne fonctionne que pour la langue anglaise, mais il n'en est rien, elle fonctionne aussi en français, mais pas efficacement.
Alors que cette propriété fonctionne très bien pour l'anglais, ses résultats sont très mitigés pour la langue française.
2-C-10. MatchCase▲
Cette propriété permet la distinction entre les majuscules et les minuscules.
With
Selection.Find
.ClearFormatting
.MatchCase
=
True
.Forward
=
True
.Text
=
"Cheval"
.Execute
Debug.Print
.Found
End
With
Dans cet exemple, seul Cheval écrit avec une majuscule sera trouvé.
2-C-11. MatchPhrase▲
Cette propriété permet de retrouver une phrase en omettant les signes de ponctuation, les espaces...
With
Selection.Find
.ClearFormatting
.MatchPhrase
=
True
.Forward
=
True
.Text
=
"un animal qui appartient"
.Execute
Debug.Print
.Found
End
With
Dans l'exemple ci-dessus, votre recherche aboutira aussi pour "un animal, qui appartient".
2-C-12. MatchSoundsLike▲
La traduction de cette propriété est "sonne comme", ce qui signifie que l'on va retrouver les homophones du texte.
With
Selection.Find
.ClearFormatting
.MatchSoundsLike
=
True
.Forward
=
True
.Text
=
"home"
.Execute
Debug.Print
.Found
End
With
Dans la phrase "Cet homme habite ce home", seront trouvés "homme" et "home".
Dans l'interface graphique il est précisé que cette option ne fonctionne que pour la langue anglaise, mais il n'en est rien, elle fonctionne aussi en français, mais les résultats sont assez décevant pour le français.
2-C-13. MatchWholeWord▲
Cette option va limiter la recherche au mot entier, les portions de mots seront ignorées.
With
Selection.Find
.ClearFormatting
.MatchWholeWord
=
True
.Forward
=
True
.Text
=
"hom"
.Execute
Debug.Print
.Found
End
With
Dans la phrase "Cet homme habite ce home", la recherche sera infructueuse.
2-C-14. MatchWildcards▲
Si vous souhaitez utiliser des caractères génériques dans vos recherches, cette propriété doit être True.
Le plus connu de ces caractères génériques est l'étoile "*". Ce caractère représente, lorsqu'il est utilisé, un ou plusieurs caractères.
Si vous utilisez pour votre recherche "i*m", vous obtiendrez comme résultat : ipsum; icies, purus lectus m\x{0085} En fait, toutes les combinaisons possibles dans votre document commençant par un "i" et se terminant par un "m", que ces lettres soient ou non dans un même mot. Au point que si vous prenez la première et la dernière lettre de votre texte, vous aurez un résultat contenant tout votre texte.
With
Selection.Find
.Text
=
"i*m"
.Forward
=
True
.MatchWildcards
=
True
.Execute
End
With
Si cette propriété n'est pas True, pour la même recherche, les seuls résultats qui seront fructueux seront les mots de trois lettres suivants : "i*m".
2-C-15. NoProofing▲
Cette propriété, lorsqu'elle est True, ignore dans la recherche les mots trouvés fautifs par le vérificateur d'orthographe ou de grammaire.
With
Selection.Find
.Text
=
"i*m"
.Forward
=
True
.NoProofing
=
True
.Execute
End
With
2-C-16. ParagraphFormat▲
Permet de faire une recherche sur des propriétés précises d'un paragraphe comme son niveau, son espacement\x{0085}
With
Selection.Find
.Forward
=
True
.ParagraphFormat.OutlineLevel
=
wdOutlineLevel3 'Recherche sur un niveau 3
.Execute
End
With
Si vous exécutez une recherche sur un format de paragraphe, la propriété .Text peut être omise.
2-C-17. Replacement▲
Cette propriété permet, lorsqu'elle est utilisée, de remplacer le mot recherché par celui qui lui est passé en argument. Cette propriété peut en recevoir d'autres en argument.
Si vous souhaitez que la police du mot trouvé change, c'est en argument que vous devez le spécifier.
With
Selection.Find
.Text
=
"Mon texte à chercher"
.Replacment.Text
=
"Mon texte de remplacement"
.ClearFormating
.Execute
End
With
Si dans votre remplacement, vous souhaitez modifier le format du texte, le surligner en rouge, c'est avec cette propriété que vous devez le faire.
2-C-18. Style▲
Style permet de faire une recherche sur une portion de texte avec un style précis.
With
Selection.Find
.Text
=
"auctor"
.Style
=
"Normal"
.Forward
=
True
.NoProofing
=
True
.Execute
End
With
2-C-19. Text▲
Cette propriété reçoit comme argument le texte qui sera recherché.
With
Selection.Find
.Text
=
"auctor"
.Forward
=
True
.NoProofing
=
True
.Execute
End
With
2-C-20. Wrap▲
Cette propriété permet de définir si la recherche n'a pas commencé au début du document, si elle doit reprendre dès le début quand la fin du texte est atteinte.
.Wrap
=
wdFindStop
Cette propriété peut prendre trois valeurs en argument wdFindStop, wdFindAsk et wdFindcontinue qui auront comme résultat l'arrêt à la fin du document, une demande à l'utilisateur ou continuer depuis le début.
2-D. Méthodes▲
Comme pour les propriétés, la liste des méthodes n'est pas exhaustive, seules deux méthodes sont abordées.
Si vous souhaitez lancer la recherche par le début du document, vous devez déplacer la sélection vers le début de votre document avec :
Selection.HomeKey Unit:=wdStory
2-D-1. ClearFormatting▲
Cette méthode est utilisée pour supprimer le formatage du texte de la recherche ou du remplacement.
Selection.HomeKey
unit:=
wdStory
With
Selection.Find
.ClearFormatting
With
.Font
.Bold
=
True
.Name
=
"Arial"
End
With
.Forward
=
True
.Text
=
"auctor"
.Execute
Debug.Print
.Found
End
With
Dans l'exemple ci-dessus, nous cherchons un texte qui serait écrit avec la police de caractère Arial.
Si nous lançons une seconde recherche :
Selection.HomeKey
unit:=
wdStory
With
Selection.Find
.ClearFormatting
With
.Font
.Italic
=
True
End
With
.Forward
=
True
.Text
=
"auctor"
.Execute
Debug.Print
.Found
End
With
La recherche ne sera fructueuse que pour le mot "auctor" qui sera écrit en Arial gras et italique. Les paramètres de formatage de la recherche précédente restent en "mémoire" et faussent le résultat. En utilisant .ClearFormatting, vous "videz la mémoire".
Cette méthode doit être utilisée tant pour la recherche que pour le remplacement.
With
Selection.Find
.ClearFormatting
.Replacement.ClearFormatting
End
With
&
#8230
;.
&
#8230
;.
&
#8230
;.
2-D-2. Execute▲
Cette méthode est la plus importante. Sous Word 2010 et 2007 on retrouve une méthode Execute2007 qui est semblable à la méthode Execute.
Elle va exécuter la recherche demandée. Cette méthode renvoie True si la recherche est couronnée de succès. Avec cette méthode, vous pouvez passer directement les arguments à la fonction.
Sub
RechercherUnMot
(
)
MsgBox
Selection.Find.Execute
(
FindText:=
"Olivier"
)
End
Sub
Si votre texte contient le mot "Olivier", vous aurez une boîte de message avec comme texte "True".
Elle peut prendre un argument qui est important dans le cas d'un remplacement.
With
Selection.Find
.Text
=
"Moi"
.Replacement.Text
=
"Toi"
.Execute
Replace
:=
wdReplaceAll
End
With
En argument, si vous souhaitez faire un remplacement, vous devrez utiliser : Replace. Elle peut recevoir trois valeurs, qui sont des constantes : wdReplaceAll; wdReplaceOne et wdReplaceNone.
3. En pratique▲
Nous allons simplement couvrir quelques possibilités concernant l'utilisation de la méthode de recherche.
3-A. Recherche et remplacement d'une liste de mots▲
La recherche d'une liste de mots va se faire sur la base d'une boucle et sur le résultat renvoyé par la recherche.
Dans cet exemple, la liste des mots sera contenue dans un tableau Word composé de deux colonnes, la première contenant les mots à rechercher et la seconde contenant les mots de remplacement.
La fonction située ci-dessous sert à supprimer les deux caractères présents lorsque l'on extrait du texte d'une cellule.
Function
NetText
(
stTemp As
String
) As
String
'-------------------------------------------------
'Fonction de nettoyage
'Supprime les deux caractères de fin de cellule
'-------------------------------------------------
NetText =
Left
(
stTemp, Len
(
stTemp) -
2
)
End
Function
Nous l'utiliserons dans notre procédure pour obtenir les mots recherchés et les mots de remplacement.
3-A-1. La procédure de recherche et remplacement.▲
Dans un premier temps, nous allons ouvrir les deux documents, le premier contenant la liste des mots à rechercher (tableau à deux colonnes) et le second étant celui dans lequel nous souhaitons faire les remplacements.
Pour ouvrir les documents, au lieu de les mettre en "dur" dans le code, nous allons utiliser un objet "FileDialog". Cet objet permet de sélectionner un répertoire ou un fichier. Dans notre exemple, nous allons l'utiliser pour les fichiers. Ce choix s'obtient par l'argument passé lors de l'affectation.
Set
oDlg =
Application.FileDialog
(
msoFileDialogFilePicker)
Pour afficher cette boîte de dialogue, nous allons utiliser sa méthode ".Show".
Comme il s'agit d'un échange avec l'utilisateur, nous avons la possibilité de choisir un titre pour la boîte de dialogue et nous n'avons besoin que d'un seul fichier.
With
oDlg
'Pour un seul fichier la valeur sera False
.AllowMultiSelect
=
False
.Title
=
"Document contenant le tableau"
.Show
End
With
Cet objet va renvoyer le nom du fichier choisi par l'utilisateur. Comme il n'y a qu'un seul fichier, nous récupérons le premier élément.
oDlg.SelectedItems
(
1
)
Il n'est pas nécessaire de passer par une variable, nous pouvons directement utiliser le résultat en argument.
Que ce soit pour le document source ou le document cible, la méthode d'ouverture du document est toujours la même.
Set
oDocSource =
Documents.Open
(
oDlg.SelectedItems
(
1
))
Il ne nous reste que la boucle sur les éléments du tableau qui seront utilisés pour la recherche et le remplacement. On affecte le premier tableau du document source à la variable tableau pour ensuite faire une boucle sur les lignes du tableau. Dans notre cas, c'est assez simple, la première colonne contient le mot à rechercher et la seconde, le mot de remplacement.
Set
oTbl =
oDocSource.Tables
(
1
)
'Boucle sur les cellules de la table
For
Each
oRow In
oTbl.Rows
'Sélection du document cible
oDocCible.Select
Selection.HomeKey
unit:=
wdStory
With
Selection.Find
.ClearFormatting
.Forward
=
True
.Text
=
NetText
(
oRow.Cells
(
1
).Range.Text
) 'utilisation de notre fonction
.Replacement.Text
=
NetText
(
oRow.Cells
(
2
).Range.Text
) 'utilisation de notre fonction
.Replacement.ClearFormatting
.Execute
Replace
:=
wdReplaceAll
End
With
Next
oRow
Dans cette boucle, nous utilisons directement le résultat dans notre fonction de recherche et remplacement.
With
Selection.Find
.ClearFormatting
.Forward
=
True
.Text
=
NetText
(
oRow.Cells
(
1
).Range.Text
) 'utilisation de la fonction de nettoyage
.Replacement.Text
=
NetText
(
oRow.Cells
(
2
).Range.Text
) 'utilisation de la fonction de nettoyage
.Replacement.ClearFormatting
.Execute
Replace
:=
wdReplaceAll
End
With
Voici le code complet :
Sub
RemplacerListeDeMots
(
)
'-------------------------------------------------
'Cette macro a pour rôle de remplacer les mots d'un
' document par une liste de
'mots se trouvant dans une table à deux colonnes
'-------------------------------------------------
'Déclaration des variables
'Le document oDocSource , contient la
'liste des mots et le document oDocCible les mots
'à remplacer
Dim
oDocSource As
Document, oDocCible As
Document
'Déclaration des variables table
Dim
oTbl As
Table
Dim
oRow As
Row
'Une boîte de dialogue pour choisir les documents
Dim
oDlg As
FileDialog
'Ouverture du premier document
'Affectation de l'objet oDlg
Set
oDlg =
Application.FileDialog
(
msoFileDialogFilePicker)
'Ouverture de la boîte de dialogue
With
oDlg
.AllowMultiSelect
=
False
.Title
=
"Document contenant le tableau"
.Show
End
With
'La propriété SelectedItems contient
Set
oDocSource =
Documents.Open
(
oDlg.SelectedItems
(
1
))
'Il faut répéter l'opération une seconde fois pour le
'document cible
With
oDlg
.AllowMultiSelect
=
False
.Title
=
"Document avec remplacement"
.Show
End
With
'ouverture du second document
Set
oDocCible =
Documents.Open
(
oDlg.SelectedItems
(
1
))
'Affectation de la table
Set
oTbl =
oDocSource.Tables
(
1
)
'Boucle sur les cellules de la table
For
Each
oRow In
oTbl.Rows
'Sélection du document cible
oDocCible.Select
Selection.HomeKey
unit:=
wdStory
With
Selection.Find
.ClearFormatting
.Forward
=
True
.Text
=
NetText
(
oRow.Cells
(
1
).Range.Text
) 'utilisation de notre fonction
.Replacement.Text
=
NetText
(
oRow.Cells
(
2
).Range.Text
) 'utilisation de notre fonction
.Replacement.ClearFormatting
.Execute
Replace
:=
wdReplaceAll
End
With
Next
oRow
'Libération des objets
Set
oDlg =
Nothing
Set
oTbl =
Nothing
oDocSource.Close
savechanges:=
wdDoNotSaveChanges
Set
oDocSource =
Nothing
End
Sub
Ces deux codes sont à placer dans le Normal.Dotm pour qu'ils soient disponibles pour toutes vos recherches. La fonction de nettoyage des caractères de fin de cellule peut être réutilisée dans d'autres codes.
3-B. Recherche dans plusieurs documents situés dans un répertoire▲
Le travail sur des documents contenus dans un répertoire n'est pas plus compliqué.
Pour intervenir sur les fichiers et les répertoires, j'utilise la bibliothèque Microsoft Scripting Runtime. Si vous souhaitez en apprendre un peu plus sur cette bibliothèque, je vous conseille de lire ce tutoriel : Manipulation des fichiers en VBA.
Ce que nous allons faire est une pseudo d'indexation d'un mot dans les fichiers d'un répertoire.
La première étape est l'ajout de la bibliothèque Microsoft Scripting Runtime qui permet de travailler sur les fichiers et les répertoires. Nous pourrons alors faire une boucle sur les fichiers d'un répertoire.
Cette étape peut être ignorée si l'on utilise le LateBinding. L'utilisation de l'EarlyBinding permet de profiter de l'intellisense. L'intellisense est une fonctionnalité de l'éditeur VBE qui affiche pour chaque objet une liste déroulante contenant les propriétés ou méthodes disponibles. Elle nous permet d'éliminer ou de diminuer les erreurs dans la saisie du code. Tous les exemples sont basés sur le EarlyBinding.
Les mots que nous allons rechercher dans les documents d'un répertoire sont stockés dans une table qui ne contient qu'une colonne. Chaque mot étant dans une cellule.
Set
oDocSource =
Documents.Open
(
FileName:=
"C:\Users\Oliver\Documents\Word\Forum\Tuto\listemots.docm"
)
...
'Affectation de la table qui contient les mots à rechercher.
Set
oTbl1 =
oDocSource.Tables
(
1
)
Il est plus facile de travailler avec un objet table qu'avec un document. Cet objet table sera affecté à la variable oTbl1 et le résultat de la recherche sera stocké dans une table créée dans un nouveau document.
'Affectation du document qui recevra le résultat de la recherche
Set
oDocCible =
Documents.Add
'Affectation de la table qui recevra les résultats
Set
oTbl2 =
oDocCible.Tables.Add
(
Range:=
Selection.Range
, numrows:=
1
, numcolumns:=
3
)
'Titres des colonnes de la table
With
oTbl2.Rows
(
1
)
.Cells
(
1
).Range.Text
=
"Mots"
.Cells
(
2
).Range.Text
=
"Page"
.Cells
(
3
).Range.Text
=
"Fichier"
End
With
Le code ci-dessus permet d'ajouter un "titre" aux colonnes.
Nous allons faire la recherche sur tous les fichiers d'un répertoire, nous avons besoin de récupérer le chemin de ce répertoire. Pour y parvenir, nous utiliserons un objet FileDialog.
Set
oDlg =
Application.FileDialog
(
msoFileDialogFolderPicker)
'Affichage de la boîte de dialogue
oDlg.Show
...
'Affectation du répertoire
Set
oFol =
oFso.GetFolder
(
oDlg.SelectedItems
(
1
))
Le résultat de l'objet FileDialog est utilisé pour affecter un répertoire à l'objet File System Object.
Nous utiliserons deux objets de cette "bibliothèque", le premier est l'objet Folder et le second l'objet File, qui sont respectivement les objets Répertoire et Fichier
Nous allons faire une boucle sur les fichiers d'un répertoire choisi par l'utilisateur. Pour ce choix, nous allons utiliser un objet FileDialog, mais contrairement à l'exemple précédent, nous n'allons pas récupérer le nom d'un fichier mais celui d'un répertoire.
For
Each
oFil In
oFol.Files
'Traitement de nos fichiers
Next
oFil
Dans cette boucle, nous allons traiter un par un les fichiers. Comme nous ne traitons que les fichiers Word, nous allons tester les extensions des fichiers pour n'utiliser que les "doc", "docx" et "docm". Les autres fichiers seront simplement ignorés.
If
Right
(
oFil.Name
, 4
) =
"docm"
Or
Right
(
oFil.Name
, 4
) =
"docx"
Or
Right
(
oFil.Name
, 3
) =
"doc"
Then
&
#8230
;
End
If
Si nous sommes en présence d'un document, nous allons le traiter, la première opération sera l'ouverture du document.
Après ouverture du document, nous allons lancer la recherche pour chaque mot contenu dans la table. Nous allons faire une boucle pour chaque élément de la table et pour chaque élément récupéré, une boucle de recherche.
'Première boucle sur les éléments de la table
For
Each
oRw In
oTbl1.Rows
'Pour chaque mot, retour au début du document
Selection.HomeKey
unit:=
wdStory
'seconde boucle sur la recherche
Do
'Recherche
With
Selection.Find
'Récupération du mot de la liste
.Text
=
NetText
(
oRw.Cells
(
1
).Range.Text
)
.Execute
'Affectation du résultat de la recherche à une variable
boofound =
.Found
End
With
'si la recherche est fructueuse
If
boofound Then
Debug.Print
oFil.Path
&
" - "
&
NetText
(
oRw.Cells
(
1
).Range.Text
) &
" - "
&
Selection.Information
(
wdActiveEndPageNumber)
'Ajout d'une ligne à la table
oTbl2.Rows.Add
'Utilisation du range de la nouvelle ligne de la table
With
oTbl2.Rows
(
oTbl2.Rows.Count
)
'Remplissage de la table
.Cells
(
1
).Range.Text
=
NetText
(
oRw.Cells
(
1
).Range.Text
)
.Cells
(
2
).Range.Text
=
Selection.Information
(
wdActiveEndPageNumber)
.Cells
(
3
).Range.Text
=
oFil.Path
End
With
End
If
'test de sortie de boucle
Loop
While
boofound
Next
oRw
Pour chaque mot, nous devons repositionner la Selection au début du document avec Selection.HomeKey unit:=wdStory. La récupération des mots contenus dans la table passe par un nettoyage de la chaîne de caractères. Chaque cellule d'une table Word contient deux caractères supplémentaires qu'il faut éliminer. Pour ce nettoyage, j'ai une petite fonction NetText qui élimine ces deux derniers caractères.
Ensuite, c'est une recherche normale dans le document. Comme nous souhaitons récupérer le résultat de la recherche, nous allons faire une boucle et tant que la recherche est fructueuse, nous l'exécutons.
Do
&
#8230
;.
'test de sortie de boucle
Loop
While
boofound
Le résultat est testé en fin de boucle. Si le mot n'est pas trouvé, la recherche s'arrête pour passer au mot suivant.
'si la recherche est fructueuse
If
boofound Then
'Ajout d'une ligne à la table
oTbl2.Rows.Add
'Utilisation du range de la nouvelle ligne de la table
With
oTbl2.Rows
(
oTbl2.Rows.Count
)
'Remplissage de la table
.Cells
(
1
).Range.Text
=
NetText
(
oRw.Cells
(
1
).Range.Text
)
.Cells
(
2
).Range.Text
=
Selection.Information
(
wdActiveEndPageNumber)
.Cells
(
3
).Range.Text
=
oFil.Path
End
With
End
If
Si le mot a été trouvé, nous ajoutons une ligne à notre table et insérons dans cette ligne le résultat : mot, page et nom du document. Avant d'ajouter une ligne, nous vérifions le résultat de la recherche. Ce test est nécessaire pour une raison simple : sans test, quelque soit le résultat, la boucle sera exécutée et la ligne ajoutée "If boofound Then".
Voilà le code complet avec la fonction de nettoyage :
Sub
BoucleSurRepertoire
(
)
'Déclaration des variables
Dim
oFso As
FileSystemObject
Dim
oFol As
Folder
Dim
oFil As
File
Dim
oDlg As
FileDialog
Dim
stFolder As
String
'Deux document, un qui recevra le résultat et un dans lequel
'la recherche sera exécutée
'La liste des mots à trouver sera dans le doc cible sous
'la forme d'une table
Dim
oDocSource As
Document, oDocCible As
Document, oDocTrv As
Document
Dim
oTbl1 As
Table, oTbl2 As
Table
Dim
oRw As
Row
Dim
boofound As
Boolean
'Affectation des variables
Set
oFso =
New
FileSystemObject
Set
oDlg =
Application.FileDialog
(
msoFileDialogFolderPicker)
'Affichage de la boîte de dialogue
oDlg.Show
'Affectation du document contenant la liste
Set
oDocSource =
Documents.Open
(
FileName:=
"C:\Users\Oliver\Documents\Word\Forum\Tuto\listemots.docm"
)
'Affectation du document qui recevra le résultat de la recherche
Set
oDocCible =
Documents.Add
'Affectation de la table qui recevra les résultats
Set
oTbl2 =
oDocCible.Tables.Add
(
Range:=
Selection.Range
, numrows:=
1
, numcolumns:=
3
)
'Titres des colonnes de la table
With
oTbl2.Rows
(
1
)
.Cells
(
1
).Range.Text
=
"Mots"
.Cells
(
2
).Range.Text
=
"Page"
.Cells
(
3
).Range.Text
=
"Fichier"
End
With
'Affectation de la table qui contient les mots à rechercher.
Set
oTbl1 =
oDocSource.Tables
(
1
)
'Affectation du répertoire
Set
oFol =
oFso.GetFolder
(
oDlg.SelectedItems
(
1
))
For
Each
oFil In
oFol.Files
'Test pour ne traiter que les documents et ignorer les autres fichiers
If
Right
(
oFil.Name
, 4
) =
"docm"
Or
Right
(
oFil.Name
, 4
) =
"docx"
Or
Right
(
oFil.Name
, 3
) =
"doc"
Then
'ouverture des fichiers
Set
oDocTrv =
Documents.Open
(
oFil.Path
)
'selection du fichier
oDocTrv.Select
'boucle sur la table contenant les mots
For
Each
oRw In
oTbl1.Rows
'Pour chaque mot, retour au début du document
Selection.HomeKey
unit:=
wdStory
'boucle sur la recherche
Do
'Recherche
With
Selection.Find
'Récupération du mot de la liste
.Text
=
NetText
(
oRw.Cells
(
1
).Range.Text
)
.Execute
'Affectation du résultat de la recherche à une variable
boofound =
.Found
End
With
'si la recherche est fructueuse
If
boofound Then
Debug.Print
oFil.Path
&
" - "
&
NetText
(
oRw.Cells
(
1
).Range.Text
) &
" - "
&
Selection.Information
(
wdActiveEndPageNumber)
'Ajout d'une ligne à la table
oTbl2.Rows.Add
'Utilisation du range de la nouvelle ligne de la table
With
oTbl2.Rows
(
oTbl2.Rows.Count
)
'Remplissage de la table
.Cells
(
1
).Range.Text
=
NetText
(
oRw.Cells
(
1
).Range.Text
)
.Cells
(
2
).Range.Text
=
Selection.Information
(
wdActiveEndPageNumber)
.Cells
(
3
).Range.Text
=
oFil.Path
End
With
End
If
'test de sortie de boucle
Loop
While
boofound
Next
oRw
'Fermeture du document dans lequel nous effectuons la recherche
oDocTrv.Close
End
If
Next
oFil
Set
oTbl1 =
Nothing
Set
oTbl2 =
Nothing
oDocSource.Close
Set
oDocSource =
Nothing
Set
oDlg =
Nothing
Set
oFol =
Nothing
Set
oFso =
Nothing
End
Sub
Function
NetText
(
stTemp As
String
) As
String
'Fonction de nettoyage
'Supprime les deux derniers caractères de la cellule
NetText =
Left
(
stTemp, Len
(
stTemp) -
2
)
End
Function
4. Remerciements▲
Un grand merci à l'équipe Office et aux relecteurs orthographiques et plus particulièrement Jacques Thery.