Pour partager cette vidéo sur les réseaux sociaux ou sur un site, voici son url :
Sujets que vous pourriez aussi aimer :Importer des données externes
Dans ce nouveau volet, nous allons apprendre relativement simplement Ã
importer les données de fichiers externes par le
code VBA Word. Ici, l'idée est d'assembler des articles pour reconstituer le document final, de façon automatisée.
Les sources de données
Pour la démonstration, nous avons besoin de fichiers hébergeant des
données à importer.
Comme vous pouvez le voir, la décompression livre un
dossier nommé
import.
- Double cliquer sur ce dossier pour l'ouvrir,
Trois fichiers de texte sont présents. Ils hébergent chacun un bout d'article. Et ces articles sont une suite logique d'une partie d'une
formation VBA Excel, précisément sur l'
importation de données dans une feuille. Et nous allons voir que les techniques que nous y avions apprises sont similaires, à quelques détails près, que nous allons découvrir ensemble.
Accès en lecture
Il est question d'ouvrir le contenu de chaque fichier en mémoire pour y
accéder en lecture par le
code VBA. Nous pourrons ainsi prélever les informations ligne à ligne pour les recomposer sur le document. Ces trois
fichiers externes se suivent. Donc, ils doivent être ouverts puis fermés dans l'enchaînement. C'est la raison pour laquelle il est judicieux de créer une procédure générale centralisée pour l'
importation. Elle devra être appelée pour chaque fichier à importer en lui passant le
chemin d'accès à traiter.
- Démarrer Word et créer un nouveau document,
- Puis, l'enregistrer au format Docm dans le dossier de téléchargement,
Nous choisissons donc de placer le
fichier Word au-dessus du
dossier import. L'
extension docm est importante. Sans elle les
macros VBA ne peuvent être gérées.
- Basculer dans l'éditeur VBA Word avec le raccourci clavier ALT + F11,
- Dans l'explorateur de projet sur la gauche, double cliquer sur l'élément ThisDocument,
Ainsi, nous affichons la
feuille de code associée au document actif au centre de l'écran. Certes, elle est encore vierge à ce stade.
- Dans cette feuille de code, créer la procédure importer comme suit :
Private Sub importer(chemin As String)
End Sub
Nous la déclarons avec un paramètre de type texte en attente. C'est effectivement cette
variable chemin qui doit transmettre le
chemin d'accès au fichier dont il s'agit de récupérer le contenu.
Notez que nous la déclarons comme une
procédure privée (private). En effet, elle n'est pas destinée à se déclencher seule. Elle doit être appelée avec transmission de l'information nécessaire en paramètre. Grâce à cette
signature privée, elle n'apparaîtra pas dans la liste des macros.
Private Sub importer(chemin As String)
Dim texte As String
End Sub
Nous déclarons donc une
variable de type texte. Elle doit servir à réceptionner le contenu externe, au fil de la lecture par le
code VBA, pour l'inscrire dans le flux du document. Nous devons maintenant
ouvrir le fichier texte en mémoire. Son chemin est passé en paramètre de la procédure.
- A la suite du code, ajouter les instructions VBA suivantes :
Private Sub importer(chemin As String)
Dim texte As String
Open chemin For Input As #1
Close #1
End Sub
Il s'agit d'instructions classiques que nous avons déjà eu l'occasion d'aborder en
VBA Excel et en
VBA Access. Grâce au
mot clé Open, nous annonçons le fichier à analyser. Et précisément, il est désigné dans l'enchaînement grâce à la
variable chemin transmise en paramètre. Ensuite, c'est le mode d'accès qui doit être stipulé et qui est annoncé par le
mot clé For. Nous y accédons en lecture (Input) et non en écriture. Et pour que ce fichier puisse être lu, nous devons le
charger en mémoire. C'est la raison pour laquelle nous définissons un numéro d'allocation pas encore utilisé (
As #1). C'est cet
adressage par le biais de ce numéro, qui va permettre au
code VBA de pointer sur le fichier externe ainsi logé pour le parcourir. Et avant d'implémenter cette section, nous n'oublions pas de fermer ce fichier pour libérer la mémoire après traitement (Close #1). Comme vous le constatez, c'est bien par son numéro que nous désignons le fichier à fermer.
Maintenant, nous devons coder
entre les bornes de cette instruction de lecture pour
parcourir le fichier ainsi stocké en mémoire. Et pour cela, nous avons besoin d'une
boucle capable de prélever chaque ligne tant que la fin du fichier n'est pas atteinte.
- Dans les bornes de l'instruction de lecture, ajouter le code VBA suivant :
Private Sub importer(chemin As String)
Dim texte As String
Open chemin For Input As #1
Do While Not EOF(1)
Loop
Close #1
End Sub
Nous engageons une
boucle Do While qui doit poursuivre son traitement tant que le critère émis est vérifié. Ce critère est stipulé par la même ligne. Il exploite la
fonction VBA EOF qui signifie
End Of File. Nous lui passons l'adresse du fichier chargé en mémoire (1). Grâce à la négation, nous poursuivons le
traitement de la boucle tant que la fin du fichier n'est pas atteinte. Le
mot clé Loop est naturellement exploité pour borner cette boucle.
Dans cette
boucle, nous devons maintenant prélever les informations de ce fichier ligne à ligne et comme nous l'avons dit, tant que la fin n'est pas atteinte.
- A la suite du code, toujours dans les bornes de la boucle, ajouter l'instruction VBA suivante :
Private Sub importer(chemin As String)
Dim texte As String
Open chemin For Input As #1
Do While Not EOF(1)
Line Input #1, texte
Loop
Close #1
End Sub
L'instruction
Line Input procède à la lecture de la ligne en cours dans le fichier toujours désigné par son adresse en mémoire (#1). Cette ligne est stockée dans la
variable texte que nous avions déclarée à cet effet. A l'issue, le pointeur de lecture est placé sur la ligne suivante. C'est ainsi que la boucle peut naturellement poursuivre son analyse de ligne en ligne.
Avant de prélever la ligne qui suit, nous devons commencer par restituer celle que nous venons de récupérer. Ces méthodes d'injection dans le flux du document, nous les avons largement abordées à l'occasion des
astuces VBA Word précédentes.
- Toujours dans la boucle et à la suite du code, ajouter l'instruction VBA suivante :
Private Sub importer(chemin As String)
Dim texte As String
Open chemin For Input As #1
Do While Not EOF(1)
Line Input #1, texte
Selection.InsertAfter texte & Chr(13)
Loop
Close #1
End Sub
C'est la
méthode InsertAfter de l'
objet VBA Selection qui permet d'
insérer le texte après la sélection active, en l'occurrence ici après le point d'insertion. Et ce texte est bien sûr passé en paramètre de cette méthode grâce à la
variable (texte) qui le stocke jusqu'au prochain passage dans la boucle. Et nous le faisons suivre d'un saut de paragraphe grâce à la
fonction VBA Chr. Avec la valeur 13, nous simulons l'action de la touche Entrée sur le clavier.
Importer le contenu externe
Maintenant, il est temps d'exploiter cette procédure en l'appelant à trois reprises pour
importer le contenu des trois fichiers textes. Et pour cela, nous devons créer une
nouvelle procédure mais
publique cette fois pour qu'elle puisse être exécutée par un bouton de macro par exemple.
- Au-dessus de la procédure importer, créer la procédure lancer comme suit :
Sub lancer()
Dim acces As String
End Sub
Nous commençons donc par déclarer la
variable destinée à stocker le
chemin d'accès aux fichiers, tout au moins le début de ce chemin car la fin varie en fonction du nom du fichier.
- A la suite du code de la procédure, ajouter l'affectation VBA suivante :
Sub lancer()
Dim acces As String
acces = ThisDocument.Path & "\import\"
End Sub
C'est la
propriété Path de l'
objet ThisDocument qui renseigne sur le
chemin d'accès du document actif. Par concaténation, nous pointons sur le sous
dossier import. Puis, nous stockons cette adresse inachevée dans la
variable acces.
Maintenant, avant de déclencher l'
importation des fichiers, nous devons nous assurer que l'espace est purgé.
- A la suite du code, ajouter les deux instructions VBA suivantes :
Sub lancer()
Dim acces As String
acces = ThisDocument.Path & "\import\"
Selection.WholeStory
Selection.Delete
End Sub
La
méthode WholeStory de l'
objet Selection permet de sélectionner l'intégralité du document. Ensuite, la
méthode Delete de ce même objet engage la suppression du contenu sélectionné, donc de tous les paragraphes du document dans ce contexte.
- Dès lors et toujours à la suite du code VBA, ajouter les trois appels suivants :
Sub lancer()
Dim acces As String
acces = ThisDocument.Path & "\import\"
Selection.WholeStory
Selection.Delete
importer acces & "partie1.txt"
importer acces & "partie2.txt"
importer acces & "partie3.txt"
End Sub
La
procédure importer est donc appelée à trois reprises. Mais à chaque fois, nous adaptons la fin du chemin pour pointer sur le
fichier externe suivant. Nous devrions donc réaliser la
consolidation des contenus des trois fichiers texte sur le même document, les uns en dessous des autres.
- Enregistrer les modifications (CTRL + S) et basculer sur le document Word(ALT + Tab),
- En haut de la fenêtre Word, cliquer sur l'onglet Développeur pour activer son ruban,
S'il n'est pas disponible dans votre environnement, vous devez cliquer droit n'importe où sur le ruban actif. Ensuite, dans le menu contextuel, vous devez opter pour l'
option Personnaliser le ruban. Dès lors dans la boîte de dialogue qui apparaît, vous devez cocher la
case Développeur et cliquer sur le bouton Ok pour l'intégrer.
- Dans la section Code à gauche du ruban Développeur, cliquer sur le bouton Macros,
- Dans la boîte de dialogue qui suit, cliquer sur la ligne de la macro lancer,
- Puis, cliquer sur le bouton Exécuter en haut à droite de la boîte de dialogue,
Aussitôt et comme vous pouvez l'apprécier, les trois blocs de textes issus des trois fichiers se disposent les uns en dessous des autres. Grâce à notre procédure centralisée de lecture en mémoire, l'importation des trois fichiers de texte semble s'être déroulée à merveille. Et pourtant en y regardant de plus près, des défauts sautent aux yeux. Ils concernent la deuxième importation. Tous les accents sont mal retranscrits et apparaissent illisibles.
C'est donc le deuxième fichier texte (partie2.txt) qui semble être en cause.
Système d'encodage des fichiers
Tout est en réalité une question d'
encodage des fichiers. Selon leur nature, l'importation ne peut pas être réalisée de la même façon. Les caractères doivent être interprétés en conséquence. C'est la raison pour laquelle ce nouveau volet
VBA Word est particulièrement intéressant.
- A la racine du dossier de décompression, double cliquer sur le dossier import pour l'ouvrir,
- Dès lors, cliquer droit sur le fichier partie2.txt,
- Dans le menu contextuel, choisir de l'ouvrir avec un éditeur comme le Notepad++,
Si vous ne le possédez pas, sachez qu'il s'agit d'un logiciel gratuit. Vous pouvez le trouver très facilement avec un moteur de recherche comme Google.
Comme vous le remarquez, les accents sont cette fois parfaitement encodés. Et nous allons comprendre ce qui justifie une telle différence.
- En haut de l'éditeur Notepad, cliquer sur le menu Encodage,
Ce fichier est
encodé en Utf-8. Cet
encodage est différent de la
norme Iso utilisée par défaut dans les phases d'importation classique pour la
gestion des accents. Cette différence explique ce problème d'interprétation des accents une fois l'importation livrée.
Gérer l'encodage des fichiers
Nous allons donc devoir changer notre fusil d'épaule. Nous devons utiliser une
méthode d'importation à partir de laquelle il est possible de définir le
système d'encodage du fichier à récupérer. Et pour cela, nous allons instancier la
classe ADODB.Stream. L'objet ainsi créé héritera des
propriétés pour notamment définir l'
encodage mais aussi des
méthodes dont celle permettant d'
accéder au fichier en lecture.
- Revenir dans l'éditeur VBA Word,
- Supprimer le code de la procédure importer, sauf la déclaration de variable,
- Ajouter alors la déclaration supplémentaire : Dim objFlux,
- Puis, modifier la signature de la procédure avec un nouveau paramètre à transmettre :
Private Sub importer(chemin As String, encodage As String)
Dim texte As String
Dim objFlux
End Sub
Nous ne typons pas la
variable objFlux. C'est elle qui doit instancier la
classe ADODB.Stream. Elle sera donc naturellement transformée en
variable objet. Le second paramètre attendu concerne le
système d'encodage à utiliser pour lire les informations du fichier passé en premier paramètre.
- Après les déclarations, ajouter l'instanciation suivante :
Private Sub importer(chemin As String, encodage As String)
Dim texte As String
Dim objFlux
Set objFlux = CreateObject("ADODB.Stream")
End Sub
C'est la
fonction VBA CreateObject qui permet de pointer sur une
classe à instancier.C'est par son nom qu'elle lui est passée en paramètre. De fait et par initialisation et affectation (Set), la
variable objFlux est transformée en objet ayant hérité des
propriétés et
méthodes de cette
classe.
Nous allons donc maintenant pouvoir exploiter cet objet pour accéder aux
contenus des fichiers en lecture, tout en définissant le
système d'encodage approprié.
- A la suite du code VBA, ajouter les instructions suivantes :
Private Sub importer(chemin As String, encodage As String)
Dim texte As String
Dim objFlux
Set objFlux = CreateObject("ADODB.Stream")
objFlux.Charset = encodage
objFlux.Open
objFlux.LoadFromFile (chemin)
texte = objFlux.ReadText()
objFlux.Close
Selection.InsertAfter texte
End Sub
Toutd'abord, c'est la
propriété Charset de l'objet ainsi créé qui permet de définir l'
encodage à utiliser pour
lire le contenu du fichier. Nous l'affectons à l'encodage passé en paramètre de la procédure. Ensuite, la
méthode Open permet d'initialiser le flux en allouant une place en mémoire. Dès lors, nous exploitons la
méthode LoadFromFile pour pointer sur le fichier à récupérer. Nous passons à cette méthode le
chemin d'accès transmis en
premier paramètre de la
procédure importer. Dès lors, la
méthode ReadText permet de récupérer le contenu complet. Ce contenu est affecté à la
variable texte. Nous fermons le flux pour libérer la mémoire grâce à la
méthode Close de l'
objet ADODB.Stream. Enfin, nous insérons l'intégralité du contenu ainsi récupéré comme précédemment, grâce à la
méthode InsertAfter de l'
objet Selection.
Nous devons maintenant adapter les
appels de la procédure pour lui transmettre l'
encodage à respecter en second paramètre.
- Dans la procédure lancer, adapter le code VBA comme suit :
Sub lancer()
Dim acces As String
acces = ThisDocument.Path & "\import\"
Selection.WholeStory
Selection.Delete
importer acces & "partie1.txt","iso-8859-1"
importer acces & "partie2.txt","utf-8"
importer acces & "partie3.txt","iso-8859-1"
End Sub
- Enregistrer les modifications (CTRL + S) et basculer sur le document Word,
- Dans la section Code, à gauche du ruban Développeur, cliquer sur le bouton Macros,
- Dans la boîte de dialogue, sélectionner la macro lancer puis cliquer sur le bouton Exécuter,
Comme vous pouvez le voir, l'importation s'est cette fois parfaitement déroulée. Les spécificités du deuxième fichier ont été gérées par le
jeu d'encodage transmis à la volée.