Le publipostage avec Access

Olivier Lebeau

Comment faire communiquer Access et Word pour échanger des données, ainsi que Access et Outlook pour envoyer des données.

- Titre : Le publipostage avec Access

- Auteur : Olivier Lebeau

- Parution : 15 février 2007

- Licence : Copyright ® 2007 Olivier Lebeau. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- I. Communication entre Access et Word (Le Publipostage)

- I-A. Pourquoi le publipostage ?

- I-B. Les différents types de publipostages qui seront abordés

- I-B-1. Le publipostage traditionnel

- I-B-2. Le publipostage au départ d'Access.

- I-B-3. Le publipostage au départ de "recordset" pour une publication et impression page par page.

- I-B-4. Le transfert de données dans un document Word

- I-B-5. L'envoi massif de mail via Outlook.

- I-B-5-a. Publipostage depuis Access : Comment faire ?

- I-B-5-b. Préparer les données.

- I-B-5-c. Préparation du document principal de fusion.

- I-B-5-d. Modification de la base de données "Comptoir"

- I-B-5-e. Ajout d'une procédure

- I-B-5-f. Ajout d'un formulaire

- I-B-6. Publipostage à l'aide de Recordsets et de signets

- I-B-6-a. Préparation des données

- I-B-6-b. Préparation du document.

- I-B-6-c. Modification de la base de données Comptoir

- I-B-7. Transfert intégral de données en Word

- I-B-7-a. Base de données

- I-B-7-b. Document Word.

- I-B-7-c. Détail du Code

- I-B-8. Avec des images à insérer

- II. Publipostage vers le mail

- II-A. News Letter

- II-B. Mail au format HTML

- II-B-1. Notion de HTML

- II-B-2. Modification du Formulaire

- II-B-3. Mise en forme du HTML

- II-B-4. Code

- III. Remerciements

I - Communication entre Access et Word (Le Publipostage)

Vous pouvez trouver un autre article sur le publipostage à cette adresse : Fusion et Publipostage

I-A - Pourquoi le publipostage ?

Word et Access font tous deux partie de la suite bureautique de Microsoft.

Pour l'envoi de courrier, il est parfois utile d'automatiser certaines tâches, Word est fait pour le courrier, alors qu''Access l'est pour la gestion des données. On pourrait même se dire qu''Access n'a pas besoin de Word pour générer du courrier pour l'envoi de documents. Mais à l'utilisation, on se rend compte qu''un document Word a un peu plus de "cachet" qu''état Access, ne serait-ce que par la mise en page.

I-B - Les différents types de publipostages qui seront abordés

I-B-1 - Le publipostage traditionnel

Communication entre Word et Access.

Cette manière de faire est la plus répandue, Word permet de choisir une multitude de sources pour effectuer le publipostage. On peut le faire au départ d'un fichier Word, Excel, Access ou tout autre fichier qu''il soit issu d'une base de données ou non.

Cette forme de publipostage ne sera pas abordée dans le cadre de ce tutoriel.

I-B-2 - Le publipostage au départ d'Access.

Avec ce mode de publipostage, Access va prendre le contrôle de Word pour exécuter les actions nécessaires au publipostage traditionnel. Word va attendre les commandes DDE d' Access pour effectuer le publipostage.

I-B-3 - Le publipostage au départ de "recordset" pour une publication et impression page par page.

Cette façon permet de remplir un document en atteignant des signets qui ont été préalablement placés dans ce document. On va ainsi indiquer à Access l'endroit dans le document Word où il pourra inscrire les données.

I-B-4 - Le transfert de données dans un document Word

Le transfert de données de Word vers Access, peut par exemple permettre de traiter des contrats avec clauses en Access, où l'on se trouve avec une bibliothèque de clauses et qu'il suffit de piocher pour ajouter les clauses au contrat. Un export des données vers Word, permettrait de faire une mise en page plus élégante.

I-B-5 - L'envoi massif de mail via Outlook.

On pourrait utiliser cette méthode pour l'envoi d'une News Letter au départ d'Access via Outlook.

