Envoi automatique de mail (avec pièce jointe) en vba : excel, word ou access par oulook express ou modzilla thunderbird ou d

Description

Module en VBA qui s'utilise aussi bien avec Access qu'avec Word ou Excel.
Il envoie automatiquement un mail (avec pièce jointe si on désire).
Ce Programme est sans prétention : Pas d'appel à des API plus ou moins obscures pour les débutants.
Il s'adresse plutôt à ces derniers car il est TRES documenté (environ les 3/4 des lignes sont des commentaires)
Je l'ai testé avec Word, Excel et Access. Et avec 3 clients de messagerie Outlook Express, Mozilla Thunderbird et Office Outlook. Mais il est très facile à adapter à d'autres clients (Eudora....).
Je fournis un exemple d'utilisation avec Excel : A l'ouverture du classeur on vérifie si, dans une liste de tâches, certaines sont arrivées à échéance et on envoie automatiquement un mail avec le nom des tâches en question.

Cette version comporte quelques améliorations suggérées dans les commentaires depuis la parution (mai 2005) jusqu'à aujourd'hui (16/01/2008) :

Des clients de messagerie nouveaux
La possibilité d'envoyer des plages Excel
La gestion des copies et copies cachées
L'utilisation du copier coller pour des corps volumineux...

Un résumé des questions posées jusqu'à présent dans les commentaires
- Si vous voulez éviter l'ouverture de la fenêtre et que vous utilisez Outlook 2003 (à essayer avec les autres versions d'Outlook), vous pouvez utiliser une autre méthode indiquée en fin de de Code(Elle ne figure pas dans le zip).
- Pour placer des caractères spéciaux dans le corps, utiliser les codes Hexa de ces caractères (exemple pour placer un saut de ligne dans le corps du message utiliser "%0A")
- La taille de l'URL transmise (donc du message) est limitée (à 817 caractères semble-t-il). Au delà il faut utiliser le copier/coller (cf dans le code)

