Email automatique Excel VBA : relances clients, alertes et rapports PDF en 1 clic
Code VBA prêt à l'emploi pour envoyer des emails personnalisés depuis Excel via Outlook relances impayés, alertes de stock, rapports PDF automatiques. Guide technique commenté, erreurs courantes et personnalisation sans coder.
L'envoi d'e-mails automatiques depuis Excel est l'une des automatisations les plus demandées et les plus rentables. Pas besoin de serveur, pas besoin de logiciel supplémentaire, pas d'abonnement : si votre poste a Outlook installé et configuré, vous pouvez envoyer des e-mails personnalisés depuis Excel en quelques lignes de VBA.
Dans ce guide, je vous présente 3 macros VBA fonctionnelles et commentées, adaptées aux cas d'usage les plus fréquents en PME. Chaque exemple est prêt à être copié-collé dans votre fichier et adapté à vos besoins sans connaissances en programmation.
Prérequis : ce qu'il vous faut avant de commencer
Activer la référence Outlook dans VBA
C'est l'étape que la plupart des tutoriels oublient de mentionner. Sans elle, votre macro renvoie l'erreur "Type défini par l'utilisateur non défini" dès qu'elle essaie de créer un objet Outlook.
- Ouvrez l'éditeur VBA : Alt + F11
- Menu Outils → Références
- Cochez "Microsoft Outlook XX.0 Object Library" (XX = votre version, ex : 16.0 pour Office 365)
- OK la référence est maintenant active
Si vous partagez votre fichier avec des postes ayant différentes versions d'Office, utilisez CreateObject("Outlook.Application") au lieu de déclarer Dim outApp As Outlook.Application. Cette approche "Late Binding" évite les problèmes de compatibilité de version mais perd l'autocomplétion dans l'éditeur VBA.
La structure de base d'une macro e-mail
Avant les exemples spécifiques, voici la structure fondamentale que toutes les macros d'envoi e-mail VBA partagent. Comprendre cette structure vous permettra d'adapter n'importe quel exemple à votre contexte.
Sub EnvoyerEmail_Base()
' ── Déclaration des variables ────────────────────────────────
Dim outApp As Outlook.Application ' Application Outlook
Dim outMail As Outlook.MailItem ' L'e-mail à créer
' ── Créer la connexion à Outlook ─────────────────────────────
Set outApp = New Outlook.Application
Set outMail = outApp.CreateItem(olMailItem)
' ── Paramétrer l'e-mail ──────────────────────────────────────
With outMail
.To = "destinataire@exemple.com"
.CC = "copie@exemple.com" ' Optionnel
.Subject = "Objet de l'e-mail"
.Body = "Corps du message en texte simple."
' Pour un corps HTML (mise en forme) :
.HTMLBody = "<p>Corps <strong>en HTML</strong></p>"
' .Display pour afficher avant envoi (mode brouillon)
' .Send pour envoyer directement
.Display
End With
' ── Libérer la mémoire ───────────────────────────────────────
Set outMail = Nothing
Set outApp = Nothing
End Sub
La différence entre .Display et .Send est cruciale : .Display ouvre l'e-mail dans Outlook pour que l'utilisateur le relise avant d'envoyer (recommandé pour les débuts), tandis que .Send envoie directement sans confirmation. Je recommande toujours .Display lors des tests, puis .Send uniquement une fois la macro validée.
Exemple 1 : relance client personnalisée
Ce premier exemple parcourt un tableau de factures impayées et génère un e-mail de relance personnalisé pour chaque client en retard. Le nom du client, le montant et le numéro de facture sont extraits automatiquement du tableau.
Structure attendue du tableau Excel :
- Colonne A : Nom du client
- Colonne B : E-mail du client
- Colonne C : Numéro de facture
- Colonne D : Montant TTC (€)
- Colonne E : Date d'échéance
- Colonne F : Statut (vide ou "Relancé" pour sauter)
Sub EnvoyerRelancesClients()
Dim outApp As Outlook.Application
Dim outMail As Outlook.MailItem
Dim ws As Worksheet
Dim i As Long
Dim derniereLigne As Long
' ── Cibler la feuille de données ─────────────────────────────
Set ws = ThisWorkbook.Sheets("Factures")
derniereLigne = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
' ── Initialiser Outlook ──────────────────────────────────────
Set outApp = New Outlook.Application
' ── Boucle sur toutes les lignes du tableau ──────────────────
For i = 2 To derniereLigne ' Ligne 2 = première donnée (ligne 1 = en-tête)
' Sauter si déjà relancé ou e-mail vide
If ws.Cells(i, "F").Value = "Relancé" Then GoTo SuivantClient
If ws.Cells(i, "B").Value = "" Then GoTo SuivantClient
' Sauter si l'échéance n'est pas dépassée
If ws.Cells(i, "E").Value > Date Then GoTo SuivantClient
' ── Récupérer les données du client ──────────────────────────
Dim nomClient As String : nomClient = ws.Cells(i, "A").Value
Dim emailClient As String : emailClient = ws.Cells(i, "B").Value
Dim numFacture As String : numFacture = ws.Cells(i, "C").Value
Dim montantDu As String : montantDu = Format(ws.Cells(i, "D").Value, "# ##0.00 €")
Dim dateEcheance As String : dateEcheance = Format(ws.Cells(i, "E").Value, "dd/mm/yyyy")
' ── Créer et paramétrer l'e-mail ─────────────────────────────
Set outMail = outApp.CreateItem(olMailItem)
With outMail
.To = emailClient
.Subject = "Rappel de règlement Facture " & numFacture
' Corps HTML avec personnalisation dynamique
.HTMLBody = "<p>Bonjour " & nomClient & ",</p>" & _
"<p>Sauf erreur de notre part, votre facture n° <strong>" & numFacture & "</strong> " & _
"d'un montant de <strong>" & montantDu & "</strong>, " & _
"dont la date d'échéance était le " & dateEcheance & ", " & _
"n'a pas encore été réglée.</p>" & _
"<p>Pourriez-vous nous confirmer la date de règlement prévue ou nous faire part " & _
"de toute anomalie sur cette facture ?</p>" & _
"<p>Restant à votre disposition,<br>" & _
"<strong>Le service comptabilité</strong></p>"
.Display ' Changer en .Send pour envoi automatique
End With
' ── Marquer la ligne comme "Relancé" ─────────────────────────
ws.Cells(i, "F").Value = "Relancé"
SuivantClient:
Next i
' ── Nettoyage ────────────────────────────────────────────────
Set outMail = Nothing
Set outApp = Nothing
MsgBox "Relances générées avec succès !", vbInformation
End Sub
Vous voulez cette macro adaptée à votre fichier existant ?
ASPECT adapte ces macros à votre structure de données exacte, ajoute la gestion des cas particuliers (CC automatique, pièces jointes, signatures d'entreprise) et forme votre équipe à l'utiliser.
Exemple 2 : alerte de stock automatique
Cette macro vérifie le stock actuel de chaque article et envoie un e-mail récapitulatif des articles en dessous du seuil minimal. Un seul e-mail est envoyé avec la liste complète des articles en alerte, ce qui est plus lisible qu'un e-mail par article.
Sub AlerteStock()
Dim outApp As Outlook.Application
Dim outMail As Outlook.MailItem
Dim ws As Worksheet
Dim i As Long
Dim derniereLigne As Long
Dim listeAlertes As String
Dim nbAlertes As Integer
Set ws = ThisWorkbook.Sheets("Stock")
derniereLigne = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
' ── Construire la liste des articles en alerte ───────────────
listeAlertes = ""
nbAlertes = 0
For i = 2 To derniereLigne
Dim reference As String : reference = ws.Cells(i, "A").Value
Dim designation As String : designation = ws.Cells(i, "B").Value
Dim stockActuel As Long : stockActuel = ws.Cells(i, "C").Value
Dim seuilMinimal As Long : seuilMinimal = ws.Cells(i, "D").Value
Dim qtteACommander As Long : qtteACommander = ws.Cells(i, "E").Value
' Si le stock est inférieur ou égal au seuil : ajouter à la liste
If stockActuel <= seuilMinimal Then
nbAlertes = nbAlertes + 1
listeAlertes = listeAlertes & _
"<tr style='background:" & IIf(stockActuel = 0, "#fef2f2", "#fffbeb") & "'>" & _
"<td style='padding:8px;border:1px solid #e2e8f0'>" & reference & "</td>" & _
"<td style='padding:8px;border:1px solid #e2e8f0'>" & designation & "</td>" & _
"<td style='padding:8px;border:1px solid #e2e8f0;text-align:center;color:" & _
IIf(stockActuel = 0, "#ef4444", "#f59e0b") & ";font-weight:bold'>" & stockActuel & "</td>" & _
"<td style='padding:8px;border:1px solid #e2e8f0;text-align:center'>" & seuilMinimal & "</td>" & _
"<td style='padding:8px;border:1px solid #e2e8f0;text-align:center;font-weight:bold'>" & qtteACommander & "</td>" & _
"</tr>"
End If
Next i
' ── Ne rien envoyer si aucune alerte ─────────────────────────
If nbAlertes = 0 Then
MsgBox "Aucun article en dessous du seuil minimal.", vbInformation
Exit Sub
End If
' ── Construire et envoyer l'e-mail ───────────────────────────
Set outApp = New Outlook.Application
Set outMail = outApp.CreateItem(olMailItem)
With outMail
.To = "acheteur@votreentreprise.com"
.CC = "direction@votreentreprise.com"
.Subject = "⚠️ Alerte stock " & nbAlertes & " article(s) à réapprovisionner " & Format(Date, "dd/mm/yyyy")
.HTMLBody = "<h2 style='color:#ef4444'>Alerte stock du " & Format(Date, "dd/mm/yyyy") & "</h2>" & _
"<p>" & nbAlertes & " article(s) sont en dessous du seuil minimal de réapprovisionnement :</p>" & _
"<table style='border-collapse:collapse;width:100%;font-family:Arial;font-size:13px'>" & _
"<tr style='background:#f1f5f9'>" & _
"<th style='padding:8px;border:1px solid #e2e8f0;text-align:left'>Référence</th>" & _
"<th style='padding:8px;border:1px solid #e2e8f0;text-align:left'>Désignation</th>" & _
"<th style='padding:8px;border:1px solid #e2e8f0;text-align:center'>Stock actuel</th>" & _
"<th style='padding:8px;border:1px solid #e2e8f0;text-align:center'>Seuil mini</th>" & _
"<th style='padding:8px;border:1px solid #e2e8f0;text-align:center'>Qté à commander</th>" & _
"</tr>" & listeAlertes & "</table>" & _
"<p style='color:#6b7280;font-size:12px;margin-top:16px'>" & _
"Message généré automatiquement depuis Excel ASPECT Gestion Stock</p>"
.Display
End With
Set outMail = Nothing
Set outApp = Nothing
End Sub
Exemple 3 : rapport PDF joint automatiquement
Le cas le plus demandé : générer un PDF d'un onglet Excel et l'envoyer automatiquement en pièce jointe. Cette macro exporte un onglet spécifique en PDF, l'envoie par e-mail, puis supprime le fichier temporaire.
Sub EnvoyerRapportPDF()
Dim outApp As Outlook.Application
Dim outMail As Outlook.MailItem
Dim ws As Worksheet
Dim cheminPDF As String
Dim nomFichier As String
' ── Définir l'onglet à exporter ──────────────────────────────
Set ws = ThisWorkbook.Sheets("Rapport_Hebdo")
' ── Construire le nom de fichier avec date ───────────────────
nomFichier = "Rapport_Hebdo_" & Format(Date, "yyyy-mm-dd") & ".pdf"
cheminPDF = Environ("TEMP") & "\" & nomFichier
' ── Exporter l'onglet en PDF ─────────────────────────────────
ws.ExportAsFixedFormat _
Type:=xlTypePDF, _
Filename:=cheminPDF, _
Quality:=xlQualityStandard, _
IncludeDocProperties:=True, _
IgnorePrintAreas:=False, _
OpenAfterPublish:=False
' Vérifier que le PDF a bien été créé
If Dir(cheminPDF) = "" Then
MsgBox "Erreur : le PDF n'a pas pu être généré.", vbCritical
Exit Sub
End If
' ── Créer et paramétrer l'e-mail ─────────────────────────────
Set outApp = New Outlook.Application
Set outMail = outApp.CreateItem(olMailItem)
With outMail
.To = "direction@votreentreprise.com;responsable@votreentreprise.com"
.Subject = "Rapport hebdomadaire semaine du " & Format(Date - Weekday(Date, vbMonday) + 1, "dd/mm") & _
" au " & Format(Date - Weekday(Date, vbMonday) + 5, "dd/mm/yyyy")
.HTMLBody = "<p>Bonjour,</p>" & _
"<p>Veuillez trouver en pièce jointe le rapport hebdomadaire " & _
"de la semaine du <strong>" & _
Format(Date - Weekday(Date, vbMonday) + 1, "dd/mm") & _
" au " & Format(Date - Weekday(Date, vbMonday) + 5, "dd/mm/yyyy") & _
"</strong>.</p>" & _
"<p>Bonne lecture,<br><strong>Équipe Reporting</strong></p>"
' ── Joindre le PDF ───────────────────────────────────────────
.Attachments.Add cheminPDF
.Display ' Remplacer par .Send pour envoi automatique
End With
' ── Supprimer le fichier temporaire après envoi ──────────────
' (Si .Send est utilisé, attendre que l'e-mail soit envoyé)
' Kill cheminPDF ' Décommenter si utilisation de .Send
Set outMail = Nothing
Set outApp = Nothing
MsgBox "Rapport PDF envoyé avec succès !", vbInformation
End Sub
Erreurs courantes et solutions
Voici les erreurs VBA les plus fréquentes dans les macros d'e-mail, avec leur cause et leur solution :
| Erreur | Cause | Solution |
|---|---|---|
| Erreur 429 ActiveX ne peut pas créer l'objet |
Outlook n'est pas installé ou pas configuré avec un compte | Ouvrir Outlook, configurer un compte e-mail, puis réessayer |
| Erreur de compilation Type défini par l'utilisateur non défini |
Référence Outlook non activée dans VBA | Outils → Références → cocher "Microsoft Outlook XX.0 Object Library" |
| Erreur 2147221005 Impossible d'opération COM |
Outlook bloqué par la politique de sécurité de l'entreprise | Contacter l'administrateur IT pour autoriser l'automatisation Outlook |
| Boîte de dialogue de sécurité Outlook à chaque envoi | Protection anti-spam d'Outlook contre les macros non approuvées | Ajouter le fichier Excel aux emplacements de confiance, ou utiliser un complément COM signé |
| Erreur 91 Variable objet non définie |
Set outApp ou Set outMail non exécuté |
Vérifier que les lignes Set sont bien présentes et exécutées avant utilisation |
| E-mail envoyé mais corps vide | Conflit entre .Body et .HTMLBody (ne pas utiliser les deux) |
Utiliser uniquement .HTMLBody OU .Body, pas les deux dans le même With |
Comment personnaliser sans coder
Si vous n'êtes pas à l'aise avec VBA, voici les 5 lignes à modifier dans n'importe quelle des macros ci-dessus pour l'adapter à votre contexte, sans toucher au reste :
- Nom de la feuille : Remplacez
"Factures","Stock"ou"Rapport_Hebdo"par le nom exact de votre onglet. - Lettre des colonnes : Remplacez les lettres dans
ws.Cells(i, "A")par les colonnes de votre tableau (ex :"C"si les e-mails sont en colonne C). - Destinataire : Remplacez l'adresse dans
.To = "..."par votre adresse ou une référence de cellule :.To = ws.Cells(i, "B").Value. - Objet de l'e-mail : Modifiez le texte dans
.Subject = "..."selon votre convention. - Corps du message : Adaptez le texte dans
.HTMLBody = "..."avec vos formulations habituelles.
Avant de passer à .Send (envoi automatique), testez systématiquement avec .Display (qui ouvre l'e-mail dans Outlook sans l'envoyer). Vérifiez que le destinataire, l'objet, le corps et les pièces jointes sont corrects. Ce simple réflexe évite d'envoyer des centaines d'e-mails avec une erreur dans le corps du message.
Par défaut, VBA n'inclut pas la signature Outlook dans les e-mails créés. Pour l'ajouter, utilisez .Display avant d'ajouter le corps, ce qui précharge la signature dans le brouillon, puis accédez à .HTMLBody pour y insérer votre contenu avant la signature existante : .HTMLBody = monContenu & .HTMLBody. Cette astuce préserve la signature configurée dans Outlook.
Essayez directement avec l'assistant IA
Besoin d'envoyer des emails automatiques depuis Excel ? Décrivez votre macro en français l'assistant IA génère le code VBA Outlook prêt à l'emploi.
Générer le code VBA email avec l'IA →Gratuit · Pas d'inscription · Résultat en 3 secondes
Vous voulez qu'ASPECT automatise ça pour vous ?
Ces exemples de code sont un point de départ. ASPECT développe des macros robustes, documentées et adaptées à votre structure exacte avec gestion des cas particuliers, journalisation des envois, et formation de votre équipe. Devis gratuit sous 24h.
Réponse sous 24h · Devis gratuit · ✅ Code livré + commenté · Formation incluse