Expédier des emails avec pièces jointes via Outlook
Comment expédier un email avec pièces jointes à partir d’Access ?
Le principe
Cet article complète l’article Expédier des emails via Outlook. Il reprend le même objet MailItem
, en utilisant en plus sa propriété Attachments
, qui permet d’ajouter des pièces jointes à un message. Les pièces jointes peuvent être en nombre quelconque, et de nature quelconque.
Le code Visual Basic
Recopiez le code ci-dessous dans un module standard d’Access :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
' --- ' ENVOYER UN MAIL DEPUIS ACCESS, AVEC PIECES JOINTES ' --- ' Entrée : strEmail <- Adresse e-mail du destinataire ' strObj <- Objet du courrier ' strMsg <- Corps du message ' blnEdit <- True pour pouvoir modifier le courrier avant envoi ' False pour expédier le courrier directement. ' astrFichiers <- Tableau des pièces jointes ' Remarques : Le mail est expédié via Microsoft Outlook ' plutôt que via SendObject. Public Sub SendOLMail2( _ ByVal strEmail As String, _ ByVal strObj As String, _ ByVal strMsg As String, _ ByVal blnEdit As Boolean, _ Optional ByVal avarFichiers As Variant) Dim ol As Outlook.Application Dim mi As Outlook.MailItem Dim varPJ As Variant ' Créer une instance d'Outlook On Error GoTo OLMailErr Set ol = New Outlook.Application ' Créer un objet Email Set mi = ol.CreateItem(olMailItem) ' Paraméter le message With mi .To = strEmail .Subject = strObj .Body = strMsg ' Joindre les pièces, s'il y en a For Each varPJ In avarFichiers .Attachments.Add (varPJ) Next If blnEdit Then .Display Else .Send End If End With Set mi = Nothing Set ol = Nothing Exit Sub OLMailErr: MsgBox "Erreur : " & Err.Number & vbCrLf & Err.Description Exit Sub End Sub |
Comment tester ?
La procédure SendOLMail2
, ci-dessus, reçoit les pièces jointes (leur chemin en fait) dans un tableau. Elle doit donc être appelée à partir d’un autre bout de code VBA. Par exemple :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
' --- ' TEST DE LA PROCEDURE SendOLMail2 ' --- ' Sub TestSendOLMail2() Dim astrFichiers(1 To 3) As String ' Chemin des 3 fichiers à joindre astrFichiers(1) = "C:...Stats Web.xls" astrFichiers(2) = "C:..Signature SelfAccess.html" astrFichiers(3) = "C:...chap03_rels.mdb" ' On expédie le message SendOLMail2 "email@fournisseur.com", _ "Quelques pièces jointes...", _ "Salut," & vbCrLf & "Ci-joint, quelques fichiers pour tester..." _ & vbCrLf & "-- Hervé Inisan.", _ True, _ astrFichiers End Sub |
Une fois ce code tapé (et les chemins de fichiers corrigés), placez votre curseur quelque part entre le Sub
et le End Sub
, puis cliquez sur l’icône Exécuter Sub/UserForm. Bien sûr, vous pouvez modifier les dimensions du tableau astrFichiers
, et ajouter d’autres pièces jointes si nécessaire.
bonjour,
Votre code marche s’il existe les pièces jointes mais s’il en manque une = c’est le bug fichier introuvable.
Comment modifier votre code pour qu’il ne prenne que les PJ existantes ?
merci pour votre aide
Mamanhou
Le code suppose effectivement que les chemins fournis pointent vers des fichiers corrects. Il faudrait tester en amont si les fichiers existent bien. Cet autre article peut aider pour le faire.
Bonjour tout le monde,
J’ai lu avec intérêt pas mal de tutos sur ce site super bien fait (Merci à Hervé pour le boulot), mais je bloque sur un morceau de code que j’ai construit en fonction des tutos que j’ai lu.
Fonction = envoi de mails spécifiques et personnalisés outlook à partir d’Access sur une sélection d’enregistrements (une requête s’en charge). J’arrive à bien faire ce que je veux sauf pour les pièces jointes. Je n’arrive pas à ajouter automatiquement les X pièces jointes dispo dans mon champ pièce jointe de ma table. Le recordset bloque à ce niveau.
J’ai essayé un bout de code « For each PJ etc etc… » mais sans succès. Une idée?
Code:
Sub Outlook2_Click()
Dim rst As DAO.Recordset
Dim strMessageType As String
Dim strTitre As String
Dim strMsg As String
Dim AQui As String
Dim Fichier As String
strTitre = « Echéance ATU {NomATU} pour {InitpatNOM}/{InitpatPRE} – Rappel »
strMessageType = « Bonjour Docteur {Medecin}, » _
& vbCrLf & vbCrLf _
& « L’ATU n°{NumeroATU} de {NomATU} pour le patient {InitpatNOM}/{InitpatPRE} arrive à échéance le {EcheanceATU}. » _
& vbCrLf & vbCrLf & « Veuillez trouver ci-joint un formulaire à compléter et à nous retourner en cas de demande de renouvellement » & vbCrLf _
& vbCrLf & vbCrLf & « Merci de préciser la tolérance et l’efficacité du médicament » _
& vbCrLf & vbCrLf & « Cordialement, » _
‘ Initialisation
strSQL = « SELECT * FROM [RelanceMail] »
Set rst = CurrentDb.OpenRecordset(strSQL, dbOpenSnapshot)
With rst
While Not rst.EOF
‘ Construire un message personnalisé
strTitre = Replace(strTitre, « {NomATU} », rst(« NomATU »))
strTitre = Replace(strTitre, « {InitpatNOM} », rst(« InitpatNOM »))
strTitre = Replace(strTitre, « {InitpatPRE} », rst(« InitpatPRE »))
strMsg = Replace(strMessageType, « {Medecin} », rst(« Medecin »))
strMsg = Replace(strMsg, « {NomATU} », rst(« NomATU »))
strMsg = Replace(strMsg, « {InitpatNOM} », rst(« InitpatNOM »))
strMsg = Replace(strMsg, « {InitpatPRE} », rst(« InitpatPRE »))
strMsg = Replace(strMsg, « {NumeroATU} », rst(« NumeroATU »))
strMsg = Replace(strMsg, « {EcheanceATU} », rst(« EcheanceATU »))
AQui = rst!Mail
‘ Fichier = rst!DocPUT (test par cette méthode mais ne fonctionne pas (DocPUT étant mon champ pièce jointe de ma requete/table)
‘commande l’envoie du mail
Envoie_Message_dadou5821 strTitre, strMsg, AQui ‘, Fichier
rst.MoveNext
Wend
End With
‘ Fermeture de la session Outlook et désallocation des objets
rst.Close
Set rst = Nothing
End Sub
Private Sub Envoie_Message_dadou5821(LeTitre As String, LeMessage As String, Destinataire As String, Optional ByVal avarFichiers As Variant)
Dim MonOutlook As Object ‘New Outlook.Application
Dim MonMessage As Object ‘Outlook.MailItem
Dim varPJ As Variant
Set MonOutlook = New Outlook.Application ‘avec reference outlook
‘Set MonOutlook = CreateObject(« Outlook.Application ») ‘sans reference outlook
Set MonMessage = MonOutlook.CreateItem(olMailItem)
‘Remplissage de l’objet MailItem
With MonMessage
.To = Destinataire
.Subject = LeTitre
.Body = LeMessage
.Attachments.Add « LOCALISATION FICHIER SYSTEMATIQUE »
‘ ici je souhaite ajouter les X pièces jointes de mon enregistrement selon l’enregistrement concerné mais fonctionne pas
For Each varPJ In rst
.Attachments.Add (varPJ)
Next
End With
MonMessage.Display
‘ MonMessage.Send
‘ Fermeture de la session Outlook et désallocation des objets
Set MonOutlook = Nothing
End Sub
J’ai peut-être raté quelque chose, mais j’ai l’impression que la variable
rst
n’existe pas la procédure Envoie_Message_dadou5821.Est-ce que ça peut être une piste ?
En effet,
rst étant mon recordset dans ma 1ère partie de code. Je l’ai déclaré dans la deuxième partie de code (envoi message dadou) mais rien n’y fait.
je pense que ce n’est pas un argument valide
Il faut non seulement que rst soit déclaré, mais aussi qu’il ait une valeur (la variable doit pointer un objet Recordset valide).
Sinon, que contient rst, et comment sont stockées les pièces jointes ?
Salut Hervé,
Tout d’abord merci pour ce site qui à été et reste une mine d’or inépuisable d’informations précieuses pour moi et bien d’autres 🙂
Je te solicite car j’ai un petit problème similaire à « Greed » d’Erreur -115396542 Ce chemin d’accès n’existe pas. Assurez vous qu’il est correct.” avec ce code et je ne trouve pas de solution :
Sub EnvoiMail_click()
‘ Initialisation :
Dim astrFichiers(1 To 3) As String
Dim strDest As String ‘ L’adresse e-mail du destinataire envoyée
Dim strMessage As String ‘ Le corps du message
Dim ListeEMail As Recordset ‘ Variable reçevant l’E-Mail de la liste
Set ListeEMail = CurrentDb.OpenRecordset(« R_EMailOUI ») ‘Requête contenant les E-Mails sélectionnés
Dim Message As String ‘ Message à Saisir
ListeEMail.MoveFirst ‘Positionnement au début de la liste
‘ Création du message
strObj = « Message de votre club préféré » ‘ Objet du Message
Message = InputBox(« Saisissez votre Message : », « Message à envoyer ») ‘Saisie du Message
astrFichiers(1) = InputBox(« Saisissez le lien vers la 1ère Pièce à joindre : », « Fichier à envoyer ») ‘Saisie de la P.J.
astrFichiers(2) = InputBox(« Saisissez le lien vers la 2ème Pièce à joindre : », « Fichier à envoyer ») ‘Saisie de la P.J.
astrFichiers(3) = InputBox(« Saisissez le lien vers la 3ème Pièce à joindre : », « Fichier à envoyer ») ‘Saisie de la P.J.
‘Corps du Message
strMessage = strMessage & vbCrLf & « Bonjour, »
strMessage = strMessage & vbCrLf & vbCrLf
strMessage = strMessage & Message
strMessage = strMessage & vbCrLf & vbCrLf
strMessage = strMessage & vbCrLf & « Cordialement, »
strMessage = strMessage & vbCrLf
strMessage = strMessage & vbCrLf & « Monsieur X »
‘ Création de la liste selon sélection :
While Not ListeEMail.EOF
strDest = ListeEMail(« E-Mail »)
SendOLMail strDest, strObj, strMessage, False, astrFichiers
ListeEMail.MoveNext
Wend
‘ Clôture des Fonctions !
MsgBox « Envoi du (des) mail(s) Terminé ! », vbInformation, « Information »
ListeEMail.Close
Set ListeEMail = Nothing
End Sub
le sendOLMail étant celui posté plus haut.
Pourrais-tu me sortir de ce mauvais pas ? 🙂 Merci d’avance de ton temps consacré 😉
Je vois que les chemins sont demandés manuellement par MsgBox. Ça peut augmenter le risque d’erreur de saisie, donc de chemin incorrect. Il y a aurait au moins 2 façons de gérer ça :
D’autre part, ton code attend systématiquement 3 fichiers, ce qui ne sera sans doute pas le cas tout le temps (il faudrait du coup adapter pour pouvoir gérer de 0 à n fichiers).
tadresse > Le premier bout de code –
SendOLMail2
– doit être placé dans un module standard, mais il n’est pas prévu pour être associé directement à un bouton (ça permet de le réutiliser pour plusieurs boutons).Par contre, tout ce qui est dans le bloc
TestSendOLMail2
peut faire l’objet d’un bouton, effectivement. C’est ce bloc qui déclenche l’appel de la procédure générique donnée au début.Bonjour je voudrais savoir si je peu placer ce code sur l’évènement click d’un boutton parce que j’essaye de puis et ca donne pas
Merci d’avance
biloux > Dans cet article-ci, tu as la procédure pour envoyer un fichier (quelconque) avec Access, du moment que tu connais son chemin. Regarde les articles qui parlent de la création de documents PDF, tu auras l’autre partie. Ce que tu souhaites, c’est enchaîner les deux :
bjr,
je souhaite envoyer un page d’un etat (access) via outlook. comment demander à outlook de recuperer un aperçu avant impression, de le convertir sous PDF avant de récupérer le chemin pour l’envoi;
Merci
Greed > Content que ça marche. 🙂
Bon dév’ !
C’est bon ça fonctionne, c’était bien au niveau de la déclaration du tableau que ça déconnait ^^
Merci beaucoup pour ces réponses claires et précises, très bon site au passage et si j’ai d’autres questions j’hésiterai pas :p
A la revoyure !
Greed > Le problème vient sans doute du
Dim astrFichiers(1)
. En VBA, si on ne met qu’un seul chiffre entre les parenthèses, ce chiffre est l’indice maximal du tableau, le tableau démarrant implicitement à 0. Ce qui veut dire que, dans ton cas,astrFichiers(0)
est vide, etastrFichiers(1
) contient un chemin. D’où sans doute le problème dans la boucle, le premier fichier étant introuvable.Pour éviter les ambiguïtés, remplace
Dim astrFichiers(1)
parDim astrFichiers(1 to 1)
. Dans ce cas, on précise explicitement l’indice de départ et l’indice d’arrivée.Pour ce qui est du
For Each
: je le garderais dansSendOLMail2()
, parce que ce bloc de code est une « boîte noire », il n’a pas besoin d’être retouché. Sinon, le jour où tu as 2 pièces jointes (ça peut arriver, donc ça arrivera ;-)), on doit remodifier…J’ai bien changé le chemin, mais j’ai fait une petite modif du coup, étant donné que je n’ai qu’un seul fichier à envoyer(fichier word).
J’ai mis : Dim astrFichiers(1) (au lieu de 1 to 3 mais à mon avis c’est pas ça le problème)
le chemin est assez long et commence par V: (mais comme j’ai fait un copié collé du chemin dans l’explorateur,avec la pièce jointe ensuite, il devrai pas y avoir de soucis)
A moins qu’il y ai un problème au niveau du ForEach ?
J’y pense à l’instant mais comme il n’y a qu’une seul pièce jointe peut-être qu’il n’y aurai pas besoin de ForEach ?
Greed > Comme dit dans l’article, tu as corrigé les chemins ? (pas de C:… mais quelque chose de réel)
Si ça peut aider, tu peux poster le chemin ici.
Bonjour, j’ai un problème avec cette procédure.
En fait, lorsque j’exécute le code, je reçois un message d’erreur de ce type : »Erreur -115396542 Ce chemin d’accès n’existe pas. Assurez vous qu’il est correct. »
J’ai bien vérifié plusieurs fois le chemin mais rien n’y fait, je ne comprend pas.
Si vous pouviez résoudre mon problème ce serai bien sympa.
Cordialement
Greed.
ZZDriver > Un peu tard pour la réponse… mais à vue de nez, c’est bien tout ça qu’il faut faire pour aménager le code !
Merci beaucoup pour la réponse, cela m’apprendra à lire correctement, j’ai confondu la référence » Microsoft Outlook 12.00″ et « Microsoft office 12.0 »
J’imagine que si je souhaite envoyer l’email en copie,
je dois ajouter sous la ligne :
« ByVal strEmail As String, _ »
la ligne :
« ByVal strEmailCC As String, _ »
Et sous la ligne:
« .To = strEmail »
la ligne :
« .CC= strEmailCC »
Et pour finir compléter la ligne dans le Sub:
« SendOLMail2 [email], _ »
avec:
« SendOLMail2 [email],[emailCC], _
[emailCC] étant le nom du champ qui contient, dans mon formulaire, l’adresse email à mettre en copie.
Si vous avez le temps de me le confirmer, je vous en remercie d’avance.
Excellent week-end.
ZZ
zzdriver > Il s’agit d’un problème de références. Le haut de cet article donne un lien vers un article précédent (Expédier des mails via Outlook) où la réponse est donnée. Bons tests !
Bonjour, je ne suis peut être pas très doué mais lorsque je test, j’ai un avertissement » Type défini par l’utilisateur non défini »
Les lignes suivantes sont surlignées en jaune :
Public Sub SendOLMail2( _
ByVal strEmail As String, _
ByVal strObj As String, _
ByVal strMsg As String, _
ByVal blnEdit As Boolean, _
Optional ByVal avarFichiers As Variant)
ET cette ligne est surlignée en bleu :
Dim ol As Outlook.Application
Mon logiciel de messagerie est bien Outlook.
Si vous aviez une idée, cela me rendrait bien service.
Cordialement,
ZZdriver