I-B-5-a - Publipostage depuis Access : Comment faire ?

Il faut avant toute chose définir la source de données et la destination de ces données.

La source n'est plus une surprise, c'est une base de données Access et principalement une table qui contiendra les données relatives aux personnes ou organisations.

Ces données devront au moins contenir un nom, éventuellement un prénom, une adresse. Certaines petites choses vont ajouter un cachet supplémentaire, comme le sexe, _.

Pour la première partie du tuto, nous allons utiliser la base de données fournie en exemple avec Office, "Comptoir.mdb". Un document principal de fusion sera aussi nécessaire pour permettre le publipostage.

I-B-5-b - Préparer les données.

Dans notre cas, les données sont existantes et il suffit simplement d'utiliser ce qui nous est fournis.

I-B-5-c - Préparation du document principal de fusion.

Un document principal de fusion, c'est un document Word qui contient les champs de fusion. On peut facilement visualiser ces champs par leur couleur grise lors de leur sélection.

Pour arriver à ce document, il faut réaliser certaines actions.

Création d'un nouveau document. Pour ce document, on peut soit utiliser une lettre ou tout autre document existant.

Afficher la barre d'outils fusion et publipostage.

Si elle n'est pas visible, le fait d'aller dans le menu Outil :: Fusion et Publipostage fait apparaître la barre d'outils.

Le premier outil permet de choisir le type de document que nous allons réaliser.

La boîte de dialogue associée.

Les choix proposés sont sans équivoque.

Le second bouton permet de choisir la source de données.

S'ouvre alors la boîte de dialogue traditionnelle permettant de choisir un fichier qui sera de préférence un MDB.

Pour éviter d'avoir trop d'enregistrements, nous allons utiliser la table Employés.

La table client aurait aussi pu convenir, mais elle comporte plus d'enregistrements et le but n'est pas de faire une longue liste.

La partie qui nous intéresse le plus est la suivante :

L'insertion des champs de fusion. Ce sont ces champs qui vont recevoir les données en provenance d'Access.

Ces champs, on les choisit dans une liste. Cette liste reprend les champs présents dans la table Employés.

Pour le reste, c'est un document presque normal.

Il est possible de vérifier que les champs que nous avons choisis sont bien des champs de fusion en cliquant sur le champ. Une fois sélectionné, le champ devient gris

Il ne reste plus qu'a sauvegarder le document.

Une fois sauvegardé, le document devient un document principal de fusion.

C'est en quelque sorte un document qui est prêt à être fusionné.

Lors de ces étapes, un assistant s'est normalement ouvert. Si l'on continue avec l'assistant, on finira avec un document fusionné. Ce n'est pas réellement ce qui nous intéresse.

I-B-5-d - Modification de la base de données "Comptoir"

La première chose à faire, c'est de copier la base de données comptoir dans un répertoire différent j'ai choisi le répertoire suivant sur mon PC, mais un autre répertoire fera tout aussi bien l'affaire : "C:\Local Data\Access\Publipostage\". Ce qui sera important, c'est d'avoir l DB et les documents dans le même répertoire.

Le répertoire d'origine est :

" C:\Program Files\Microsoft Office\OFFICE11\SAMPLES\comptoir.mdb ".

Le choix s'est porté sur cette base de données car elle contient tout ce dont nous avons besoin, y compris les données.

I-B-5-e - Ajout d'une procédure

La première étape est l'ajout d'un nouveau module. Nous nommerons ce module "Publipostage".

Dans ce module, nous allons ajouter une procédure pour effectuer le publipostage.

Cette procédure sera appelée "MergeIt()"

Cette procédure est assez simple.

Sub MergeIt()
Dim objWord As Word.Document
Set objWord = GetObject("C:\Local Data\Access\Publipostage\Publipostage.doc", "Word.Document")
' Rend Word visible important puisque la fusion se fait à l'écran.
objWord.Application.Visible = True
' Sélectionne .la base de données Comptoir comme source de données pour la fusion
objWord.MailMerge.OpenDataSource _
Name:="C:\Local Data\Access\Publipostage\Comptoir.mdb", _
LinkToSource:=True, _
Connection:="TABLE Employés", _
SQLStatement:="SELECT * FROM [Employés]"
' Exécution de la fusion.
objWord.MailMerge.Execute
Set objWord = Nothing

