Attention : Programmeurs avertis connaissant un peu Access et Outlook uniquement !
Les listes de distribution disponibles dans Outlook
sont une solution, mais pas toujours idéale. Une des limitations de ce
procédé est que vous envoyez un seul mail avec dans les zones
A, CC ou CCi toutes les adresses de vos correspondants : Il suffit que votre
fournisseur d'accès vous interdise par exemple d'envoyer un message à
plus de 50 destinataires et que vous en avez 200 pour que vous soyez bloqué.
Avec cette astuce VBA, vous allez pouvoir constourner ce problème en
créant un E-Mail par personne. De plus, cette personne sera dans la zone
"A:", ce qui va lui donner l'impression que vous avez envoyé
ce mail à elle et elle seule ! Vous avez dit puissance ?
Nous allons donc imaginer une base de données Access "Client.mdb", dans laquelle il y a une table "T_Client". Cette table contient 3 champs : NomPrenom, Selectionne (case à cocher) et EMail. Il va s'agir de parcourir une requête "R_ClientSelectionne", et d'envoyer un E-Mail par Client dont le champ Selectionne est à Oui.
Pour commencer, il faut regarder en détail comment une procédure VBA peut créer un message et l'envoyer. Dans Outlook, créez un nouveau Module, et écrivez-y cette première routine :
Sub EnvoiMailSimple()
' Création d'une variable de type
E-Mail :
Dim EMail As Object
' Assignation de cette variable à
la création d'un nouveau Mail :
Set EMail = Application.CreateItem(olMailItem)
' Création de l'e-mail : Titre,
Corps du message, destinataire :
EMail.Subject = "Joli message"
EMail.Body = "Vive les vacances !"
EMail.To = "truc@machin.com"
' Placement de l'e-mail dans la boîte
d'envoi :
EMail.Send
' Libération de la variable-objet
:
Set EMail = Nothing
End Sub
Normalement, après exécution de cette macro, vous devriez retrouver votre message dans votre dossier "Boîte d'envoi"
Le code va être le même, mais comme nous pilotons un programme Office (Outlook) depuis un autre (Access), la définition des variables doit être plus pointue. Lancez Access, et créez une nouvelle base de données Client.mdb. N'y créez pour l'instant aucune table, allez directement dans "Modules", et créez un nouveau module.
Une fois dans l'environnement VBA Access, comme nous allons avoir besoin d'utiliser des objets Outlook, il faut qu'on charge la bibliothèque Outlook. Allez dans le menu Outils/Références, et cochez la case "Microsoft Outlook 11.0 object library". le 11.0 veut dire version 2003 : si vous avez XP, c'est 10.0, 2000, c'est 9.0 et 97 c'est évidemment 8.0.
Placez y ce code :
Sub EnvoiMail()
' Déclaration d'une variable Application
de l'objet Outlook :
Dim MonOutlook As Object
Set MonOutlook = Outlook.Application
Dim EMail As Object
Set EMail = MonOutlook.CreateItem(olMailItem)
EMail.To = "haha@hoho.com"
EMail.Body = "Je suis dans Access"
EMail.Subject = "Vive Access"
EMail.Send
Set EMail = Nothing
End Sub
Constatez qu'il ressemble fortement au code directement exploitable par Oulook que nous avons vu juste avant.
Alors attention, à partir de la version XP (je crois), vous aurez un message "Un programme tente d'envoyer automatiquement du courrier électronique en votre nom, l'autorisez-vous à poursuivre ?". Pour pouvoir répondre Oui, il faut absolument attendre quelques secondes que la barre de progression aie terminé de s'afficher.
La raison en est simple : en effet, comme c'est un programme externe qui tente de créer un e-mail, il se pourrait que ce soit un virus ou un programme malveillant que vous auriez exécuté par mégarde, c'est pourquoi vous devez supporter ce message et son attente. Pourquoi faut il attendre quelques secondes ? simplement xar si un programme virus essayait d'envoyer un e-mail à votre place et cliquer sur OK à votre place, vous n'auriez pas le temps de lire l'avertissement.
Vous pouvez également exécuter ce code même si Outlook est fermé.
Plus rien à voir avec VBA, maintenant que nous pouvons créler un E-Mail depuis Access, conceptualisons notre table et notre requête. Créez la table suivante :
Nom :
T_Client
Champs:
NomPrenom : Texte
EMail : Texte
Selectionne :Oui/Non
Données :
NomPrenom | Selectionne | |
André Agassi | agassi@hotmail.com | OUI |
Bernard Montiel | b.montiel@france.fr | OUI |
Charles Dumont | charles@dumont.com | NON |
Daniel Muller | d_muller@muller.com.au | OUI |
Créez maintenant une requête basée sur cette table, qui contient les 3 champs, mais qui inclut seulement les "Selectionne". Vous devriez avoir ce résultat :
André Agassi | agassi@hotmail.com | OUI |
Bernard Montiel | b.montiel@france.fr | OUI |
Daniel Muller | d_muller@muller.com.au | OUI |
Enregistrez cette requête sous R_ClientSelectionne
Je vous conseille de lire cette page si vous n'êtes pas familier avec ADO.
On commence par voir si l'ouverture de la requête se passe bien :
Sub ParcourtRequete()
' Déclaraion d'une variable ADO
:
Dim MaBase As New ADODB.Recordset
' On ouvre la requête par ADO :
MaBase.Open "R_ClientSelectionne", CurrentProject.Connection
' On se positionne sur le premier enregistrement
:
MaBase.MoveFirst
' On affiche le contenu du champs NomPrenom
et EMail :
MsgBox MaBase("NomPrenom")
MsgBox MaBase("EMail")
' On va sur le suivant :
MaBase.MoveNext
MsgBox MaBase("NomPrenom")
' On ferme proprement et on libère
la variable :
MaBase.Close
Set MaBase = Nothing
End Sub
Modifions notre code par l'insertion d'une boucle qui va parcourir tous les enregistrements jusqu'à la fin (EOF = End Of File) :
Consultez cette page si vous ne connaissez pas bien l'utilisation de WHILE ... WEND, ou DO ... LOOP
Corrigez le code en conséquence :
Sub ParcourtRequete()
Dim MaBase As New ADODB.Recordset
MaBase.Open "R_ClientSelectionne", CurrentProject.Connection
MaBase.MoveFirst
' Tant qu'on est pas sur la fin des enregistrements
:
While Not MaBase.EOF
MsgBox MaBase("NomPrenom")
MsgBox MaBase("EMail")
MaBase.MoveNext
Wend
MaBase.Close
Set MaBase = Nothing
End Sub
Il ne s'agit donc pas de simplement afficher les enregistrements avec MsgBox, mais de leur envoyer à chacun un E-Mail :
Sub ParcourtRequete()
Dim MonOutlook As Object
Dim EMail As Object
Set MonOutlook = Outlook.Application
Dim MaBase As New ADODB.Recordset
MaBase.Open "R_ClientSelectionne", CurrentProject.Connection
MaBase.MoveFirst
While Not MaBase.EOF
Set EMail = MonOutlook.CreateItem(olMailItem)
EMail.To = MaBase("EMail")
EMail.Subject = "Déménagement"
EMail.Body = "Madame, Monsieur, Nous vous informons
que nous allons déménager"
EMail.Send
MaBase.MoveNext
Wend
MaBase.Close
Set MaBase = Nothing
Set EMail = Nothing
End Sub
Cette solution fonctionne, mais n'est pas parfaite. En effet, à chaque client, Outlook croit que c'est à chaque fois l'intrusion d'un virus, et impose le message d'attente à chaque fois, ce qui est élvidemment casse-pieds...
Un petit exécutable, que vous trouverez à cette adresse permet d'outrepasser cette limite (je n'ai pas testé)
Pour contourner ça, on pourrait imaginer créer une chaîne de caractère qui se complète gentiment à chaque tour de boucle et qui, à la fin place tous les destinataires d'un seul coup dans le A:; ou le CC, mais si le provider limite le nombre de destinataires simultanés, ça ne va pas non plus... On peut également utiliser EMail.Recipients.Add
Ou alors... Au lieu de faire tourner cette macro depuis Access, la faire tourner depuis le VBA Outlook : comme C'est Outlook lui-même qui crée les messages, on se débarasse de ce message d'attente...
Pour avoir de jolies mises en forme, on peut imposer le format HTML dans le
message, comme ceci :
EMail.BodyFormat = olFormatHTML
Mais il faut alors insérer correctement les balises HTML dans :
EMail.Body = "<HTML><strong>Bonjour</strong><BR>Les
amis</HTML>"