Nouveautés dans le ZIP posté le 08/10/2008 :
-le choix de l'expéditeur du mail avec Thunderbird (certainement facile à adapter pour Outlook...).
-Toujours avec Thundrbird, forcer l'envoi du mail en HTML (c'est mieux pour les tableaux)
- Enfin j'ai amélioré le classeur Excel qui demande désormais le client mail utilisé avant d'envoyer le mail (avec les versions précédentes, l'envoi automatique à l'ouverture du classeur ne fonctionnait qu'avec thunderbird)

Merci pour toutes les questions posées (et les réponses fournies) qui me permettent d'améliorer cette source.

Source / Exemple :


'
' Ce module permet l'envoi d'un mail par le logiciel client SMTP par défaut du système
'
' le principe est de créer un lien de type "mailto:"
' et de demander au programme appelant de suivre ce lien
'
' Les arguments Adresse, Objet, Corps et Adresses de copie et de copie cachés sont fournis à la procédure
' qui les utilise pour définir l'hyperlien qui sera activé par la méthode
' FollowHyperLink du classeur actif
'
' le problème est que VB suit le lien
' (ici il lance le programme de messagerie en lui fournissant les infos nécessaires)
' puis se désintéresse du problème
' c'est donc à l'utilisateur de finir le travail :
' choix éventuel de la pièce jointe et envoi du message.
'
' pour automatiser complètement le processus,
' on utilise une méthode un peu simpliste mais efficace :
' simuler l'appui sur les touches à utiliser pour envoyer le message
' à l'aide de l'instruction SendKeys.
' en temporisant les envois successifs de touches, on y arrive très bien
'
' Inconvénient de la méthode : chaque logiciel de messagerie utilise ses propres
' menus (donc touches) pour joindre un fichier et envoyer le message
' par exemple : Outlook Express utilise le menu Intsertion (touche : Alt-I)
' puis le sous menu Pièce (touche : P)
' et l'envoi du message se fait par Alt-Entrée
'
' pour pallier à cet inconvénient, je propose de stocker dans 2 tableaux
' TouchesPJ() et TouchesEnvoi()
' l'enchaînement de touches à utiliser
' je fournis ici l'initialisation des tableaux pour les 3 clients de messagerie
' dont je dispose sur ma machine :
' Mozilla ThunderBird,
' Outlook Express,
' et Office 2003 Outlook (je ne pense pas que cela change pour les autres versions))
' il suffit donc d'activer l'initialisation qui va bien pour le client utilisé.
' on pourrait aller gratter dans la base de registre de Windows pour le trouver
' mais outre que si on tombe sur un logiciel de messagerie un peu exotique
' et non prévu dans notre liste, on est mal,
' surtout cela compliquerait un programme sans prétention mais qui est simple et accessible à tous
'
' Bon, assez parlé, un peu de code maintenant
' ------------------------------------------------------------------
Option Explicit
' ------------------------------------------------------------------
'Déclaration des tableaux qui recevront les touches à utiliser suivant
' le logiciel de messagerie par défaut du système.
' Déclarés ici, les tableaux ont une portée qui couvre tout le module
Dim TouchesPJ(5) As String, TouchesEnvoi(5) As String
' ------------------------------------------------------------------
' Procédure principale qui compose les éléments du message
' et effectue la demande d'envoi
' c'est cette procédure qui sera appelée par le programme principal (ici Excel)
'
Sub EnvoiEmail(Adresse As String, Objet As String, Corps As String, Optional PJ As String, Optional Cc As String, Optional Bcc As String, Optional Collage As Boolean)
' Remarques : seuls les arguments : Adresse, Objet et Corps sont obligatoires
' l'argument PJ (pièce jointe) est optionnel. S'il est fourni,
' c'est le chemin complet du fichier à joindre qui doit être fourni
' pour joindre plusieurs pièces,
' il faudrait que PJ soit un tableau et qu'il soit traité + bas par une boucle...
' les arguements Cc (copie) et Bcc (copie cachée) sont également facultatifs
' l'argument Collage permet d'indiquer à la procédure si elle doit coller
' le contenu du presse papier dans le corps du message
' Pour Excel, On peut envoyer une plage de cellule au lieu d'une cellule
' en utilisant dans le programme appelant les fonctions PH() ou PT() fournies + bas
'-----------------------------------------------------------------------------
' Quelques exemples d'appel de la procédure EnvoiMail depuis un classeur Excel
'
' Envoi simple sans pièce jointe :
' EnvoiMail Range("A1"), Range("A2"), Range("A3")

' Si les cellules sont nommées :
' EnvoiMail Range("Adresse"),Range("Sujet"),Range("Corps")

' Pour envoyer une plage :
' EnvoiMail Range("Adressse"),Range("Sujet"),PT(Range("A3:A10"))

' En utilisant les  arguements nommés (c'est le plus clair):
' EnvoiMail Adresse:= Range("A1"), _
'           Objet:= Range("A2"), _
'           Corps:= PH(Range("A3:A10")), _
'           Collage:= True _
'           PJ:= Application.Path & "\AJoindre.jpg" _
'           Bcc:="zorro@fantomas.com"
'--------------------------------------------------------------------------------
Dim HyperLien As String ' Reçoit les éléments de l'hyperlien
                        ' composés à partir des arguments fournis à la procédure
Dim i As Integer        ' un compteur
Dim Client As Integer
' la syntaxe de base du mailto est la suivante :
' mailto:dest@domaine.bof?Subject=Le sujet du message _
                         &Body=Le corps du message _
                         &cc=Destinataire copie _
                         &bcc=Destinataire copie cachée

HyperLien = "mailto:" & Adresse & "?"       ' Le ? introduit les arguments
HyperLien = HyperLien & "Subject=" & Objet & " (à " & Time() & ")"
If Not Collage Then ' (en cas de collage, le corps est ajouté juste avant le collage)
    HyperLien = HyperLien & "&Body=" & Corps    ' le & sépare les arguments
End If
If Cc <> "" Then HyperLien = HyperLien & "&cc=" & Cc
If Bcc <> "" Then HyperLien = HyperLien & "&bcc=" & Bcc

' Activation du lien
'
ActiveWorkbook.FollowHyperlink HyperLien    ' Pour Excel (les autres doivent être en commentaire)
'ThisDocument.FollowHyperlink HyperLien      ' Pour Word (les autres doivent être en commentaire)
'Application.FollowHyperlink HyperLien       ' Pour Access (les autres doivent être en commentaire)

        
Attendre 2                                  ' Appel d'une procédure qui temporise
                                            ' c'est à dire que la procédure courante
                                            ' (ici EnvoiMail) est suspendue pendant 5s
                                            ' cela permet d'Attendre que le client
                                            ' de messagerie soit lancé et prêt
                                            ' avant d'envoyer les touches
                                            ' sinon ce serait le programme appelant
                                            ' (ici Excel) qui recevrait les touches
                                            ' A REGLER selon votre config
                                            