End Sub

Le principe est aussi assez simple, on va ouvrir Word et piloter Word depuis Access avec une procédure propre à Word, le MailMerge, qui est la fonction de publipostage.

I-B-5-f - Ajout d'un formulaire

Ce formulaire va servir à lancer la procédure de publipostage.

Pour ce faire, nous allons créer un formulaire simple sans l'aide de l'assistant.

Nouveau Formulaire en mode création.

Pour être créatif, le formulaire recevra le nom "Publipostage"

Sur ce formulaire, nous allons placer un bouton. Le nom de ce bouton sera cmdMergeIt.

Dans la fenêtre des propriétés et sur l'évènement Click du bouton, nous allons faire appel au générateur de code.

Private Sub cmdMergeIt_Click()

Call MergeIt

End Sub

Le bouton va donc appeler la procédure qui va exécuter la fusion.

I-B-6 - Publipostage à l'aide de Recordsets et de signets

Cette méthode de publipostage diffère de la précédente par la méthode de communication utilisée avec Word.

Dans l'exemple précédent, nous avons utilisé les champs de publipostage.

Ici, nous allons utiliser les Signets (bookmark) et tenter d'atteindre ces signets pour y insérer des données.

I-B-6-a - Préparation des données

Comme pour l'exemple précédent, nous allons utiliser la base de données Comptoir et un nouveau document Word "BM Publipostage.doc".

I-B-6-b - Préparation du document.

Il faut créer un nouveau document Word dans lequel nous allons insérer des signets.

Pour insérer les signets, Insérer :: Signets.

Le plus simple est de se positionner sur le document exactement où l'on insère le signet. C'est à cet emplacement que le texte sera inséré.

Pour vérifier que les signets ont correctement été mis en place, la vérification se fait comme suit.

Edition :: Atteindre : une boîte de dialogue s'ouvre, on choisit l'objet que l'on veut atteindre, dans notre cas, Signet et une liste des signets disponible apparaît, il suffit de choisir le signet que l'on veut atteindre, et le curseur va se déplacer à l'endroit du signet.

I-B-6-c - Modification de la base de données Comptoir

Une fois de plus, nous allons avoir besoin d'un module. Le module publipostage semble être tout indiqué.

Sub MergeBM()
Dim wApp As Word.Application
Dim chemin As String
Dim rs As DAO.Recordset
Dim db As DAO.Database
Dim sql As String
sql = "SELECT * from Employés"

Set db = CurrentDb
Set rs = db.OpenRecordset(sql)
Set wApp = New Word.Application
chemin = currentproject.path
wApp.Visible = True

While Not rs.EOF
With wApp
.Documents.Open (chemin & _\BM Publipostage.doc_)
.ActiveDocument.Bookmarks("nom").Range.Text = rs.Fields("nom")
.ActiveDocument.Bookmarks("prenom").Range.Text = rs.Fields("prénom")
.ActiveDocument.PrintOut
.ActiveDocument.Close (wdDoNotSaveChanges)
End With
rs.MoveNext
Wend
rs.Close
Set rs = Nothing
db.Close
Set db = Nothing

Set wApp = Nothing
End Sub

Par le même principe que dans l'exemple précédent, on va prendre contrôle de Word en Access.

Pour extraire les données pour le publipostage, nous allons utiliser un recordset qui contiendra les données de la table. Pour chaque enregistrement, nous allons créer un nouveau document, ensuite après impression, le fermer sans enregistrer les changements.

Pour l'édition du document, nous allons nous positionner sur les signets et y insérer le texte issu de notre DB.

Comme nous avons déjà un formulaire, le plus simple est de reprendre ce formulaire.

On va y ajouter un second bouton pour effectuer notre publipostage avec recordset et bookmark.

