Pour partager cette vidéo sur les réseaux sociaux ou sur un site, voici son url :
Sujets que vous pourriez aussi aimer :
Exporter les données au format Word
Avec les travaux précédents, nous avons découvert différentes techniques d'
importation et d'
exportation des données. Dans ce nouveau volet, nous proposons d'
exporter toutes les données d'une table au
format Word . L'idée est de créer des fiches produit individuelles, donc une fiche par enregistrement.
Base de données Access à télécharger
Pour développer cette solution, nous suggérons d'appuyer les travaux sur une
base de données offrant des
données à exporter , ainsi qu'un
formulaire déjà doté de quelques fonctionnalités.
Comme vous le constatez, la décompression fournit le
fichier de la base de données accompagné d'un
sous dossier nommé
exports . C'est lui qui doit accueillir les
exportations des fiches produit au
format Word .
Double cliquer sur le fichier de la base de données pour l'ouvrir dans Access ,
Le volet de navigation indique que cette base de données est constituée de deux tables et d'un formulaire.
Double cliquer sur la table Produits pour l'afficher en mode feuille de données ,
Comme vous pouvez le voir, elle est constituée de 244 enregistrements. Elle archive des articles vestimentaires avec un certain niveau de détail. C'est sur la base du détail de ses
champs que nous souhaitons
automatiser l'exportation des 244 fiches produits au
format Word .
Fermer cette table en cliquant sur la croix de son onglet,
Puis, double cliquer sur le formulaire fQuestions pour l'exécuter,
Dès lors, déployer la liste déroulante qui se propose,
C'est un
code VBA Access qui se déclenche au
chargement du formulaire pour
remplir automatiquement cette
liste déroulante des
noms de tables existantes.
Au clic sur le bouton Exporter
Pour débuter, nous devons tout d'abord créer la procédure de
code VBA qui se déclenchera au clic sur le
bouton Exporter .
A gauche du ruban Accueil , cliquer sur la flèche du bouton Affichage ,
Dans les propositions, choisir le mode Création ,
Sur le formulaire en conception, cliquer sur le bouton Exporter pour le sélectionner,
Activer l'onglet Evénement de sa feuille de propriétés ,
Puis, cliquer sur le petit bouton associé à son événement Au clic ,
Dans la boîte de dialogue qui suit, choisir le Générateur de code et valider par Ok,
Nous basculons ainsi dans l'
éditeur VBA Access , entre les bornes de la
procédure exporter_Click . Son code s'exécutera donc au clic sur le
bouton Exporter .
La déclaration des variables
Quelques
variables sont nécessaires pour notamment piloter la
base de données mais aussi pour piloter une
instance de Word , capable de réceptionner les informations et de les enregistrer.
Dans les bornes de la procédure, ajouter les déclarations de variables suivantes :
Private Sub exporter_Click()
Dim base As Database: Dim enr As Recordset: Dim table As TableDef: Dim champ As Field
Dim instanceW As Object
Dim nomTable As String: Dim champs() As String
Dim nomF As String: Dim nbChamps As Byte: Dim compteur As Byte: Dim i As Byte
End Sub
L'
objet base de type Database est destiné à pointer sur la
base de données en cours . Grâce à ses propriétés et méthodes héritées, nous pourrons initialiser l'
objet enr de type Recordset , pour qu'il pilote les
enregistrements de la table désignée par l'utilisateur. L'
objet table de type TableDef doit permettre d'accéder aux informations de la table, pour notamment connaître les
noms de ses champs . En effet, d'une table à une autre, le nom et la structure peuvent changer. Nous ne pouvons donc pas nous permettre de développer un code statique sur des noms de champs définis en dur. L'objet
instanceW est pour l'instant typé comme un objet au sens large. Il prendra son type grâce à la
fonction CreateObject pour instancier la
classe Word
Les
variables qui suivent son plus classiques.
nomTable doit stocker le
nom de la table choisie. Puis, nous déclarons un
tableau de variables nommé
champs . Son rôle est de stocker
tous les noms de champs de la table pour pouvoir les parcourir et récupérer leurs informations et ce, pour chaque enregistrement. C'est à ce prix que nous pourrons construire chaque fiche produit.
nomF doit reconstruire le
chemin d'accès complet jusqu'au
sous dossier exports pour lui associer un
nom de fichier avec l'
extension docx . Ce
nom de fichier , nous le baserons sur le nom du produit en cours d'analyse. Ensuite, nous déclarons quelques
variables numériques , typées comme des
entiers courts . Elles serviront notamment de
compteur et de
variables de boucles .
Les objets de base de données
Nous devons maintenant affecter certaines de ces variables notamment pour
initialiser les objets de base de données .
A la suite du code, ajouter les instructions VBA suivantes :
...
If (choixTable.Value <> "") Then
nomTable = choixTable.Value
Set base = CurrentDb()
Set table = base.TableDefs(nomTable)
nbChamps = table.Fields.Count
ReDim champs(nbChamps)
compteur = 0
End If
...
La
liste déroulante est nommée
choixTable . Nous vérifions tout d'abord que son contenu n'est pas vide. En effet, il n'est pas utile de lancer le traitement si aucune table n'a été désignée par l'utilisateur. Grâce à la
fonction CurrentDb , nous initialisons (Set) l'
objet base sur la
base de données en cours . Dès lors, nous exploitons sa
collection héritée TableDefs pour prendre possession de la table dont le nom est passé en paramètre. Désormais, l'
objet table ainsi initialisé (Set) peut piloter cette table désignée. Pour preuve, nous exploitons dans l'enchaînement sa
collection Fields avec sa
propriété Count pour stocker le
nombre de champs de cette table dans la
variable nbChamps . Nous redimensionnons (ReDim) alors le
tableau de variables sur cette quantité. Il sera ainsi en mesure d'accueillir chaque nom de champ à mémoriser. Enfin, nous initialisons la
variable compteur à zéro.
Récolter les noms des champs
Grâce à l'
objet table et à sa désormais
collection Fields , nous allons maintenant pouvoir
parcourir tous ses champs à l'aide d'une
boucle For Each . L'objectif est de pouvoir stocker chaque
nom de champ dans une rangée différente du
tableau de variables . C'est la raison pour laquelle nous avons initialisé la
variable compteur à zéro. Au lancement, elle pointe ainsi sur la première rangée du tableau à alimenter.
A la suite et toujours dans l'instruction conditionnelle, créer la boucle For Each suivante :
...
For Each champ In table.Fields
champs(compteur) = champ.Name
compteur = compteur + 1
Next champ
...
A chaque passage, nous stockons le
nom du champ en cours d'analyse (champ.Name) dans la rangée active du
tableau de variables . Avant de boucler, nous n'oublions pas d'
incrémenter la variable compteur (compteur = compteur + 1) pour que le
prochain nom de champ soit stocké dans la
rangée suivante .
Les enregistrements et l'instance Word
Certes, ce n'est pas très protocolaire car nous aurions pu regrouper toutes les initialisations d'objets. Mais dans la démarche chronologique, c'est maintenant que nous entreprenons d'initialiser l'objet devant
piloter les enregistrements de la table ainsi que celui devant
piloter une instance de Word .
A la suite et toujours dans l'instruction conditionnelle, ajouter les lignes VBA suivantes :
...
Set enr = base.OpenRecordset(nomTable)
Set instanceW = CreateObject("Word.Application")
instanceW.Visible = False
...
Grâce à la désormais
méthode OpenRecordset de l'
objet base , nous initialisons (Set) l'
objet enr sur le jeu d'enregistrements de la table en cours (nomTable). C'est ensuite la
fonction CreateObject avec l'
argument Word.Application qui permet d'
instancier la classe Word . C'est ainsi que l'
objet instanceW propose notamment la
propriété Visible que nous réglons Ã
False . En effet, nous souhaitons que ces créations et exportations se fassent en
tâches de fond . Il n'est pas question d'ouvrir une nouvelle fenêtre Word à chaque enregistrement exporté.
Parcourir tous les enregistrements
Puisque tous nos objets sont fin prêts, il est temps d'entreprendre la création d'une
boucle parcourant chaque enregistrement de la table désignée. Et souvenez-vous, dans cette
boucle , nous devrons
parcourir tous les champs de
chaque enregistrement pour récolter toutes les informations.
Toujours dans le If et à la suite du code, créer la boucle suivante :
...
enr.MoveFirst: compteur = 1
Do
instanceW.Documents.Add DocumentType:= wdNewBlankDocument
enr.MoveNext
compteur = compteur + 1
enCours.Value = Int((compteur * 100) / enr.RecordCount)
Loop Until enr.EOF
...
Nous plaçons tout d'abord le
pointeur de lecture sur le
premier enregistrement avec la
méthode MoveFirst . Puis, nous réinitialisons la
variable compteur . Grâce à la
propriété EOF (End Of File) de l'
objet enr , nous bouclons (Do... Loop Until) tant que le
dernier enregistrement n'est pas atteint. A chaque passage, nous exploitons la
méthode Add de la
collection Documents de notre
instance de Word , pour créer un
nouveau document (wdNewBlankDocument). Son rôle est d'accueillir chaque nouvelle fiche à créer avec les informations de
chaque enregistrement passé en revue.
Bien entendu, Ã chaque passage, nous n'oublions pas de
déplacer le pointeur de lecture sur l'
enregistrement suivant , avec la
méthode MoveNext . Nous incrémentons ensuite la
variable compteur pour rendre compte de l'état d'avancement, en l'exploitant dans la
propriété Value de l'
objet enCours . Cet objet représente le
contrôle ActiveX de la
barre de progression sur le
formulaire .
Ecrire sur le document Word
Maintenant, il est question de faire intervenir des techniques que nous avons apprises en
VBA Word pour écrire les informations récoltées sur le document. Et pour puiser toutes les
données des champs pour l'
enregistrement en cours d'analyse, nous devons entreprendre une
boucle parcourant chaque élément du
tableau de variables .
...
Do
instanceW.Documents.Add DocumentType:=wdNewBlankDocument
For i = 0 To nbChamps - 1
If i = 1 Then
instanceW.Selection.TypeText Chr(13)
instanceW.Selection.Font.Bold = True
instanceW.Selection.Font.Size = 16
End If
instanceW.Selection.TypeText champs(i) & " : " & enr.Fields(champs(i)) & Chr(13)
If i = 1 Then
instanceW.Selection.Font.Bold = False
instanceW.Selection.Font.Size = 11
instanceW.Selection.TypeText Chr(13)
End If
Next i
enr.MoveNext
compteur = compteur + 1
enCours.Value = Int((compteur * 100) / enr.RecordCount)
Loop Until enr.EOF
...
Nous parcourons tous les champs du premier (0) jusqu'au dernier (nbChamps - 1). S'il s'agit de la deuxième rangée du
tableau de variables (If i = 1 Then), nous en déduisons qu'il s'agit de l'élément important du tableau de valeurs. En effet, dans la construction d'une table, la
clé primaire est généralement déclarée en premier puis vient le nom ou la désignation. C'est cet élément que nous souhaitons faire ressortir. Pour cela, nous exploitons la
propriété Font de l'
objet enfant Selection de notre
instance de Word , celle du nouveau document. Nous calibrons l'inscription en gras et en taille 16. Puis, nous exploitons la
méthode TypeText de ce même
objet Selection pour inscrire le nom du champ suivi de son contenu (enr.Fields(champs(i))). Comme cette inscription est réalisée en dehors du If, elle est valable pour tous les champs. Mais pour celui de la désignation, elle est faite en gras et en taille 16 du fait des initialisations précédentes. Et précisément, une fois cet élément clé passé, nous réinitialisons la police en taille 11 et dans un style normal. Notez que la
fonction chr est utilisée avec la valeur 13 pour créer des
sauts de ligne .
Enregistrer chaque document Word
Il reste quelques détails à régler. En fonction des deux premiers champs (clé primaire et nom), nous devons construire le
nom de chaque fichier à enregistrer. Et pour cela, nous devons aussi recomposer le
chemin d'accès complet jusqu'au
sous dossier exports .
Après la boucle For mais toujours dans la boucle Do , ajouter les instructions VBA suivantes :
...
nomF = LCase(Replace(enr.Fields(champs(0)) & "-" & enr.Fields(champs(1)), " ", "-")) & ".docx"
nomF = Replace(Replace(nomF, "?", "-"), "/", "-")
nomF = CurrentProject.Path & "\exports\" & nomF
instanceW.ActiveDocument.SaveAs2 nomF, wdFormatDocumentDefault
...
Nous exploitons la
fonction VBA LCase pour convertir en lettres minuscules l'assemblage du numéro et du nom séparés d'un tiret (champs(0)) & "-" & enr.Fields(champs(1)). Cette même fonction LCase embarque la
fonction Replace pour remplacer tous les espaces par des tirets ("", "-"). Puis, nous ajoutons l'extension du document Word (.docx). Nous engageons alors un nouveau traitement pour corriger certains caractères interdits dans les noms de fichiers, comme le point d'interrogation (?) ou le slash (/). Enfin, nous passons ce nom à la
méthode SaveAs de l'
objet ActiveDocument de l'instance Word pour créer la fiche produit au format Word par défaut (wdFormatDocumentDefault).
Détruire les variables objets
Nous en avons presque terminé. Les variables objets, lorsqu'elles ne sont plus utilisées, doivent être fermées et détruites pour libérer proprement la mémoire.
A la fin du code, avant le dernier End If , ajouter les instructions VBA suivantes :
...
enCours.Value = Int((compteur * 100) / enr.RecordCount)
Loop Until enr.EOF
instanceW.Quit
Set instanceW = Nothing
enr.Close
base.Close
Set base = Nothing
Set enr = Nothing
MsgBox "Le processus de conversion est terminé.", vbInformation
End If
End Sub
...
Nous exploitons les
méthodes Quit et Close pour fermer respectivement l'
instance de Word , l'
objet pilotant les enregistrements et l'
objet pointant sur la base de données en cours . Ensuite, nous les réinitialisons tous (Set) à la
valeur Nothing pour les détruire et ainsi les sortir de la mémoire. Enfin, nous enclenchons une
boîte de dialogue avec la
fonction VBA MsgBox pour informer l'utilisateur que le
processus d'exportation est terminé.
Convertir les enregistrements en fiches Word
Il est temps de tester le bon fonctionnement de ce
code VBA Access .
Enregistrer les modifications (CTRL + S) et basculer sur le formulaire (ALT + Tab),
L'exécuter avec la touche F5 du clavier ,
Avec la liste déroulante, choisir la table Produits ,
Puis, cliquer sur le bouton Exporter ,
Le processus prend du temps car les données à exporter et à convertir sont nombreuses. Si vous affichez le contenu du
sous dossier exports , vous voyez apparaître les nouveaux
fichiers Word les uns après les autres. Ils portent bien les noms retravaillés à partir des désignations.
Si vous ouvrez l'un ou l'autre
fichier Word , vous constatez que les reproductions des fiches produit sont fidèles aux informations des éléments désignés dans la
base de données .
Le
code VBA Access complet que nous avons construit pour
exporter ces données de table dans des
fichiers Word est le suivant :
Private Sub exporter_Click()
Dim base As Database: Dim enr As Recordset: Dim table As TableDef: Dim champ As Field
Dim instanceW As Object
Dim nomTable As String: Dim champs() As String
Dim nomF As String: Dim nbChamps As Byte: Dim compteur As Byte: Dim i As Byte
If (choixTable.Value <> "") Then
nomTable = choixTable.Value
Set base = CurrentDb()
Set table = base.TableDefs(nomTable)
nbChamps = table.Fields.Count
ReDim champs(nbChamps)
compteur = 0
For Each champ In table.Fields
champs(compteur) = champ.Name
compteur = compteur + 1
Next champ
Set enr = base.OpenRecordset(nomTable)
Set instanceW = CreateObject("Word.Application")
instanceW.Visible = False
enr.MoveFirst: compteur = 1
Do
instanceW.Documents.Add DocumentType:=wdNewBlankDocument
For i = 0 To nbChamps - 1
If i = 1 Then
instanceW.Selection.TypeText Chr(13)
instanceW.Selection.Font.Bold = True
instanceW.Selection.Font.Size = 16
End If
instanceW.Selection.TypeText champs(i) & " : " & enr.Fields(champs(i)) & Chr(13)
If i = 1 Then
instanceW.Selection.Font.Bold = False
instanceW.Selection.Font.Size = 11
instanceW.Selection.TypeText Chr(13)
End If
Next i
nomF = LCase(Replace(enr.Fields(champs(0)) & "-" & enr.Fields(champs(1)), " ", "-")) & ".docx"
nomF = Replace(Replace(nomF, "?", "-"), "/", "-")
nomF = CurrentProject.Path & "\exports\" & nomF
instanceW.ActiveDocument.SaveAs2 nomF, wdFormatDocumentDefault
enr.MoveNext
compteur = compteur + 1
enCours.Value = Int((compteur * 100) / enr.RecordCount)
Loop Until enr.EOF
instanceW.Quit
Set instanceW = Nothing
enr.Close
base.Close
Set base = Nothing
Set enr = Nothing
MsgBox "Le processus de conversion est terminé.", vbInformation
End If
End Sub