' l'argument  de FollowHyperlink se plante au delà de 817 caractères
' donc pour les long messages, on peut utiliser le copier/coller
' C'est le programme appelant qui effectue le COPIER
' (éventuellement même une copie de cellules en tant qu'image : Selection.CopyPicture)
' la présente procédure se contente de COLLER le contenu du presse-papier
' si l'arguement Collage est à True
If Collage Then
    ' colle puis insère le texte du message au début du message
    SendKeys "+{INSERT}", True  ' collage
    SendKeys "^{HOME}", True    ' début du message
    SendKeys Corps, True        ' envoi du corps du message
    SendKeys "{Enter}", True    ' ligne suivante
End If
Client = 2  ' 1=Outlook Express
            ' 2=Mozilla Thunderbird
            ' 3=Office Outlook
            ' Suivent des configurations pour d'autres clients de messagerie
            ' trouvées sur le forum
            ' 4=Une autre version pour Outlook2003
            ' 5=Incredimail
            ' 6=Office Outlook 2007
            ' 7=...à vous d'ajouter d'autres clients

Select Case Client      ' appel du chargement des tableaux des touches selon le
                        ' client de messagerie indiqué
    Case 1
        OutLookExpress
    Case 2
        MozillaThunderbird
    Case 3
        Office2003OutLook
    Case 4
        Office2003OutLookV2
    Case 5
        Incredimail
    Case 6
        Office2007OutLook
    Case 7
        Office2000OutLook
    Case Else
        MsgBox "Aucun client de messagerie connu n'est indiqué"
        Exit Sub
End Select

' Le traitement de la pièce jointe ne s'exécute que si la procédure à reçu qqchose
' dans l'argument PJ (Optional<=>Facultatif)

If PJ <> "" Then
    For i = 1 To TouchesPJ(0)   ' dans TouchesPJ(0) on a stocké le nombre de touches
                                ' à envoyer au programme pour joindre une pièce
        SendKeys TouchesPJ(i), True     ' Envoie les touches d'ajout d'1 pièce jointe
        Attendre 1                        ' temporise (à règler éventuellement)
    Next i
    SendKeys PJ, True       ' A ce stade le programme Attend un nom de fichier
                            ' on lui envoie
    Attendre 1                ' on temporise
    SendKeys "{ENTER}", True    ' et on valide ce nom de fichier
    Attendre 1
End If
For i = 1 To TouchesEnvoi(0)
    SendKeys TouchesEnvoi(i), True  ' on envoie le message
Next i
End Sub

Sub Attendre(Secondes As Integer)
' Cette procédure temporise pendant le nombre de secondes qu'on lui transmet en argument
Dim Début As Long, Fin As Long, Chrono As Long
Début = Timer
Fin = Début + Secondes
Do Until Timer >= Fin
    DoEvents
Loop
End Sub

Sub OutLookExpress()
'Initialisation des tableaux de touches pour Outlook Express
    ' Pour une pièce jointe
    TouchesPJ(0) = 2        ' Nombre de touches nécessaires
    TouchesPJ(1) = "%i"     ' Appel du menu Insertion par la touche Alt-i
    TouchesPJ(2) = "p"      ' appel du sous-menu pièce par la touche p
    ' Pour l'envoi du mail
    TouchesEnvoi(0) = 1     ' Nombre de touches nécessaires
    TouchesEnvoi(1) = "%s"  ' Envoi du message avec Alt-s
End Sub

Sub MozillaThunderbird()
'Initialisation des tableaux de touches pour Mozilla Thunderbird
    ' Pour une pièce jointe
    TouchesPJ(0) = 4        ' Nombre de touches nécessaires
    ' il semble que l'appel par Alt-f du menu fichier ne marche pas
    ' à tous les coups donc (merci à FRED65200)
    TouchesPJ(1) = "{F10}"     ' Appel des menus par {F10}
    TouchesPJ(2) = "f"     ' Appel du menu Fichier par la touche f
    TouchesPJ(3) = "j"      ' appel du sous-menu Joindre par la touche j
    TouchesPJ(4) = "f"      ' appel du sous-sous-menu Fichier par la touche f
    ' Pour l'envoi du mail
    TouchesEnvoi(0) = 4             ' Nombre de touches nécessaires
    TouchesEnvoi(1) = "%xf"         ' choisit l'expéditeur qui commence par F
                                    ' à changer bien sur pour votre cas perso
    TouchesEnvoi(2) = "^{ENTER}"    ' Envoi du message avec Ctrl-Entrée
    TouchesEnvoi(3) = "{DOWN}"  ' Flèche bas pour choisir l'option "Envoyer en HTML seul"
                                    ' dans la boite dialogue
    TouchesEnvoi(4) = "{ENTER}"     ' confirmation par Entrée