Le nom de ce bouton, pour faire dans l'originalité sera "cmdMergeBM".

Private Sub cmdMergeBM_Click()

Call MergeBM

End Sub

Ce second bouton fera appel à notre procédure.

I-B-7 - Transfert intégral de données en Word

Il est parfois intéressant de faire un transfert intégral de données vers Word pour en assurer l'impression. On pourrait envisager une impression de contrat, où toutes les clauses contractuelles seraient en Access. On pourrait piocher dans une bibliothèque de clauses contractuelles, pour ensuite les envoyer vers un document Word pour être imprimé et éventuellement modifié.

I-B-7-a - Base de données

Comme la base de données comptoir ne convenait pas vraiment à cette partie, j'ai refait une base de données disponible en téléchargement.

Cette base de données simule de façon très sommaire une gestion de contrat avec clauses contractuelle.

La base de données comportera quatre tables.

tblClause

idClause

Numéro Auto

Clé primaire

stRubrique

Texte

15 caractères

stClause

Mémo

tblClient

Idclient

Numéro Auto

Clé primaire

stNom

Texte

30

stPrenom

Texte

30

stAdresse

Texte

30

stVille

Texte

25

stCP

Texte

6

stTitre

Texte

8

stEmail

Texte

50

tblContrat

idContrat

Numero Auto

Clé primaire

idClient

Numérique

Entier long

dtDate

Date

stRaison

Mémo

stTexteLibre

Mémo

tblDetailContrat

idDetCon

Numéro Auto

Clé primaire

IdContrat

Numérique

IdClause

Numérique

Tous les Id sont numériques et lorsqu'ils sont en clé primaire, ce sont des NuméroAuto.

Les formulaires clauses et clients ont été faits à l'aide de l'assistant.

Le formulaire d'accueil

Ce formulaire permet de naviguer vers les trois formulaires de manipulation de données.

Seul le formulaire contrat permet de faire le transfert des données Access vers Word.

Code qui permet de faire appel à la procédure de transfert au départ du formulaire contrat.

Private Sub CmdExportWord_Click()
Call TrfText(idContrat)

End Sub

Sans grande surprise, c'est le bouton export vers Word qui va à l'aide d'une procédure transférer les données dans un document Word.

I-B-7-b - Document Word.

Le Document Word, sera un document vide avec comme nom de fichier "contrat.doc".

Le fichier devra être dans le même répertoire que la base de données par exemple :"c:\Local Data\Access\Publipostage\"

I-B-7-c - Détail du Code

'******************************************************************************
'*  Procédure pour l'export de texte vers un document Word
'*  Utilisé dans le cadre d'un tuto pour le publipostage
'*
'******************************************************************************
Public Sub TrfText(idctrt As Integer)
Dim rs01 As Recordset
Dim rs02 As Recordset 'recordset de la table client
Dim rs03 As Recordset 'recordset de la table clause
Dim db As Database
Dim stSQL01 As String
Dim stSQL02 As String
Dim stSQL03 As String
Dim strChemin As string
strChemin = CurrentProject.Path
Dim wApp As Word.Application
Set wApp = New Word.Application
wApp.Visible = True 'permet d'afficher à l'écran le transfert de texte

'ouverture du document Word
wApp.Documents.Open strChemin & "\contrat.doc"
stSQL01 = "Select * from tblcontrat where idcontrat =" & idctrt
Set db = CurrentDb
Set rs01 = db.OpenRecordset(stSQL01) 'défnition du premier recordset table contrat
'insérer le code d'appel pour insertion dans Word
With wApp.Selection
.TypeParagraph 'ajoute une ligne en Word
.TypeText "Contrat  " 'insertion de donnée de type texte
.TypeText rs01.Fields("idContrat") 'insertion des données issues du recordset
.TypeParagraph
.TypeText "En date du  " & rs01.Fields("dtDate")
.TypeParagraph
.TypeParagraph
End With
stSQL02 = "select * from tblclient where idclient =" & rs01.Fields("idclient").Value
Set rs02 = db.OpenRecordset(stSQL02) 'définition du second recordset table client
With wApp.Selection
.TypeParagraph
.TypeParagraph
.TypeText rs02.Fields("sttitre") & " " & rs02.Fields("stNom")
.TypeParagraph
.TypeText rs02.Fields("stAdresse")
.TypeParagraph
.TypeText rs02.Fields("stCP") & "  " & rs02.Fields("stville")
.TypeParagraph
.TypeParagraph
End With

