Automatisation VBA

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.

Fenêtre Excel avec code VBA visible et fenêtre Outlook ouverte côte à côte montrant un email généré automatiquement avec pièce jointe PDF
Excel et Outlook communiquent via VBA votre rapport s'envoie automatiquement sans ouvrir Outlook manuellement

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

📨
Outlook installé et configuré
Un compte e-mail actif dans Outlook Desktop (pas Outlook Web). L'application doit être ouverte ou au moins configurée.
📊
Excel avec macros activées
Fichier .xlsm (pas .xlsx). Macros autorisées dans les paramètres de sécurité d'Excel (Centre de gestion de la confidentialité).
🔗
Référence Outlook activée
Dans l'éditeur VBA : Outils → Références → cocher "Microsoft Outlook XX.0 Object Library".

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.

  1. Ouvrez l'éditeur VBA : Alt + F11
  2. Menu Outils → Références
  3. Cochez "Microsoft Outlook XX.0 Object Library" (XX = votre version, ex : 16.0 pour Office 365)
  4. OK la référence est maintenant active
📌 Alternative sans référence (Late Binding)

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.

Structure de base Macro e-mail VBA
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)
Macro VBA Relances clients depuis tableau Excel
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
Email Outlook reçu avec objet automatique 'Rapport mensuel Avril 2026' et fichier PDF en pièce jointe généré par Excel
Le résultat final : un email professionnel avec rapport PDF en pièce jointe, envoyé automatiquement chaque mois

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.

Service Automatisation Excel

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.

Macro VBA Alerte stock récapitulative
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.

Macro VBA Export PDF + envoi e-mail automatique
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 :

  1. Nom de la feuille : Remplacez "Factures", "Stock" ou "Rapport_Hebdo" par le nom exact de votre onglet.
  2. 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).
  3. Destinataire : Remplacez l'adresse dans .To = "..." par votre adresse ou une référence de cellule : .To = ws.Cells(i, "B").Value.
  4. Objet de l'e-mail : Modifiez le texte dans .Subject = "..." selon votre convention.
  5. Corps du message : Adaptez le texte dans .HTMLBody = "..." avec vos formulations habituelles.
📌 Conseil important : toujours tester avec .Display d'abord

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.

💡 Cas concret : la signature automatique

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