End Sub

Sub Office2003OutLook()
'Initialisation des tableaux de touches pour Office Outlook 2003
    ' Pour une pièce jointe
    TouchesPJ(0) = 2        ' Nombre de touches nécessaires
    TouchesPJ(1) = "%i"     ' Appel du menu Insertion par la touche Alt-i
    TouchesPJ(2) = "f"      ' appel du sous-menu fichier par la touche f
    ' Pour l'envoi du mail
    TouchesEnvoi(0) = 1     ' Nombre de touches nécessaires
    TouchesEnvoi(1) = "%v"  ' Envoi du message avec Alt-v
End Sub

'--------------------------------------------------------
' Voici quelques contributions trouvées sur le forum
' pour d'autres logiciels de messagerie
' merci à leurs auteurs
' par contre, je ne les ai pas vérifiés
'--------------------------------------------------------

Sub Incredimail()
    ' Contribution de KOLOCO pour Incredimail
    ' Initialisation des tableaux de touches pour Incrédimail
    ' Pour une pièce jointe
    TouchesPJ(0) = 1        ' Nombre de touches nécessaires
    TouchesPJ(1) = "^+a"    'Appel du menu Insertion Fichier par la touche Ctrl+Shift+A
    ' Pour l'envoi du mail
    TouchesEnvoi(0) = 1     ' Nombre de touches nécessaires
    TouchesEnvoi(1) = "%s"  'Envoi du message avecAlt-s
End Sub

Sub Office2003OutLookV2()
    ' Version corrigée par CLARK1978 à essayer si la version d'origine ne gère pas
    ' la touche Alt-i correctement
    ' Initialisation des tableaux de touches pour Office Outlook 2003
    ' Pour une pièce jointe
    TouchesPJ(0) = 3            ' Nombre de touches nécessaires
    TouchesPJ(1) = "%a"         'Appel du menu Insertion par la touche Alt-a (affichage)
    TouchesPJ(2) = "{RIGHT}"    ' puis flèche à droite
    TouchesPJ(3) = "f"          ' appel du sous-menu fichier par la touche f
    ' Pour l 'envoi du mail
    TouchesEnvoi(0) = 1         ' Nombre de touches nécessaires
    TouchesEnvoi(1) = "%v"      ' Envoi du message avecAlt-v
End Sub

Sub Office2007OutLook()
    ' Contribution de PC512 pour Office 2007
    ' Initialisation des tableaux de touches pour Office Outlook 2007
    ' Pour une pièce jointe
    TouchesPJ(0) = 2        ' Nombre de touches nécessaires
    TouchesPJ(1) = "%s"     ' Appel du menu Insertion par la touche Alt-i
    TouchesPJ(2) = "jf"     ' appel du sous-menu fichier par la touche f
    ' Pour l'envoi du mail
    TouchesEnvoi(0) = 1     ' Nombre de touches nécessaires
    TouchesEnvoi(1) = "%v"  'Envoi du message avecAlt-v
End Sub

Sub Office2000OutLook()
    ' Contribution de TANATLOC92 pour Office Outlook 2000
    ' Initialisation des tableaux de touches pour Office Outlook 2000
    ' Pour une pièce jointe
    TouchesPJ(0) = 2 ' Nombre de touches nécessaires
    TouchesPJ(1) = "%i" ' Appel du menu Insertion par la touche Alt-i
    TouchesPJ(2) = "f" ' appel du sous-menu fichier par la touche f
    ' Pour l'envoi du mail
    TouchesEnvoi(0) = 1 ' Nombre de touches nécessaires
    TouchesEnvoi(1) = "^{ENTER}" ' Envoi du message avec Ctrl-Entrée
End Sub
'----------------------------------------------------------------------------------
' POUR ENVOYER UNE PLAGE DE CELLULES
'----------------------------------------------------------------------------------
' Les fonctions qui suivent sont adaptées à Excel
' elles permettent d'envoyer une plage de cellules plutôt qu'une seule cellule
' elles sont utilisées par le PROGRAMME APPELANT pour préparer le corps du message
'                             ------------------
' avant de le transmettre à la procédure EnvoiMail

' Première Version:
' Transforme une plage en tableau HTML
' (mais votre programme de messagerie risque de vous demander une confirmation
'  pour un envoi de message en HTML, ce qui rompt l'automatisme)