stSQL03 = "SELECT tblContrat.idContrat, tblClause.idClause, tblClause.stRubrique, " _&
"tblClause.stClause " _ &
"FROM tblContrat INNER JOIN (tblClause INNER JOIN tblDetailContrat " _ &
"ON tblClause.idClause = tblDetailContrat.idClause) "_ &
"ON tblContrat.idContrat = tblDetailContrat.idContrat " _&
"WHERE tblContrat.idContrat= " & rs01.Fields("idcontrat")
Set rs03 = db.OpenRecordset(stSQL03) 'définition de roisième recordset table clause
While Not rs03.EOF 'boucle pour récuperer les enreistrments de la table liée
With wApp.Selection
.TypeText rs03.Fields("strubrique")
.TypeParagraph
.TypeText rs03.Fields("stclause")
.TypeParagraph
.TypeParagraph
End With
rs03.MoveNext
Wend
' libération des objets
'afin de pourvoir manipuler le fichier Word, l'application n'est pas fermée
Set rs01 = Nothing
Set rs02 = Nothing
Set rs03 = Nothing
Set db = Nothing
End Sub

Dans l'appel de la procédure, on va mettre en argument le numéro du contrat qui est la base de tous les autres éléments. Cet état est reflété par la position centrale de la table contrat dans la DB.

De ce fait, la procédure peut être appelée de n'importe où dans l'application.

L'argument passé à la procédure va permettre de sélectionner l'enregistrement principal dans la table contrat. De cet enregistrement, et pas le biais des relations, on va obtenir les autres enregistrements qui nous seront utiles.

Pour obtenir ces valeurs, nous allons utiliser des Recordsets basés sur du sql. On va récupérer les données du premier Reccordset pour sélectionner les suivants.

Pour la clause stSQL03, qui semble assez complexe, j'ai utilisé le QBE de Access.

Il ne reste plus qu'à effectuer un copier coller dans le module et ajouter un critère Where " WHERE tblContrat.idContrat= " & rs01.Fields("idcontrat")"

La clause sql terminée

Clause SQL

stSQL03 = "SELECT tblContrat.idContrat, tblClause.idClause, tblClause.stRubrique, tblClause.stClause
FROM tblContrat INNER JOIN (tblClause INNER JOIN tblDetailContrat ON tblClause.idClause = tblDetailContrat.idClause)
ON tblContrat.idContrat = tblDetailContrat.idContrat WHERE tblContrat.idContrat= " & rs01.Fields("idcontrat")

L'extraction du Recordset est simple.

Un fois le Recordset extrait, il faut le parcourir pour en extraire tous les enregistrements et les transférer.

Une simple boucle qui va se terminer à la fin du fichier "rs03.EOF". Au cours de la boucle les données seront écrites dans le document word.

I-B-8 - Avec des images à insérer

Il est également possible de faire du publipostage avec des images à insérer. Le principe est de stocker le chemin de l'image dans un champ texte de la base de données. Pour ajouter l'image, nous allons faire appel à la collection InLineShapes.

Représente un objet situé dans la couche de texte d'un document. Une forme insérée ne peut être qu'une image, un objet OLE ou un contrôle ActiveX. L'objet InlineShape est membre de la collection InlineShapes. La collection InlineShapes contient toutes les formes insérées dans un document, une plage ou une sélection.
Et dans cette collection nous allons ajouter un objet avec la méthode AddPicture.

InLineShapes.AddPicture(FileName, LienVersFichier, EnregistrerAvecDocument, Étendue) où :
FileName : Chemin et nom de fichier de l'image.
LiensVersFichier : Affectez-lui la valeur True pour relier l'image au fichier à partir duquel elle a été créée. Affectez-lui la valeur False pour que l'image devienne une copie indépendante du fichier. La valeur par défaut est False.
EnregistrerAvecDocument : Affectez-lui la valeur True pour enregistrer l'image liée en même temps que le document. La valeur par défaut est False.
Etendue : Emplacement où se positionnera l'image dans le texte. L'image remplace la plage, si cette dernière n'est pas réduite ; si elle l'est, l'image est insérée. Si vous ne spécifiez pas cet argument, l'image se place automatiquement.

Dans le code ci-dessous, en plus de faire du publipostage, nous allons sauvegarder chaque document fusionné.

Public Sub publipost()
Dim oWord As Word.Application
Dim oDoc As Word.Document
Dim db As DAO.Database
Dim rs As DAO.Recordset

Set db = CurrentDb
Set rs = db.OpenRecordset("select * from tbl_nomImages")
Set oWord = New Word.Application

While Not rs.EOF
oWord.Documents.Add ("c:\local data\images\images.dot")
oWord.ActiveDocument.Bookmarks("bm1").Select
Selection.TypeText rs.Fields(1)
oWord.ActiveDocument.Bookmarks("image").Select
Selection.InlineShapes.AddPicture FileName:=rs.Fields(2), linktofile:=False, savewithdocument:=True

oWord.ActiveDocument.SaveAs "c:\local data\images\" & rs.Fields(1) & ".doc"
oWord.ActiveDocument.Close
rs.MoveNext
Wend
rs.Close
Set rs = Nothing
db.Close
Set db = Nothing
oWord.Quit
End Sub

Détail du code utilisé.

Code

Explications

Dim .........

Ces lignes servent à initialiser les variables qui seront utilisées dans le code.

Set db = CurrentDB

On affecte l'objet Base de donnée courante à la variable DB

Set rs = ..........

On va ouvrir un RecordSet

Set oWord .........

Affectation d'un Objet Application à notre variable oWord

While Not rs.EOF ---- Wend

Boucle qui va parcourir tous les enregistrements de notre RecordSet. La traduction serait Tant que la fin du fichier n'est pas atteinte, faire ce qui suit.

oWord.Documents.Add (" ")

On va ajouter un nouveau document à la collections de document de notre objet oWord.

oWord.ActiveDocument.Bookmarks("bm1").Select

On va sélectionner le signet "bm1" pour y insérer du texte.

Selection.TypeText rs.Fields(1)

Insertion du texte contenu dans le premier champ de l'enregistrement

oWord.ActiveDocument.Bookmarks ("image").Select

Sélection du signet Image

Selection.InlineShapes.Addpicture

On va ajouter une image

oWrd.ActiveDocument.SaveAs ......

La sauvegarde du document avec comme nom de fichier, le texte du premier champ de l'enregistrement

oWord.ActiveDocument.Close

On ferme le document, pour libérer des ressources

rs.MoveNext

On passe à l'enregistrement suivant

Avec les dernières lignes, on va libérer les objets avant de quitter la procédure.

Si vous utilisez cette méthode, pour chaque enregistrement, vous obtiendrez un ficher comportant une image.

Dans les exemples précédents, nous avons utilisé pour extraire les données des Recorset en utilisant le nom du champ : rs03.Fields("stclause"). Dans ce dernier exemple de code, nous avons utilisé l'index du "Fields" : rs.Fields(1).

Tutoriel sur le DAO avec initiation aux Recordset.

II - Publipostage vers le mail

Le principe reste sensiblement le même. Mais au lieu d'envoyer les données vers Word, on va les envoyer vers Outlook.

II-A - News Letter

Vers Word, on ne rencontrait pas de difficulté, puisque tous les éléments allaient dans le document actif, soit vers des champs de publipostage, des signets ou en mode continu.

Pour un mail, il y a d'autres paramètres à prendre en compte. Il faut des destinataires, un sujet pour le message et un corps de texte.

L'objet MailItem possède une multitude de propriétés et de méthodes.

Celles qui nous intéressent le plus sont les destinataires, le corps du message et le sujet.