Function PH(LaPlage As Range) As String
    ' transforme une plage en tableau HTML
    Dim l As Long, c As Long
    PH = "<html><table width='100%'>" 'balises de début du code HTML et de début de  table
    For l = 1 To LaPlage.Rows.Count   ' pour chaque ligne de la plage
        PH = PH & "<tr>"              ' balise de début de ligne
        For c = 1 To LaPlage.Columns.Count  'pour chaque colonne de la ligne
            ' balise début de colonne +  contenu de la cellule + balise fin de colonne
            PH = PH & "<td>" & LaPlage.Cells(l, c) & "</td>"
        Next c
        PH = PH & "</tr>" ' balise fin de ligne
    Next l
    PH = PH & "</table></html>"  ' balises de fin de table et de fin de code HTML
    'MsgBox PH
End Function

' Deuxième Version:
' Transforme une plage en texte délimité avec Tabulations
Function PT(LaPlage As Range) As String
    ' transforme une plage en texte avec tabulations et retours ligne
    Dim l As Long, c As Long
    PT = ""
    For l = 1 To LaPlage.Rows.Count
        For c = 1 To LaPlage.Columns.Count
            PT = PT & LaPlage.Cells(l, c)
            If c < LaPlage.Columns.Count Then
                ' on ajoute une tabulation que si on n'est pas sur la dernière colonne
                PT = PT & "%09"  ' %09 est le code pour la tabulation (vbTab ne fonctionne pas ici)
            End If
        Next c
        PT = PT & "%0A"  ' %0A est le code pour le retour ligne (vbCrLf ne fonctionne pas ici)
    Next l
    'MsgBox PT
End Function

'---------------------------------------------------------------------------
'Autre méthode totalement différente et indépendante mais qui ne fonctionne
' QU'AVEC OUTLOOK. Elle fait appel à la technologie Automation (OLE)
' il faut ajouter la bibliothèque "Microsoft Outlook 11.0 Object Library"
' à votre projet
' son avantage principal : la fenêtre Outlook ne s'ouvre pas !!!
' autre avantage : c'est un peu plus élégant
' (merci à JeanMimi75)
' Pour le programme appelant l'utilisation est identique, il suffit de changer
' le nom de la procédure appelée (EnvoiMailMéthodeOLE au lieu de EnvoiEmail)
' par exemple :
' En utilisant les  arguements nommés (c'est le plus clair):
' EnvoiMailMéthodeOLE Adresse:= Range("A1"), _
'           Objet:= Range("A2"), _
'           Corps:= PH(Range("A3:A10")), _
'           PJ:= Application.Path & "\AJoindre.jpg" _
'           Bcc:="zorro@fantomas.com"
' Attention avec cette technique, le collage du contenu du presse-papier n'est pas géré
'----------------------------------------------------------------------------
Sub EnvoiMailMéthodeOLE(Adresse As String, Objet As String, Corps As String, Optional Pièce As String, Optional Cc As String, Optional Bcc As String)
    Dim MonAppliOutlook As New Outlook.Application
    Dim MonMail As Outlook.MailItem
    Dim MaPièce As Outlook.Attachments
    Set MonMail = MonAppliOutlook.CreateItem(olMailItem)
    With MonMail
        '.Display ' retirer le commentaire si vous voulez que le fenêtre Outlook s'affiche
        .To = Adresse
        If Not IsNull(Cc) Then .Cc = Cc
        If Not IsNull(Bcc) Then .Bcc = Bcc
        .Subject = Objet
        .Body = Corps
        If Not IsNull(Pièce) Then
            Set MaPièce = .Attachments
            MaPièce.Add Pièce, olByValue
        End If
        .Send
    End With
End Sub

Conclusion :


Placez ce code dans un module de votre document Excel, Word ou Access. Pour l'activation du lien, choisissez votre application (il est fourni ici pour Excel) et choisissez votre client (ici Mozilla ThunderBird). Si vous utilisez un autre logiciel de messagerie lisez les commentaires pour adapter le module à votre cas.

Si ça marche, utilisez le classeur Excel pour m'envoyer un mail ;-)

Si vous utilisez Word ou Access, supprimez les fonctions PH et PT qui ne fonctionnent qu'avec Excel.

Vous pouvez régler les temporisations en fonction de votre machine et de votre logiciel de messagerie

Si vous avez des séquences de touches pour d'autre clients de messagerie, envoyez-les moi que je les ajoute.

Bon codage
Jean

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.