Mailitem

To

Destinataire

CC

Destinataire en copie

BCC

Destinataire en Copie Cachés

Body

Corps de message

Subject

Objet du message

Send

Envoi (méthode)

SaveAs

Sauvegarde (méthode)

Pour ces destinataires, nous allons ajouter un champ Email dans la table client de notre application.

Nous allons aussi créer une nouvelle table pour contenir le contenu du message, l'objet et le corps du message. Comme le message envoyé peut changer lors de chaque envoi, nous allons utiliser un identifiant pour l'enregistrement, un champ texte pour le sujet et un champ mémo pour le corps du message.

Nous allons partir du principe que c'est toujours le dernier message qui va être envoyé " recordset.MoveLast ".

tblMessage

Nom du champ

Type de donnée

Indexé

Idmess

NuméroAuto

Clé primaire

strObjet

Texte

100 caractères

txtCorps

Mémo

dtCrea

Date

Valeur par défaut Date()

Public Sub EnvoiMassif()
'Ajouter les références suivantes :
'Microsoft Outlook
'Microsoft DAO
Dim oApp As Outlook.Application
Dim oMail As Outlook.MailItem
Dim oDB As DAO.Database
Dim strContenu As String
Dim oRst0 As DAO.Recordset
Dim oRst1 As DAO.Recordset
Dim strTo As String
Dim sqlMail As String
'Instancie Outlook
Set oDB = CurrentDb
Set oApp = CreateObject("Outlook.Application")
'Crée un nouveau message
sqlMail = "SELECT  * FROM tblMessage;"
Set oRst0 = oDB.OpenRecordset(sqlMail)
oRst0.MoveLast
Set oMail = oApp.CreateItem(olMailItem)
oMail.Body = oRst0.Fields("txtcorps")
oMail.Subject = oRst0.Fields("strObjet") & " du " & oRst0.Fields("dtCrea")
'Ouvre un recordset sur les clients
Set oRst1 = oDB.OpenRecordset("SELECT stEmail FROM tblClient")
'Boucle sur chaque client et les ajoute au champ BCC du mail
While Not oRst1.EOF
strTo = strTo & oRst1.Fields("stEmail") & "; "
oRst1.MoveNext
Wend
'Supprime la dernière virgule
oMail.BCC = Left(strTo, Len(strTo) - 2)
'Envoi du mail
oMail.Send
oRst0.Close
oRst1.Close
Set oRst0 = Nothing
Set oRst1 = Nothing
Set oDB = Nothing
'Ferme Outlook
oApp.Quit
Set oApp = Nothing
End Sub

Dans le traitement des données, nous avons deux étapes : la première est la récupération des données du message, la seconde la récupération des destinataires qui doivent figurer sur une seule ligne.

Pour le message, un recordset basé sur une table et un déplacement sur le dernier enregistrement : Recordset.MoveNext.

Pour les destinataires, un Recordset qui sera parcouru pour ajouter les destinataires à une variable texte.

While Not oRst1.EOF
strTo = strTo & oRst1.Fields("stEmail") & "; "
oRst1.MoveNext
Wend

Lors de chaque passage, on va ajouter une nouvelle adresse mail à la variable « strTo ». Et ensuite, appliquer cette variable au champ BCC.

L'utilisation de BCC permet aux différents destinataires de ne pas se voir dans le mail et de cette manière, si un farfelu devait faire une réponse à tous, seul l'expéditeur verrait la réponse.

Mise en garde : le Spam est puni par la loi.

II-B - Mail au format HTML

II-B-1 - Notion de HTML

Le HTML, Hyper Text Markup Language est basé sur l'interprétation de balise par le programme qui reçoit le texte. Dans la plupart des cas, un navigateur Internet.

Avec l'évolution, d'autres logiciels de communication se sont mis aussi au HTML pour enrichir le format.

Parmi ces derniers figurent les logiciels de Mail. L'envoi de mail au format HTML a permis d'enrichir les messages de balises actives, de texte et images animées,_..

Pour que le HTML soit actif dans les messages il est important de le déclarer.

On va le déclarer avec le strHTML.

Le HTML utilise des balises, pour italique </i>, les balises ouvertes doivent être fermées </i>.

Avec la méthode précédente, le texte du mail était envoyé en texte brut, sans formatage.

Pourquoi le format HTML : parce qu'aujourd'hui, il est supporté par la grande majorité des logiciels de mail, et plus, c'est un format universel.

II-B-2 - Modification du Formulaire

Nous allons ajouter un bouton de plus sur le formulaire message. Ce bouton fera appel à la procédure htmlMail().

Private Sub cmdeSendHtml_Click()
Call htmlMail
End Sub

II-B-3 - Mise en forme du HTML

Pour faciliter l'introduction des tags html, j'ai ajouté quelques boutons. Je remercie les personnes qui se reconnaîtront dans cette partie.

Pour utiliser ces boutons, il suffit de faire une sélection du texte et de cliquer sur le bouton, les balises vont s'insérer de chaque côté de la sélection.

Comme on a décidé d'envoyer du texte HTML, il faut utiliser le bouton d'envoi HTML.

II-B-4 - Code

Nous allons ajouter ce code au module Envoimail.

Public Sub htmlMail()
Dim strHTML As String
Dim oApp As Outlook.Application
Dim oMail As Outlook.MailItem
Dim oDB As DAO.Database
Dim strContenu As String
Dim oRst0 As DAO.Recordset
Dim oRst1 As DAO.Recordset
Dim strTo As String
Dim sqlMail As String
Set oDB = CurrentDb
Set oApp = CreateObject("Outlook.Application")
'Crée un nouveau message
sqlMail = "SELECT  * FROM tblMessage;"
Set oRst0 = oDB.OpenRecordset(sqlMail)
oRst0.MoveLast
Set oMail = oApp.CreateItem(olMailItem)
strHTML = "<!DOCTYPE HTML PUBLIC ""-//W3C//DTD HTML 4.0 Transitional//EN"">" & _
"<HTML><HEAD>" & _
"<META http-equiv=Content-Type content=""text/html; charset=iso-8859-1"">" & _
"<META content=""MSHTML 6.00.2800.1516"" name=GENERATOR></HEAD>" & _
"<BODY><DIV STYLE=""font-size: 16px; font-face: Tahoma;"">"
oMail.HTMLBody = strHTML & oRst0.Fields("txtCorps") & "<hr>" & "</DIV></BODY></HTML>"
oMail.Subject = oRst0.Fields("strObjet") & " du " & oRst0.Fields("dtcrea")
'Ouvre un recordset sur les clients
Set oRst1 = oDB.OpenRecordset("SELECT stEmail FROM tblClient")
'Boucle sur chaque client et les ajoute au champ BCC du mail
While Not oRst1.EOF
strTo = strTo & oRst1.Fields("stEmail") & "; "
oRst1.MoveNext
Wend
'Supprime la dernière virgule
oMail.BCC = Left(strTo, Len(strTo) - 2)
'Envoi le mail
oMail.Send
'ferme le curseur
oRst0.Close
oRst1.Close
Set oRst0 = Nothing
Set oRst1 = Nothing
Set oDB = Nothing
'Ferme Outlook
oApp.Quit
Set oApp = Nothing
End Sub

On reprend les mêmes principes, on récupère le dernier message. On pourrait utiliser le message en cours. Mais le but étant le publipostage, je ne vais pas m'étendre plus sur la sélection d'enregistrement. Pour plus de détail, il y a un excellent travail de Christophe Warin sur le site de DVP concernant l'accès aux données par le DAO

III - Remerciements

En premier lieu, un grand merci à l'équipe de DVP qui a décidé de me faire confiance en m'accueillant en tant que membre.

Merci à Cafeine pour ses gros morceaux codes, Tofalu et Kikof qui m'ont encouragé dans ma démarche, et le soutien de tous les autres membres que je ne citerai pas pour être certain de ne pas en oublier.

Exemple du tuto (clic droit pour télécharger)