Fonctions en VBA pour générer des courriels depuis Excel

Des fonctions en VBA pour générer des courriels formatés par les balises HTML

Laurent Ott

Dans cet article, vous allez découvrir des fonctions en VBA pour générer des courriers électroniques depuis Excel et les envoyer par Outlook.
Ces courriels pourront contenir des textes formatés ainsi que des liens hypertextes, des tableaux, des plages de données, des graphiques ou des images.

Vous pouvez déposer vos commentaires dans cette discussion.

- Titre : Fonctions en VBA pour générer des courriels depuis Excel

- Auteur : Laurent Ott

- Parution : 20 mai 2022

- Mise à jour : 30 novembre 2022

- Licence : Le contenu de cet article est rédigé par Laurent Ott et est mis à disposition selon les termes de la Licence Creative Commons Attribution - Pas d'Utilisation Commerciale 3.0 non transposé. Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright ® 2013 Developpez.com.

Voir également :

- Tome 1 - Des bases de la programmation à l'algorithme de classement rapide QuickRanking

- Tome 2 - Des bases de la programmation en mode graphique à la programmation d'un jeu d'arcade en VBA et Microsoft Excel

- Tome 3 - Problème du Voyageur de commerce - Une méthode d'approximation basée sur des principes simples

- Tome 4 - Un algorithme de chiffrement/déchiffrement des cellules pour une meilleure confidentialité

- Tome 5 - Sentinelle - Une application qui veille sur vos classeurs sensibles - Exemples d'utilisations des tableaux de données et des requêtes SQL en VBA

- Tome 6 - Apprendre la programmation de nouvelles fonctions Excel pour l'utilisateur

- Comprendre la méthode de factorisation du Crible Quadratique

- Programmation en VBA de menus personnalisés pour Excel

- Manipuler les données des bases Access depuis Excel

- Transfert des fichiers volumineux sous Outlook

- Algorithme ECM de factorisation par les courbes elliptiques

- Un classeur Excel multi-utilisateur

- Compresser/décompresser des fichiers au format ZIP

- Fonctions en VBA pour gérer les Tableaux Structurés d’Excel

- Des fonctions en VBA pour générer des courriels par les balises HTML

- MsgBox_Perso : une boîte de message personnalisée

- Utiliser une collection ArrayList à plusieurs dimensions

- Fonctions en VBA pour gérer de gros volumes de données

- Les cryptosystèmes RSA et AES-256

Sommaire

- I. Introduction

- II. Les balises du langage HTML

- II-A. Le principe des balises HTML

- II-B. Outlook et les balises HTML

- III. Les fonctions pour générer un corps de message formaté HTML

- III-A. Mail_Texte

- III-B. Mail_SautDeLigne

- III-C. Mail_LienMessagerie

- III-D. Mail_LienHypertexte

- III-E. Mail_PlageExcel

- III-F. Mail_FichierImage

- III-G. Mail_GraphiqueExcel

- IV. Utiliser ces fonctions avec un modèle de message Outlook

- V. Envoyer un courriel formaté HTML par Outlook – Mail_Envoyer

- VI. Conclusion

- VII. Remerciements

- VIII. Le fichier joint

- IX. Des liens utiles

- X. Annexe 1 – fonctions pour convertir ou redimensionner une image

- XI. Annexe 2 – les énumérations du module

I - Introduction

Depuis Excel, il est possible de créer en VBA une session Outlook pour générer et envoyer un courriel.
Dans de nombreux exemples que vous trouverez sur Internet, le corps du message est bien souvent un texte brut, c’est-à-dire sans mises en forme telles que la police en gras, italique, couleur et autres possibilités qui rendent un message plus attrayant.

Pourtant, en utilisant les balises du langage HTML (1) , il est possible de personnaliser le format du corps du message, d’inclure des liens hypertextes, des tableaux, des plages de données Excel, des graphiques ou des images et donc de faire une présentation soignée.

Ce sera le but des fonctions présentées dans cette documentation.
Toutes ont en commun d’être préfixées « Mail_ » pour mieux les identifier.

Dans les premiers exemples d’utilisation des fonctions, les données à formater en HTML sont passées « en dur », mais nous verrons par la suite qu’elles peuvent évidemment être issues d’un classeur Excel.
Nous verrons aussi que ces fonctions peuvent être utilisées pour alimenter un modèle de message.

Les débutants en VBA acquerront le niveau nécessaire avec le tutoriel « Tome 1 - Des bases de la programmation à l'algorithme de classement rapide QuickRanking ».

Cette documentation a été réalisée avec Excel 2016 version 32 bits sous Windows 10.

II - Les balises du langage HTML

Comme indiqué en introduction, les fonctions de cette documentation génèrent un corps de message formaté grâce à l’utilisation de balises du langage HTML.
Si vous ne connaissez pas cette notion, les lignes qui suivent présentent un rapide aperçu de ce concept, ce qui vous permettra de mieux comprendre le code VBA des fonctions que nous allons étudier.

II-A - Le principe des balises HTML

Le langage HTML est un langage reconnu par les logiciels de présentation des pages Web.
Il utilise des « balises » pour indiquer le format à appliquer à un texte, afficher des images, insérer des liens...

Par exemple, la balise « <b> » met en gras le texte « Bonjour », elle est utilisée ainsi : <b>Bonjour</b>.

Vous remarquerez ici une balise de début « <b> », dite balise d’ouverture (ou ouvrante), et une balise de fin « </b> », dite balise de fermeture (ou fermante) facilement identifiable puisqu’elle est précédée du caractère « / ».
Les balises fonctionnent généralement par paire sur l’élément quelles encadrent.
Il existe des exceptions et certaines balises n’ont pas de balise d’ouverture, comme la balise <br/> qui représente un retour à la ligne ou la balise <hr/> qui trace un trait.

Les balises peuvent se cumuler, par exemple <b><i>Bonjour</i></b> formate le texte en gras par la balise <b> et en italique par la balise <i>. L’ordre n’a pas d’importance et <i><b>Bonjour</b></i> donne le même résultat.
Les balises peuvent avoir des attributs pour définir des propriétés.

Voici un exemple d'attribut (inspiré de ce site) pour la balise <p> (balise définissant un paragraphe), permettant de spécifier que le texte inclus dans le paragraphe doit être aligné (align) sur la droite (right) : <p align="right">Exemple de paragraphe</p>

II-B - Outlook et les balises HTML

Pour envoyer un courriel formaté avec des balises HTML, nous utiliserons dans cette documentation le logiciel Outlook (vous utiliserez peut-être un autre logiciel, mais le principe reste le même pour formater le corps du message).

Un courriel n’étant pas une page Web, toutes les balises du langage HTML ne seront pas reconnues par les logiciels de messagerie.
Nous n’utiliserons donc que les principales balises.

Par exemple <b> met un texte en gras alors que <STRONG> accentue fortement sa police. Une nuance qu’Outlook n’a pas. Il n’y aura donc pas un style « accentué » dans la liste des styles disponibles. Idem pour l’emphase (la balise <em>) qui est interprétée comme du texte en italique, soit la balise <i>.

Pour qu’Outlook reconnaisse que le texte est formaté en HTML nous utiliserons la propriété HTMLBody de l’objet MailItem.

Insérez cet exemple dans un classeur Excel pour tester le message « Bonjour tout le monde » où un objet message est créé sur une session Outlook par CreateObject("Outlook.Application").CreateItem(0) puis renseigné d’un texte au format HTML et enfin affiché par la propriété Display :

'------------------------------------------------------------------------------------------------
Sub Exemple()
'------------------------------------------------------------------------------------------------
Dim oMail As Object
Set oMail = CreateObject("Outlook.Application").CreateItem(0)

oMail.HTMLBody = "<b><i>Bonjour</i></b> tout le monde."

oMail.Display
Set oMail = Nothing
End Sub
'------------------------------------------------------------------------------------------------

Ce qui donne :

Ce qui est satisfaisant, mais comme vous pouvez le constater cela nécessite d’une part de connaître les balises HTML et d’autre part d’être bien rigoureux dans son message pour ne pas oublier la fermeture des balises. Ici ça reste simple, mais sur un format plus élaboré on perd facilement le fil.

Et ça se complique lorsqu’il faut rajouter de la couleur avec l’attribut color de la balise font, car la couleur doit être passée en notation hexadécimale représentant les valeurs des tons rouges, verts et bleus, ce qui donne :
oMail.HTMLBody = "<font color=#FF0000 <b><i>Bonjour </b></i></font> <font color=#000000>tout le monde</font>"

Pour générer : « Bonjour tout le monde ».

Et cet exemple n’est qu’un aperçu du formalisme qui vous attend si vous souhaitez faire un corps de message complexe en HTML, comme insérer des liens hypertextes ou des images, ou pire encore insérer des plages de données et des tableaux…

C’est pourquoi je vous propose des fonctions qui vous simplifieront la tâche, car elles prennent en charge ces contraintes.

III - Les fonctions pour générer un corps de message formaté HTML

Nous venons de voir comment les balises du langage HTML permettent de formater un message.

Ces balises seront interprétées par Outlook (et d’autres logiciels reconnaissant le HTML) lors de la mise en page du message pour modifier la police du texte, insérer des liens de messagerie ou des liens hypertextes, des plages Excel, des fichiers image ou des graphiques.

Les fonctions que nous allons étudier se servent de la variable passée en argument pour mémoriser le message formaté. C’est cette variable, nommée « M » dans nos exemples, qui sera utilisée comme corps de message lors de l’envoi du courriel que nous étudierons dans un autre chapitre.

Pour le moment, faites l’impasse sur la fonction Mail_Envoyer qui n’est reprise dans les exemples ci-dessous que pour vous permettre de les tester depuis un classeur contenant le module « Mail » que vous trouverez dans le fichier joint (à condition que vous disposiez d’Outlook et d’une habilitation à envoyer des messages).

III-A - Mail_Texte

La fonction Mail_Texte génère un texte formaté en utilisant certaines balises du langage HTML (voir le chapitre précédent). Le texte peut être mis en gras, en italique, souligné, mis en exposant ou en indice, centré. Un trait ou un saut de ligne peuvent être ajoutés.

Outre le style, la couleur, la police et la taille peuvent aussi être paramétrées.

Le texte formaté est mémorisé dans la variable passée en argument.

Ses arguments sont :

- Mémoire : la variable à utiliser pour mémoriser la mise en forme ;

- Texte : le texte à formater ;

- Style (facultatif) : une valeur de l’énumération EnumMailStyle qui indique le style à appliquer au texte (les styles peuvent se cumuler, leur ordre n’a pas d’importance)
- Style_Normal : (valeur par défaut) pas de format particulier,
- Style_Gras : le texte est mis en gras,
- Style_Italique : le texte est mis en italique,
- Style_Souligne : le texte est souligné,
- Style_Exposant : le texte est un exposant,
- Style_Indice : le texte est un indice,
- Style_Trait : un trait est tiré à la suite du texte,
- Style_Centre : le texte est centré,
- Style_SautDeLigne : un saut de ligne est effectué à la suite du texte ;

- Couleur (facultatif) : une valeur de l’énumération EnumMailCouleur qui définit la couleur du texte (noir par défaut) ou la valeur de votre choix, par exemple la couleur orange = 16 753 920 ;

- Police (facultatif) : le nom de la police à utiliser, si autre que la police par défaut ;

- Taille (facultatif) : la taille de la police, comprise entre 1 pour la plus petite et 7 pour la plus grande (la valeur par défaut est 3).

Les styles peuvent se cumuler, leur ordre n’a pas d’importance, comme dans la fonction MsgBox du VBA où les boutons peuvent se cumuler : vbYesNo + vbExclamation + vbDefaultButton1.

Pour cela, nous utilisons une énumération des styles disponibles déclarée en en-tête du module :

'------------------------------------------------------------------------------------------------
Enum EnumMailStyle
Style_Normal = 0
Style_Gras = 2
Style_Italique = 4
Style_Souligne = 8
Style_Exposant = 16
Style_Indice = 32
Style_Trait = 64
Style_Centre = 128
Style_SautDeLigne = 512
End Enum
'------------------------------------------------------------------------------------------------

Et l’opérateur logique(2) AND qui travaille sur les bits des variables, à ne pas confondre avec l’opérateur de comparaison AND que l’on retrouve sous cette forme : « If … AND … Then … ».

L’opérateur logique AND est utilisé pour comparer les bits de deux variables :
Expression1 AND Expression2 renvoie un nombre différent de 0 si Expression1 et Expression2 ont des bits en commun.
Soit la table de vérité(3) suivante :

Par exemple si l’argument Style vaut 10 nous pouvons en déduire les styles demandés :
10 AND Style_Gras = 10 AND 2 = 2, donc le style gras est demandé ;
10 AND Style_Italique = 10 AND 4 = 0, donc le style italique n’est pas demandé ;
10 AND Style_Souligne = 10 AND 8 = 8, donc le style souligné est demandé ;
Etc.

Comme nous l’avons déjà vu, l’attribut color de la balise font doit être décrit en notation hexadécimale représentant les valeurs des tons rouge, vert et bleu de la couleur désirée. Ne vous en souciez pas, vous passerez en argument un nombre correspondant à la couleur de votre choix ou l’une des couleurs prédéfinies dans l’énumération.

La décomposition en tons de cette valeur s’obtient par ces opérations :
Bleu = (Couleur Mod 256)
Vert = (Couleur \ 256) Mod 256
Rouge = (Couleur \ 65536) Mod 256

La conversion en hexadécimal se fait par la fonction Hex du VBA.

Par exemple, pour générer ceci :

'------------------------------------------------------------------------------------------------
Sub Exemple()
'------------------------------------------------------------------------------------------------
Dim M As String
Mail_Texte M, "Bonjour ", Style_Gras, Couleur_Rouge, , 6
Mail_Texte M, "tout le monde", Style_Souligne + Style_Italique + Style_SautDeLigne
Mail_Texte M, "Bienvenue sur Developpez.com", , , , 6

Mail_Envoyer M, False, "", ""
End Sub
'------------------------------------------------------------------------------------------------

Vous pouvez bien sûr nommer les arguments pour faciliter la lecture, ce qui donne :

'------------------------------------------------------------------------------------------------
Sub Exemple()
'------------------------------------------------------------------------------------------------
Dim M As String
Mail_Texte Mémoire:=M,Texte:="Bonjour ", Style:=Style_Gras, Couleur:=Couleur_Rouge
Mail_Texte Mémoire:=M,Texte:="tout le monde", Style:=Style_Souligne + Style_Italique+ Style_SautDeLigne
Mail_Texte Mémoire:=M,Texte:="Bienvenue sur Developpez.com", Taille:=6
Mail_Envoyer M, False, "", ""
End Sub
'------------------------------------------------------------------------------------------------

Le code de la fonction :

'------------------------------------------------------------------------------------------------
Sub Exemple()
'------------------------------------------------------------------------------------------------
Sub Mail_Texte(Mémoire As String, Texte As String, _
Optional Style As EnumMailStyle = Style_Normal, _
Optional Couleur As EnumMailCouleur = Couleur_Noir, _
Optional Police As String = "", _
Optional ByVal Taille As Byte = 3)
'------------------------------------------------------------------------------------------------
' Ajoute à la variable "Mémoire" la chaîne passée dans "Texte" avec la mise en forme indiquée.
'------------------------------------------------------------------------------------------------
' Mémoire : la variable à utiliser pour mémoriser la mise en forme;
' Texte : le texte à formater;
' Style : (facultatif) une valeur de l'énumération EnumMailStyle qui indique le style à appliquer
'         au texte (les styles peuvent se cumuler, leur ordre n'a pas d'importance)
'    Style_Normal : (valeur par défaut) pas de format particulier,
'    Style_Gras : le texte est mis en gras,
'    Style_Italique : le texte est mis en italique,
'    Style_Souligne : le texte est souligné,
'    Style_Exposant : le texte est un exposant,
'    Style_Indice : le texte est un indice,
'    Style_Trait : un trait est tiré à la suite du texte,
'    Style_Centre : le texte est centré,
'    Style_SautDeLigne : un saut de ligne est effectué à la suite du texte;
' Couleur: (facultatif) une valeur de l' énumération EnumMailCouleur qui définit la couleur du
'          texte (noir par défaut) ou la valeur de votre choix, par exemple la couleur orange = 16 753 920;
' Police : (facultatif) le nom de la police à utiliser, si autre que la police par défaut;
' Taille : (facultatif) la taille de la police, comprise entre 1 pour la plus petite et 7 pour la
'          plus grande (la valeur par défaut est 3).
'------------------------------------------------------------------------------------------------
Dim iRed As Long, iGreen As Long, iBlue As Long
Dim sHTML As String, i As Integer, FinBalises As String

' Conversion d'une couleur décimale en code RGB :
iBlue = (Couleur Mod 256)
iGreen = (Couleur \ 256) Mod 256
iRed = (Couleur \ 65536) Mod 256

' Contrôle le débordement de la taille :
If Taille < 1 Or Taille > 7 Then Taille = 3

' Définition de la couleur de la police si différente de vide et de la taille de la police :
sHTML = "<font color=#" & Format(Hex(iRed), "00") & Format(Hex(iGreen), "00") & Format(Hex(iBlue), "00") _
& IIf(Police <> "", " face=" & Police, "") _
& " size=" & Taille _
& ">"

' Ajoute les balises de la mise en forme du style :
If (Style And Style_SautDeLigne) <> 0 Then Texte = Texte & "<br/>"
If (Style And Style_Gras) <> 0 Then sHTML = sHTML & "<b>": FinBalises = FinBalises & "</b>"
If (Style And Style_Italique) <> 0 Then sHTML = sHTML & "<i>": FinBalises = FinBalises & "</i>"
If (Style And Style_Souligne) <> 0 Then sHTML = sHTML & "<u>": FinBalises = FinBalises & "</u>"
If (Style And Style_Exposant) <> 0 Then sHTML = sHTML & "<sup>": FinBalises = FinBalises & "</sup>"
If (Style And Style_Indice) <> 0 Then sHTML = sHTML & "<sub>": FinBalises = FinBalises & "</sub>"
If (Style And Style_Centre) <> 0 Then sHTML = sHTML & "<CENTER>": FinBalises = FinBalises & "</CENTER>"

' Génération du code HTML et fermeture des balises :
sHTML = sHTML & Texte & FinBalises & "</font>"

' S'il faut tracer un trait :
If (Style And Style_Trait) <> 0 Then sHTML = sHTML & "<hr/>"

' Alimente la mémoire du traitement :
Mémoire = Mémoire & sHTML

End Sub
'------------------------------------------------------------------------------------------------

III-B - Mail_SautDeLigne

La fonction Mail_SautDeLigne génère un ou plusieurs sauts de lignes (ou retours à la ligne).

Les sauts de lignes, réalisés par la balise « <br/> », s’ajoutent à la variable passée en argument (comme vu précédemment) qui contient le corps du message qui sera diffusé.

Ses arguments sont :

- Mémoire : la variable à utiliser pour mémoriser la mise en forme ;

- NbSaut (facultatif) : le nombre de sauts de ligne désirés, 1 par défaut.

Exemple pour générer ceci :

'------------------------------------------------------------------------------------------------
Sub Exemple()
'------------------------------------------------------------------------------------------------
Dim M As String
Mail_Texte M, "Bonjour ", Style_Gras, Couleur_Rouge
Mail_Texte M, "tout le monde", Style_Souligne + Style_Italique

Mail_SautDeLigne M, 3

Mail_Texte M, "Bienvenue sur Developpez.com", , , , 6
Mail_Envoyer M, False, "", ""
End Sub
'------------------------------------------------------------------------------------------------

Le code de la fonction :

'------------------------------------------------------------------------------------------------
Sub Mail_SautDeLigne(Mémoire As String, Optional NbSaut As Integer = 1)
'------------------------------------------------------------------------------------------------
' Ajoute à la variable "Mémoire" un ou plusieurs sauts de lignes par la balise "<br/>".
'------------------------------------------------------------------------------------------------
' Mémoire : la variable à utiliser pour mémoriser la mise en forme ;
' NbSaut : (facultatif) le nombre de sauts de ligne désirés, 1 par défaut.
'------------------------------------------------------------------------------------------------
Dim i As Integer
For i = 1 To NbSaut
Mémoire = Mémoire & "<br/>"
Next i
End Sub
'------------------------------------------------------------------------------------------------

III-C - Mail_LienMessagerie

La fonction Mail_LienMessagerie génère un lien sur une messagerie.

Lorsque la souris survole le lien, une infobulle affiche l’adresse de la messagerie (voir l’exemple ci-dessous).
Un clic sur ce lien ouvre un nouveau message avec en destinataire l’adresse indiquée.
Ce lien complète la variable passée en argument qui contient le corps du message, de la balise « a href=mailto: » sous la forme :
<a href=mailto:AdresseMail>Texte</a>.
Où AdresseMail est l’adresse de la messagerie et Texte est le texte à afficher. Le texte peut être formaté. S’il ne l’est pas, le format par défaut des liens de messagerie est appliqué.

Ses arguments sont :

- Mémoire : la variable à utiliser pour mémoriser la mise en forme ;

- AdresseMail : l’adresse de la messagerie ;

- Texte : le texte à afficher (s’il est vide l’adresse de la messagerie sera reprise) ;

- Style (facultatif) : une valeur de l’énumération EnumMailStyle qui indique le style à appliquer au format (les styles peuvent se cumuler, leur ordre n’a pas d’importance)
- Style_Normal : (valeur par défaut) pas de format particulier,
- Style_Gras : le texte est mis en gras,
- Style_Italique : le texte est mis en italique,
- Style_Souligne : le texte est souligné,
- Style_Exposant : le texte est un exposant,
- Style_Indice : le texte est un indice,
- Style_Trait : un trait est tiré à la suite du texte,
- Style_Centre : le texte est centré,
- Style_SautDeLigne : un saut de ligne est effectué à la suite du texte ;

- Couleur (facultatif) : une valeur de l’énumération EnumMailCouleur qui définit la couleur du texte (bleu par défaut) ou la valeur de votre choix, par exemple orange = 16 753 920 ;

- Police (facultatif) : le nom de la police à utiliser, si autre que la police par défaut ;

- Taille (facultatif) : la taille de la police, comprise entre 1 pour la plus petite et 7 pour la plus grande (la valeur par défaut est 3).

Par exemple, pour générer ceci :

'------------------------------------------------------------------------------------------------
Sub Exemple()
'------------------------------------------------------------------------------------------------
Dim M As String
Mail_Texte M, "Bonjour ", Style_Gras, Couleur_Rouge
Mail_Texte M, "tout le monde", Style_Souligne + Style_Italique + Style_SautDeLigne
Mail_SautDeLigne M, 2
Mail_Texte M, "Bienvenue sur Developpez.com", , , , 6

Mail_Texte M, "", Style_Trait
Mail_Texte M, "Vous pouvez nous contacter par messagerie "
Mail_LienMessagerie M, "MonAdresse@Mondomaine.com", "à cette adresse"
Mail_Texte M, "", Style_Trait

Mail_Envoyer M, False, "", ""
End Sub
'------------------------------------------------------------------------------------------------

Le code de la fonction :

'------------------------------------------------------------------------------------------------
Sub Mail_LienMessagerie(Mémoire As String, AdresseMail As String, ByVal Texte As String, _
Optional Style As EnumMailStyle = Style_Normal, _
Optional Couleur As EnumMailCouleur = Couleur_Bleu, _
Optional Police As String = "", _
Optional ByVal Taille As Byte = 3)
'------------------------------------------------------------------------------------------------
' Ajoute à la variable "Mémoire" la balise "MailTo" passée dans "AdresseMail".
'------------------------------------------------------------------------------------------------
' Mémoire : la variable à utiliser pour mémoriser la mise en forme;
' AdresseMail : l'adresse de la messagerie;
' Texte : le texte à afficher (s'il est vide l'adresse de la messagerie sera reprise);
' Style : (facultatif) une valeur de l'énumération EnumMailStyle qui indique le style à appliquer au
'         format (les styles peuvent se cumuler, leur ordre n'a pas d'importance)
'   Style_Normal : (valeur par défaut) pas de format particulier,
'   Style_Gras : le texte est mis en gras,
'   Style_Italique : le texte est mis en italique,
'   Style_Souligne : le texte est souligné,
'   Style_Exposant : le texte est un exposant,
'   Style_Indice : le texte est un indice,
'   Style_Trait : un trait est tiré à la suite du texte,
'   Style_Centre : le texte est centré,
'   Style_SautDeLigne : un saut de ligne est effectué à la suite du texte;
' Couleur: (facultatif) une valeur de l'énumération EnumMailCouleur qui définit la couleur du
'          texte (bleu par défaut) ou la valeur de votre choix, par exemple orange = 16 753 920;
' Police : (facultatif) le nom de la police à utiliser, si autre que la police par défaut;
' Taille : (facultatif) la taille de la police, comprise entre 1 pour la plus petite et 7 pour la
'          plus grande (la valeur par défaut est 3).
'------------------------------------------------------------------------------------------------
Dim StrTexte As String

' Si le texte n'est pas renseigné alors prend l'adresse :
If Texte = "" Then Texte = AdresseMail

' Met le texte au format demandé :
Call Mail_Texte(StrTexte, Texte, Style, Couleur, Police, Taille)

' Ajoute à la variable Mémoire la nouvelle balise :
Mémoire = Mémoire & "<a href=mailto:" & AdresseMail & ">" & StrTexte & "</a>"

End Sub
'------------------------------------------------------------------------------------------------

III-D - Mail_LienHypertexte

La fonction Mail_LienHypertexte génère un lien hypertexte, c’est-à-dire un lien sur une adresse Internet ou sur une adresse de fichier d’un réseau partagé.

Lorsque la souris survole le lien, une infobulle en affiche la valeur (voir l’exemple ci-dessous) et un clic ouvre le lien concerné.
Ce lien complète la variable passée en argument de la balise « a href= » sous la forme :
<a href=lien>Texte</a>.
Où lien est l’adresse et Texte est le texte à afficher. Le texte peut être formaté. S’il ne l’est pas, le format par défaut des liens de messagerie est appliqué.

Ses arguments sont :

- Mémoire : la variable à utiliser pour mémoriser la mise en forme ;

- Lien : l’adresse du lien (adresse Internet ou d’un fichier) ;

- Texte : le texte à afficher (s’il est vide, l’adresse du lien sera reprise) ;

- Style (facultatif) : une valeur de l’énumération EnumMailStyle qui indique le style à appliquer au format (les styles peuvent se cumuler, leur ordre n’a pas d’importance)
- Style_Normal : (valeur par défaut) pas de format particulier,
- Style_Gras : le texte est mis en gras,
- Style_Italique : le texte est mis en italique,
- Style_Souligne : le texte est souligné,
- Style_Exposant : le texte est un exposant,
- Style_Indice : le texte est un indice,
- Style_Trait : un trait est tiré à la suite du texte,
- Style_Centre : le texte est centré,
- Style_SautDeLigne : un saut de ligne est effectué à la suite du texte ;

- Couleur (facultatif) : une valeur de l’énumération EnumMailCouleur qui définit la couleur du texte (bleu par défaut) ou la valeur de votre choix, par exemple orange = 16 753 920 ;

- Police (facultatif) : le nom de la police à utiliser, si autre que la police par défaut ;

- Taille (facultatif) : la taille de la police, comprise entre 1 pour la plus petite et 7 pour la plus grande (la valeur par défaut est 3).

Par exemple, pour générer ceci :

'------------------------------------------------------------------------------------------------
Sub Exemple()
'------------------------------------------------------------------------------------------------
Dim M As String
Mail_Texte M, "Bonjour ", Style_Gras, Couleur_Rouge
Mail_Texte M, "tout le monde", Style_Souligne + Style_SautDeLigne + Style_Italique
Mail_SautDeLigne M, 2
Mail_Texte M, "Bienvenue sur Developpez.com", , , , 6

Mail_Texte M, "", Style_Trait
Mail_Texte M, "Vous pouvez nous contacter sur notre site "
Mail_LienHypertexte M, "https://www.developpez.net/forums/sendmessage.php", "à cette adresse"
Mail_Texte M, "", Style_Trait

Mail_Envoyer M, False, "", ""
End Sub
'------------------------------------------------------------------------------------------------

Le code de la fonction :

'------------------------------------------------------------------------------------------------
Sub Mail_LienHypertexte(Mémoire As String, Lien As String, ByVal Texte As String, _
Optional Style As EnumMailStyle = Style_Normal, _
Optional Couleur As EnumMailCouleur = Couleur_Bleu, _
Optional Police As String = "", _
Optional ByVal Taille As Byte = 3)
'------------------------------------------------------------------------------------------------
' Ajoute à la variable "Mémoire" le lien hypertexte passée dans "Lien".
'------------------------------------------------------------------------------------------------
' Mémoire : la variable à utiliser pour mémoriser la mise en forme;
' Lien : l'adresse du lien (adresse Internet ou d'un fichier);
' Texte : le texte à afficher (s'il est vide l'adresse du lien sera reprise);
' Style : (facultatif) une valeur de l'énumération EnumMailStyle qui indique le style à appliquer au
'         format (les styles peuvent se cumuler, leur ordre n'a pas d'importance)
'   Style_Normal : (valeur par défaut) pas de format particulier,
'   Style_Gras : le texte est mis en gras,
'   Style_Italique : le texte est mis en italique,
'   Style_Souligne : le texte est souligné,
'   Style_Exposant : le texte est un exposant,
'   Style_Indice : le texte est un indice,
'   Style_Trait : un trait est tiré à la suite du texte,
'   Style_Centre : le texte est centré,
'   Style_SautDeLigne : un saut de ligne est effectué à la suite du texte;
' Couleur: (facultatif) une valeur de l'énumération EnumMailCouleur qui définit la couleur du
'          texte (bleu par défaut) ou la valeur de votre choix, par exemple orange = 16 753 920;
' Police : (facultatif) le nom de la police à utiliser, si autre que la police par défaut;
' Taille : (facultatif) la taille de la police, comprise entre 1 pour la plus petite et 7 pour la
'          plus grande (la valeur par défaut est 3).
'------------------------------------------------------------------------------------------------
Dim StrTexte  As String

' Si le texte n'est pas renseigné alors prend le lien :
If Texte = "" Then Texte = Lien

' Met le texte au format demandé :
Call Mail_Texte(StrTexte, Texte, Style, Couleur, Police, Taille)

' Ajoute à la variable Mémoire la nouvelle balise :
Mémoire = Mémoire & "<a href=" & Lien & ">" & StrTexte & "</a>"

End Sub
'------------------------------------------------------------------------------------------------

III-E - Mail_PlageExcel

La fonction Mail_PlageExcel insère une plage issue du classeur Excel actif dans le corps du message.

La plage peut être une ou plusieurs cellules, un tableau structuré, un tableau croisé dynamique…

Techniquement, la plage est exportée dans un fichier temporaire au format HTML par la méthode ActiveWorkbook.PublishObjects.Add(4), puis ce fichier est lu pour modifier l’alignement par défaut avant d’être ajouté à la variable passée en argument.
Le fichier temporaire est supprimé à la fin du traitement.

Le fichier temporaire est enregistré dans un sous-répertoire du répertoire de travail de l’utilisateur obtenu par la fonction Environ("USERPROFILE"). Un nouveau dossier y est ajouté par :
MkDir Environ("USERPROFILE") & "\Mail".
Cela est nécessaire, car si l’utilisateur n’est pas administrateur de son poste, il ne pourra pas enregistrer de fichiers directement dans le répertoire de travail, par contre il est habilité à créer un sous-répertoire et à travailler dedans.

La méthode ActiveWorkbook.PublishObjects.Add est à l’origine destinée à enregistrer des documents dans une page Web. Donc au format HTML. Ici, son usage est détourné pour obtenir une « source » formatée (un fichier au format texte) que nous utiliserons pour notre corps de message.

Ses arguments sont :

- SourceType : le type de la source, pour nous xlSourceRange (4) une plage de cellules ;

- FileName : notre fichier temporaire ;

- Sheet : le nom de la feuille de calcul, elle sera déduite de la plage passée en argument de notre fonction par la propriété Parent.Name ;

- Source : l’adresse des cellules, déduite de la plage passée en argument de notre fonction par la propriété Address ;

- HtmlType : dans notre cas xlHtmlStatic (0), c’est-à-dire « utilise le langage HTML » ;

- DivID : un identificateur unique utilisé dans la balise « HTML DIV » pour identifier l’élément sur la page web, arbitrairement « DivID », car il en faut un, mais non utilisé pour nous ;

- Titre : le titre de la page web, laissé à vide dans notre cas.

Pour lire le fichier texte généré par cette méthode (nommé Tps dans l’exemple ci-dessous) et le charger dans une mémoire (sRead), nous utilisons la méthode OpenTextFile :
Set fso = CreateObject("Scripting.FileSystemObject")
Set oFile = fso.OpenTextFile(Tps, 1, False)
sRead = oFile.ReadAll
oFile.Close

Il ne reste plus qu’à remplacer l’attribut alignement de la balise par celui désiré, par exemple (pour centrer) :
>sRead = Replace(sRead, "align=left", "align=center")
>sRead = Replace(sRead, "align=right", "align=center")

La variable sRead contient le code HTML que nous ajoutons à la variable passée en argument.

Les arguments de notre fonction sont :

- Mémoire : la variable à utiliser pour mémoriser la mise en forme ;

- PlageExcel : la plage (de type Range) concernée (s’il s’agit d’un tableau structuré il suffit de passer son nom, voir l’exemple ci-dessous) ;

- Alignement (facultatif) : une valeur de l’énumération EnumMailAlignement qui indique l’alignement à appliquer
- Alignement_Gauche : (par défaut) aligné à gauche,
- Alignement_Centre : centré,
- Alignement_Droite : aligné à droite.

La fonction renvoie True si tout s’est bien passé ou False dans le cas contraire.

Par exemple, pour générer ceci :

à partir de ceci :

'------------------------------------------------------------------------------------------------
Sub Exemple()
'------------------------------------------------------------------------------------------------
Dim M As String

Mail_PlageExcel M, Sheets("Feuil1").Range("A2"), Alignement_Gauche
Mail_Texte M, "", Style_Trait
Mail_PlageExcel M, Range("Tableau1"), Alignement_Gauche
Mail_Texte M, "", Style_Trait

Mail_Envoyer M, False, "", ""
End Sub
'------------------------------------------------------------------------------------------------

Le code de la fonction :

'------------------------------------------------------------------------------------------------
Function Mail_PlageExcel(Mémoire As String, ByVal PlageExcel As Range, _
Optional Alignement As EnumMailAlignement = Alignement_Gauche) As Boolean
'------------------------------------------------------------------------------------------------
' Ajoute à la variable "Mémoire" la plage Excel passée en argument.
'------------------------------------------------------------------------------------------------
' Mémoire : la variable à utiliser pour mémoriser la mise en forme;
' PlageExcel : la plage (de type Range) concernée (s'il s'agit d'un tableau structuré il suffit de
'              passer son nom);
' Alignement : (facultatif) une valeur de l'énumération EnumMailAlignement qui indique l'alignement
'              à appliquer
'   Alignement_Gauche : (par défaut) aligné à gauche,
'   Alignement_Centre : centré,
'   Alignement_Droite : aligné à droite.
'------------------------------------------------------------------------------------------------
' La fonction renvoie True si tout s'est bien passé ou False dans le cas contraire.
'------------------------------------------------------------------------------------------------
Dim fso As Object, oFile As Object, sRead As String, Tps As String

' Gestion des erreurs :
On Error GoTo Gest_Err
Err.Clear

' Si c'est un tableau structuré alors prend l'éventuel en-tête et sous-totaux dans la plage :
If Not (PlageExcel.ListObject Is Nothing) Then
Set PlageExcel = PlageExcel.ListObject.Range
End If

Tps = Environ("USERPROFILE") & "\Mail"
If Dir(Tps, vbDirectory) = "" Then MkDir Tps
Tps = Tps & "\~XLRange.htm"

' Exporte la plage vers un fichier de type HTML, ceci afin de respecter la mise en page de la plage :
ActiveWorkbook.PublishObjects.Add(xlSourceRange, Tps, PlageExcel.Parent.Name, _
PlageExcel.Address, 0, "DivID", "").Publish True

' Lecture du fichier HTML qui a été généré par PublishObjects :
Set fso = CreateObject("Scripting.FileSystemObject")
Set oFile = fso.OpenTextFile(Tps, 1, False)
sRead = oFile.ReadAll
oFile.Close
Set oFile = Nothing
Set fso = Nothing

' Corrige l'alignement mis par défaut pour celui demandé :
Select Case Alignement
Case Alignement_Gauche
sRead = Replace(sRead, "align=center", "align=left")
sRead = Replace(sRead, "align=right", "align=left")
Case Alignement_Droite
sRead = Replace(sRead, "align=center", "align=right")
sRead = Replace(sRead, "align=left", "align=right")
Case Alignement_Centre
sRead = Replace(sRead, "align=left", "align=center")
sRead = Replace(sRead, "align=right", "align=center")
End Select

' Ajoute à la mémoire la plage Excel :
Mémoire = Mémoire & sRead

' Supprime le fichier temporaire :
Kill Tps

' Renvoie Vrai :
Mail_PlageExcel = True

Gest_Err:
Err.Clear
End Function
'------------------------------------------------------------------------------------------------

Cette fonction permet d’inclure du texte formaté contenu dans une plage du classeur actif. Elle remplace dans ce cas la fonction Mail_Texte et permet d’incorporer un message complexe, éventuellement à la main de l’utilisateur s’il faut lui laisser la possibilité de le personnaliser.

Pour une plage de données classique ou un tableau croisé dynamique, pensez à utiliser la propriété CurrentRegion de l’objet Range pour définir automatiquement la plage concernée :
Mail_PlageExcel Sheets("Feuil1").Range("A1").CurrentRegion, Alignement_Gauche

III-F - Mail_FichierImage

La fonction Mail_FichierImage insère un fichier image dans le corps du message (contenu dans la variable passée en argument) grâce à la balise « img src= » sous la forme :
<img src=Image>.
Où Image est le chemin et le nom du fichier image.

Attention, le langage HTML n’accepte pas d’espace ou de caractères spéciaux dans Image, c’est-à-dire ni dans le chemin ni dans le nom du fichier.
Il faudra donc enregistrer une copie du fichier image dans un dossier (dont le nom ne contient pas d’espace) en lui donnant un nom sans espace.

Pour le dossier, j’ai retenu la solution du répertoire de travail de l’utilisateur obtenu par la fonction Environ("USERPROFILE") et son sous-répertoire « \Mail » comme nous venons de le voir dans la fonction précédente. En théorie, ce nom de répertoire ne contient pas d’espace(5) ni de caractères spéciaux(6) (en tout cas, c’est recommandé par Windows).

Pour le nom du fichier, afin d’éviter un doublon avec un nom existant, j’ai retenu d’attribuer un numéro issu de la date et de l’heure obtenu avec la fonction Now, suivi d’un nombre aléatoire et de l’extension du fichier d’origine obtenu par :
Ext = Mid(FichierImage, InStrRev(FichierImage, "."))

Faire précéder le nom du fichier temporaire par « ~Mail~ » permet d’identifier ces fichiers pour les supprimer du dossier après l’envoi du courriel.
Tps = Environ("USERPROFILE") & "\Mail"
Tps = Tps & "\~Mail~" & Format(Now * 1000000000, "0000000000") & Format(Rnd * 10000, "00000")
Tps = Tps & Ext

La copie se fait avec l’instruction :
FileCopy FichierImage, Tps

La balise peut être complétée soit de l’attribut largeur (width), soit de l’attribut hauteur (height).

L’image sera incluse dans une balise paragraphe (<p>) qui contient l’attribut alignement (align) qui peut être définit.

Les arguments la fonction sont :

- Mémoire : la variable à utiliser pour mémoriser la mise en forme ;

- FichierImage : l’adresse du fichier concerné ;

- Alignement (facultatif) : une valeur de l’énumération EnumMailAlignement qui indique l’alignement à appliquer
- Alignement_Gauche : aligné à gauche, c’est la valeur par défaut,
- Alignement_Centre : centré,
- Alignement_Droite : aligné à droite ;

- Largeur (facultatif) : la largeur de l’image (par défaut la taille d’origine est conservée) ;

- Hauteur (facultatif) : la hauteur de l’image (par défaut la taille d’origine est conservée).

Le ratio largeur / hauteur de l’image est conservé, vous pouvez définir l’une de ces deux valeurs, mais pas les deux en même temps.

La fonction renvoie True si tout s’est bien passé ou False dans le cas contraire.

Par exemple, pour générer ceci :

'------------------------------------------------------------------------------------------------
Sub Exemple()
'------------------------------------------------------------------------------------------------
Dim M As String

' Adaptez l’exemple en indiquant un fichier image de votre ordinateur :
Mail_Texte M, "À bientôt sur :"
Mail_FichierImage M, "C :\Users\ott_l\Downloads\Logo.jpg", Alignement_Gauche, 300

Mail_Envoyer M, False, "", ""
End Sub
'------------------------------------------------------------------------------------------------

Le code de la fonction :

'------------------------------------------------------------------------------------------------
Function Mail_FichierImage(Mémoire As String, FichierImage As String, _
Optional Alignement As EnumMailAlignement = Alignement_Gauche, _
Optional Largeur As Long = 0, _
Optional Hauteur As Long = 0) As Boolean
'------------------------------------------------------------------------------------------------
' Ajoute à la variable "Mémoire" le fichier image passé dans FichierImage.
'------------------------------------------------------------------------------------------------
' Mémoire : la variable à utiliser pour mémoriser la mise en forme;
' FichierImage : l'adresse du fichier concerné;
' Alignement : (facultatif) une valeur de l'énumération EnumMailAlignement qui indique l'alignement
'              à appliquer
'   Alignement_Gauche : (par défaut) aligné à gauche,
'   Alignement_Centre : centré,
'   Alignement_Droite : aligné à droite;
' Largeur : (facultatif) la largeur de l'image (par défaut la taille d'origine est conservée);
' Hauteur: (facultatif) la hauteur de l'image (par défaut la taille d'origine est conservée).
' Le ratio largeur / hauteur de l'image est conservé, vous pouvez définir l'une de ces deux valeurs
' mais pas les deux en même temps.
'------------------------------------------------------------------------------------------------
' La fonction renvoie True si tout s'est bien passé ou False dans le cas contraire.
'------------------------------------------------------------------------------------------------
Dim sAlign As String, Tps As String, Ext As String

On Error GoTo Gest_Err
Err.Clear

' Vérifie la présence du fichier:
If Dir(FichierImage) <> "" And InStr(1, FichierImage, ".") > 0 Then

' Création d'un fichier temporaire dans un répertoire temporaire sans les espaces dans
' le nom du fichier et du répertoire car ils ne sont pas acceptés dans la balise image:
Ext = Mid(FichierImage, InStrRev(FichierImage, "."))
Tps = Environ("USERPROFILE") & "\Mail"
If Dir(Tps, vbDirectory) = "" Then MkDir Tps
Tps = Tps & "\~Mail~" & Format(Now * 1000000000, "0000000000") & Format(Rnd * 10000, "00000")
Tps = Tps & Ext
FileCopy FichierImage, Tps

' Paramétrage de l'alignement horizontal:
Select Case Alignement
Case Alignement_Centre: sAlign = "center"
Case Alignement_Droite: sAlign = "right"
Case Else: sAlign = "left"
End Select

' Ajoute l'image:
If Largeur <> 0 Then Hauteur = 0
Mémoire = Mémoire & "<p align=" & sAlign & "> <img src=" & Tps _
& IIf(Largeur > 0, " width=" & Largeur, "") _
& IIf(Hauteur > 0, " height=" & Hauteur, "") _
& "> </p>"

Mail_FichierImage = True

End If

Gest_Err:
Err.Clear

End Function
'------------------------------------------------------------------------------------------------

III-G - Mail_GraphiqueExcel

La fonction Mail_GraphiqueExcel insère un graphique issu du classeur actif dans le corps du message.

Techniquement, le graphique est exporté en fichier JPG temporaire enregistré dans le répertoire de l’utilisateur (voir les fonctions précédentes), puis inséré dans le corps du message comme un fichier image avec Mail_FichierImage.

Le graphique peut être :

- un graphique situé sur une feuille de calcul, il sera exporté par la méthode Worksheets(Feuille).ChartObjects(NomGraphique).Chart.Export(sFile, "JPG") ;

- une feuille de graphique, elle sera exportée par la méthode Sheets(Feuille).Export(sFile, "JPG").

Où :
Feuille est le nom de la feuille de calcul ou de la feuille de graphique ;
NomGraphique est le nom de l’objet Chart (le nom du graphique) ;
sFiles est le nom du fichier image temporaire.

Ses arguments sont :

- Mémoire : la variable à utiliser pour mémoriser la mise en forme ;

- Feuille : le nom de la feuille où est le graphique concerné ;

- NomGraphique : le nom de l’objet graphique s’il s’agit d’un graphique sur une feuille de calcul ;

- Alignement (facultatif) : une valeur de l’énumération EnumMailAlignement qui indique l’alignement à appliquer
- Alignement_Gauche : aligné à gauche, c’est la valeur par défaut
- Alignement_Centre : centré,
- Alignement_Droite : aligné à droite ;

- Largeur (facultatif) : la largeur de l’image (par défaut la taille d’origine est conservée) ;

- Hauteur (facultatif) : la hauteur de l’image (par défaut la taille d’origine est conservée).

Le ratio largeur / hauteur de l’image est conservé, vous pouvez définir l’une de ces deux valeurs, mais pas les deux en même temps.

La fonction renvoie True si tout s’est bien passé ou False dans le cas contraire.

Par exemple, pour générer ceci :

'------------------------------------------------------------------------------------------------
Sub Exemple()
'------------------------------------------------------------------------------------------------
Dim M As String

' Une feuille de graphique (la feuille nommée Graphique2) :
Mail_GraphiqueExcel M, "Graphique2", "", Alignement_Droite, , 200

' Un graphique issu d'une plage d'une feuille (nommé MonGraphique sur la feuille Feuil1) :
Mail_GraphiqueExcel M, "Feuil1", "MonGraphique", Alignement_Gauche, , 200

Mail_Envoyer M, False, "", ""
End Sub
End Sub
'------------------------------------------------------------------------------------------------

Le code de la fonction :

'------------------------------------------------------------------------------------------------
Function Mail_GraphiqueExcel(Mémoire As String, Feuille As String, NomGraphique As String, _
Optional Alignement As EnumMailAlignement = Alignement_Gauche, _
Optional Largeur As Long = 0, _
Optional Hauteur As Long = 0) As Boolean
'------------------------------------------------------------------------------------------------
' Ajoute à la variable "Mémoire" (sous forme d'image) le graphique Excel passé en argument.
'------------------------------------------------------------------------------------------------
' Mémoire : la variable à utiliser pour mémoriser la mise en forme;
' Feuille : le nom de la feuille où est le graphique concerné;
' NomGraphique : le nom de l'objet graphique s'il s'agit d'un graphique sur une feuille de calcul;
' Alignement : (facultatif) une valeur de l'énumération EnumMailAlignement qui indique l'alignement
'              à appliquer
'   Alignement_Gauche : (par défaut) aligné à gauche,
'   Alignement_Centre : centré,
'   Alignement_Droite : aligné à droite;
' Largeur : (facultatif) la largeur de l'image (par défaut la taille d'origine est conservée);
' Hauteur: (facultatif) la hauteur de l'image (par défaut la taille d'origine est conservée).
' Le ratio largeur / hauteur de l'image est conservé, vous pouvez définir l'une de ces deux valeurs
' mais pas les deux en même temps.
'------------------------------------------------------------------------------------------------
' La fonction renvoie True si tout s'est bien passé ou False dans le cas contraire.
'------------------------------------------------------------------------------------------------
Dim sFile As String, Tps As String

' Gestion des erreurs :
On Error GoTo Gest_Err
Err.Clear

' Création d'un fichier image temporaire dans le répertoire de l'utilisateur :
Tps = Environ("USERPROFILE") & "\Mail"
If Dir(Tps, vbDirectory) = "" Then MkDir Tps
sFile = Tps & "\~Mail~" & Format(Now * 1000000000, "0000000000") & Format(Rnd * 10000, "00000") & ".jpg"

' Copie le graphique dans un fichier image temporaire, deux cas possibles :
' - le graphique est sur une feuille de calcul, donc NomGraphique contient son nom,
' - le graphique est sur une feuille de graphique, donc NomGraphique est vide.
If NomGraphique <> "" Then
Call Worksheets(Feuille).ChartObjects(NomGraphique).Chart.Export(sFile, "JPG")
Else
Call Sheets(Feuille).Export(sFile, "JPG")
End If

' Ajoute cette image :
Mail_FichierImage Mémoire, sFile, Alignement, Largeur, Hauteur

' Renvoie Vrai :
Mail_GraphiqueExcel = True

Gest_Err:
Err.Clear

End Function
'------------------------------------------------------------------------------------------------

IV - Utiliser ces fonctions avec un modèle de message Outlook

Les fonctions du chapitre précédent vous serviront pour générer un message au format HTML, comme nous l’avons fait jusqu’à présent dans les différents exemples présentés, mais aussi pour compléter un modèle de message en y insérant des informations issues du classeur Excel.

Prenons l’exemple de cette présentation diffusée toutes les semaines à des collaborateurs :

Jusqu’à présent, nous utilisions les fonctions pour générer l’intégralité du message.
Les données, y compris les textes, pouvant être issues du classeur Excel (paramétrées par l’utilisateur ou un administrateur) et pas forcément en dur dans le code.

L’autre possibilité est de créer dans Outlook un modèle de message qui contiendra le format de présentation désiré et des « repères » personnels (ici mis arbitrairement entre accolades, mais vous pouvez choisir le signe distinctif de votre choix) où devront être incluses les données issues du classeur Excel.

Dans notre cas, il y a trois repères, pour le numéro de la semaine, le tableau des données et le graphique.

Le modèle est enregistré au « format de message Outlook (.msg) », par exemple « Modèle.msg » dans le répertoire de l’application.

La FAQ(7) du site « developpez.com » donne toutes les informations pour ouvrir une session Outlook par CreateObject("Outlook.Application") et lire notre fichier modèle en utilisant la méthode CreateItemFromTemplate de l’objet MailItem.

Le corps du message, contenu dans oMail.HTMLBody, peut alors être modifié.

Nous remplacerons dans le code ci-dessous :

- le repère {Semaine} par une valeur contenue dans le classeur Excel en « Feuil1!B14 » avec
oMail.HTMLBody = Replace(oMail.HTMLBody, "{Semaine}", Sheets("Feuil1").Range("B14")) ;

- le repère {Tableau} par la plage du tableau structuré « Tableau1 » formatée en HTML par la fonction Mail_PlageExcel ;

- le repère {Graphique} par le graphique de la feuille « Graphique2 » formaté en HTML par la fonction Mail_GraphiqueExcel ;

Ce qui donne cet exemple :

'------------------------------------------------------------------------------------------------
Function Exemple_Modèle() As String
'------------------------------------------------------------------------------------------------
Dim AppOutlook As Object, oMail As Object
Dim Fichier As String, HTML_Tableau As String, HTML_Graphique As String

On Error GoTo Gest_Err
Err.Clear

' Adresse du fichier Modèle à utiliser :
Fichier = ThisWorkbook.Path & "\Modèle.msg"

' Ouverture d'une session Outlook :
Set AppOutlook = CreateObject("Outlook.Application")

' Récupération du message:
Set oMail = AppOutlook.CreateItemFromTemplate(Fichier)

' Remplace le repère {Semaine} :
oMail.HTMLBody = Replace(oMail.HTMLBody, "{Semaine}", Sheets("Feuil1").Range("B14"))

' Remplace le repère {Tableau} par le Tableau Structuré "Tableau1" :
Mail_PlageExcel HTML_Tableau, Range("Tableau1")
oMail.HTMLBody = Replace(oMail.HTMLBody, "{Tableau}", HTML_Tableau)

' Remplace le repère {Graphique} par le graphique de la feuille "Graphique2" :
Mail_GraphiqueExcel HTML_Graphique, "Graphique2", "", Alignement_Gauche, , 100
oMail.HTMLBody = Replace(oMail.HTMLBody, "{Graphique}", HTML_Graphique)

' Renvoie le corps du message alimenté :
Exemple_Modèle = oMail.HTMLBody

' Fin du traitement :
Gest_Err:
Err.clear

If Not oMail Is Nothing Then Set oMail = Nothing
If Not AppOutlook Is Nothing Then Set AppOutlook = Nothing

End Function
'------------------------------------------------------------------------------------------------

Notez que ce code utilise les liaisons tardives, il n’est donc pas nécessaire d’installer une bibliothèque Outlook.

Cette fonction renvoie le corps du message alimenté des données HTML qui remplacent les repères (ou renvoie une chaîne vide en cas d’erreur), mais vous pouvez écrire une fonction qui envoie directement le message.

Vous l’avez sûrement deviné, il aurait été possible de mettre aussi un repère sur le lien de messagerie, le lien hypertexte ou l’image, et de se servir des fonctions Mail_LienMessagerie, Mail_LienHypertexte et Mail_FichierImage pour les renseigner.

Je ne l’ai pas fait, car je suis parti du principe que le modèle peut être modifié directement par l’utilisateur pour mettre à jour ces informations en cas d’évolution, tout comme le format du texte et son contenu.

Cette facilité est un avantage ou un inconvénient, tout dépend du but recherché et des contraintes.

En cas de besoin, vous disposez des fonctions nécessaires pour alimenter intégralement le corps de ce modèle de message.

V - Envoyer un courriel formaté HTML par Outlook – Mail_Envoyer

Les fonctions étudiées ont permis la génération d’un corps de message au format HTML.

Les exemples font appel à la fonction Mail_Envoyer pour vous permettre de les tester (si vous disposez d’Outlook).

Il est temps de voir cette fonction…

La fonction Mail_Envoyer génère un courriel en renseignant le corps du message de la variable passée en argument, préalablement alimentée par les fonctions étudiées.

La fonction présentée ici se contente d’une configuration de l’objet MailItem rudimentaire, mais qui sera suffisante dans bien des cas.

Vous vous en inspirerez pour développer une fonction qui correspond mieux à vos besoins.

La fonction Mail_Envoyer utilise les liaisons tardives, il n’est donc pas nécessaire d’installer une bibliothèque Outlook pour s’en servir.

Ses arguments sont :

- Mémoire : la variable qui contient le corps du message ;

- EnvoyerMail : soit True pour envoyer le message, soit False pour l’afficher uniquement ;

- Destinataires : la ou les adresses de messagerie du ou des destinataires (adresses séparées par des points-virgules) ;

- ObjetMail : l’objet du message (le sujet) ;

- Copies (facultatif) : la ou les adresses de messagerie du ou des personnes en copie (adresses séparées par un point-virgule) ;

- Caches (facultatif) : la ou les adresses de messagerie du ou des personnes en copie cachée (adresses séparées par un point-virgule) ;

- PiecesJointes (facultatif) : le ou les fichiers à mettre en pièces jointes, séparés par un point-virgule ;

- AdresseExpediteur (facultatif) : adresse de messagerie à utiliser si différente de la messagerie de l’expéditeur, cas par exemple pour une boîte générique pour ne pas être destinataire des éventuelles réponses ;

- ErrDescription (facultatif) : contiendra le message d'erreur en cas d'erreur de traitement.

La fonction renvoie True si tout s’est bien passé ou False dans le cas contraire et la variable ErrDescription contiendra la description de l'erreur.

La fonction vérifie la présence des pièces jointes et génère une erreur si elles ne sont pas présentes.

Vous trouverez plus d’informations sur les propriétés de l’objet MailItem dans cette rubrique : https://docs.microsoft.com/fr-fr/office/vba/api/outlook.mailitem.

N’oubliez pas le Forum Outlook : https://www.developpez.net/forums/f555/logiciels/microsoft-office/outlook/

'------------------------------------------------------------------------------------------------
Sub Exemple()
'------------------------------------------------------------------------------------------------
Dim M As String
Dim Erreur As String

Mail_Texte M, "Bonjour ", Style_Gras, Couleur_Rouge
Mail_Texte M, "tout le monde", Style_Souligne + Style_Italique
Mail_SautDeLigne M, 3
Mail_Texte M, "Bienvenue sur Developpez.com", , , , 6

If Mail_Envoyer(M, EnvoyerMail:=False, _
Destinataires:="MonAdresse@MonDomaine.com", _
ObjetMail:="Test de message", _
ErrDescription:=Erreur) = False Then
MsgBox Erreur
Else
MsgBox "Fin du traitement"
End If

End Sub
'------------------------------------------------------------------------------------------------

Le code de la fonction :

'------------------------------------------------------------------------------------------------
Function Mail_Envoyer(Mémoire As String, EnvoyerMail As Boolean, _
Destinataires As String, _
ObjetMail As String, _
Optional Copies As String = "", _
Optional Caches As String = "", _
Optional PiecesJointes As String = "", _
Optional AdresseExpediteur As String = "", _
Optional ErrDescription As String = "") As Boolean
'------------------------------------------------------------------------------------------------
' Génération du Mail.
'------------------------------------------------------------------------------------------------
' Mémoire : la variable à utiliser pour mémoriser la mise en forme;
' EnvoyerMail : soit True pour envoyer le message, soit False pour l'afficher uniquement;
' Destinataires : le ou les adresses de messagerie du ou des destinataires (adresses séparées par
'                 un point-virgule);
' ObjetMail : l'objet du message (le sujet);
' Copies : (facultatif) la ou les adresses de messagerie du ou des personnes en copie (adresses séparées
'          par un point-virgule);
' Caches : (facultatif) la ou les adresses de messagerie du ou des personnes en copie cachée (adresses
'          séparées par un point-virgule);
' PiecesJointes : (facultatif) le ou les fichiers à mettre en pièces jointes, séparés par un point-virgule;
' AdresseExpediteur (facultatif) : adresse de messagerie à utiliser si différente de la messagerie
'                   de l'expéditeur, cas par exemple pour une boîte générique pour ne pas être destinataire
'                   des éventuelles réponses.
' ErrDescription : contiendra le message d'erreur en cas d'erreur.
'------------------------------------------------------------------------------------------------
' La fonction renvoie True si tout s'est bien passé ou False dans le cas contraire.
'------------------------------------------------------------------------------------------------
Dim AppOutlook As Object, oMail As Object, Tb, i As Integer

' Gestion des erreurs :
On Error GoTo Gest_Err
Err.Clear

' Ouverture d'une session Outlook :
Set AppOutlook = CreateObject("Outlook.Application")

' Création d'un message:
Set oMail = AppOutlook.CreateItem(0)

oMail.To = Destinataires
oMail.CC = Copies
oMail.BCC = Caches
oMail.SentOnBehalfOfName = AdresseExpediteur
oMail.Subject = ObjetMail
oMail.BodyFormat = 2 ' (olFormatHTML = 2 est la valeur par défaut)
oMail.HTMLBody = Mémoire & oMail.HTMLBody

' Ajout des pièces jointes si passées en argument, après contrôle du chemin.
Tb = Split(PiecesJointes, ";")
For i = LBound(Tb) To UBound(Tb)
If Dir(Tb(i)) <> "" Then
oMail.Attachments.Add Tb(i)
Else
Err.Raise vbObjectError, , "La pièce jointe [" & Tb(i) & "] n'est pas valide."
End If
Next i

' Affiche le message ou l'envoie (après Display pour charger les images) :
oMail.Display
DoEvents
If EnvoyerMail = True Then
oMail.Send
DoEvents
End If

' Renvoie VRAI si tout s'est bien passé :
Mail_Envoyer = True

Gest_Err:
If Err.Number <> 0 Then ErrDescription = Err.Description

If Not oMail Is Nothing Then Set oMail = Nothing
If Not AppOutlook Is Nothing Then Set AppOutlook = Nothing

' Supprime les images temporaires :
Mail_SupprimerFichiersTps

End Function
'------------------------------------------------------------------------------------------------

Et la fonction qui permet de supprimer les fichiers temporaires :

'------------------------------------------------------------------------------------------------
Sub Mail_SupprimerFichiersTps()
'------------------------------------------------------------------------------------------------
' Supprime les éventuelles images temporaires.
'------------------------------------------------------------------------------------------------
On Error GoTo Gest_Err

If Dir(Environ("USERPROFILE") & "\Mail" & "\~Mail~*.*") <> "" Then
Kill Environ("USERPROFILE") & "\Mail" & "\~Mail~*.*"
End If

Gest_Err:
Err.Clear
End Sub
'------------------------------------------------------------------------------------------------

VI - Conclusion

Les fonctions présentées dans cette documentation vous permettront de générer facilement un courrier électronique formaté, contenant des liens hypertextes, des tableaux, des graphiques, des images ou d’alimenter de données HTML un modèle existant.

Gardez à l’esprit qu’une présentation soignée de vos messages est aussi un signe de respect envers ceux qui vous lisent.

Vous trouverez en annexe 1, pour ceux qui sont concernés par le sujet, deux fonctions :
- pour convertir des fichiers images en un format différent afin de les rendre compatibles avec les outils de vos destinataires ;
- pour en diminuer la taille afin d’alléger vos messages.

Pour compresser vos pièces jointes au format ZIP en utilisant le VBA, consultez cette documentation.

Découvrez dans cette discussion comment insérer des caractères spéciaux dans le sujet de vos messages.

Bonne programmation.

Laurent OTT.
2022.

VII - Remerciements

Je remercie Pierre Fauconnier pour sa relecture technique et escartefigue pour la correction orthographique.

Ainsi que toute l’équipe de Developpez.com qui contribue à la maintenance du site.

VIII - Le fichier joint

Vous trouverez le fichier Mail-Outlook.xlsm qui contient les fonctions étudiées dans cette documentation. Ces fonctions sont regroupées dans le module « Mail » facilement exportable dans vos applications par un simple « glisser/copier » depuis l’explorateur de projet VBA.

Ce fichier contient également la feuille de calcul et la feuille de graphique des exemples.

Ainsi que les modules :

- Exemples : qui reprend les exemples de la documentation ;

- ConvertImage : qui reprend les fonctions de l’annexe 1.

IX - Des liens utiles

Des liens qui m’ont apporté de nombreuses informations et que je vous recommande si vous souhaitez approfondir vos connaissances sur le langage HTML.

Sources :

https://www.developpez.net/forums/d1581644/logiciels/microsoft-office/excel/macros-vba-excel/insertion-image-jpg-corps-mail-outlook-via-macro-excel/

https://excel.developpez.com/faq/?page=Messagerie#PlageCellulesMail

Une introduction au HTML :

https://maisondescarnets.hypotheses.org/5239

https://tutorialehtml.com/fr/html-tutoriel-html-complet/

Liste des balises :

https://web.maths.unsw.edu.au/~lafaye/CCM/html/htmlstyle.htm

http://www.oujood.com/liste-balises-html.php

Liste des 140 couleurs normées :

https://htmCouleurcodes.com/fr/noms-de-couleur/

X - Annexe 1 – fonctions pour convertir ou redimensionner une image

Les deux fonctions présentées ici vous permettront de convertir des fichiers images en un format différent afin de les rendre compatibles avec les outils de vos destinataires (supporte les formats BMP, GIF, JPG, PNG, TIF) ou d’en diminuer la taille afin d’alléger vos pièces jointes.

Elles sont inspirées de cette documentation de Silkyroad et Bbil qui propose d’autres fonctionnalités dans le traitement des images.

'------------------------------------------------------------------------------------------------
Public Function ConvertirImage(ImageSource As String, ImageDestination As String, _
Optional Qualité As Integer = 100) As Boolean
'---------------------------------------------------------------------------------------
' Convertit une image source en BMP, GIF, JPG, PNG, TIF
' L'extension de l'image destination indique le format à appliquer.
'---------------------------------------------------------------------------------------
' Exemple pour convertir une image BMP en JPG:
' Call ConvertirImage("C:\_Temporaire\foret.bmp", "C:\_Temporaire\foret.jpg")
'---------------------------------------------------------------------------------------
' Sources: https://silkyroad.developpez.com/VBA/WindowsImageAcquisition/
'---------------------------------------------------------------------------------------
Dim Img As Object, IP As Object
Dim FormatID As String

' Gestion des erreurs :
On Error GoTo Gest_Err
Err.Clear

' Le format à appliquer est déduit de l'extension du fichier image destination :
Select Case UCase(Right(ImageDestination, 4))
Case ".BMP": FormatID = "{B96B3CAB-0728-11D3-9D7B-0000F81EF32E}"
Case ".JPG": FormatID = "{B96B3CAE-0728-11D3-9D7B-0000F81EF32E}"
Case ".GIF": FormatID = "{B96B3CB0-0728-11D3-9D7B-0000F81EF32E}"
Case ".PNG": FormatID = "{B96B3CAF-0728-11D3-9D7B-0000F81EF32E}"
Case ".TIF": FormatID = "{B96B3CB1-0728-11D3-9D7B-0000F81EF32E}"
Case Else
Err.Raise vbObjectError, , "L'extension du fichier image destination [" & ImageDestination & "] n'est pas reconnue."
End Select

' Création conteneur pour l'image à manipuler :
Set Img = CreateObject("WIA.ImageFile")

' Création du gestionnaire de filtre :
Set IP = CreateObject("WIA.ImageProcess")

' Chargement de l'image dans le conteneur :
Img.LoadFile ImageSource

' Ajoute le filtre pour convertir l'image (Convert) :
IP.Filters.Add IP.FilterInfos("Convert").FilterID

' Définit le format :
IP.Filters(1).Properties("FormatID") = FormatID

' Définit la qualité:
If Qualité < 1 Or Qualité > 100 Then Qualité = 100
IP.Filters(1).Properties("Quality") = Qualité

' Application du filtre à l'image :
Set Img = IP.Apply(Img)

' Enregistre l'image:
If Dir(ImageDestination) <> "" Then Kill ImageDestination
Img.SaveFile ImageDestination
ConvertirImage = True

' Gestion des erreurs:
Gest_Err:
If Err.Number <> 0 Then MsgBox "Erreur: " & Err.Number & " - " & Err.Description, _
vbCritical + vbOKOnly, "ConvertirImage"
Err.Clear
End Function
'------------------------------------------------------------------------------------------------

'------------------------------------------------------------------------------------------------
Public Function RedimensionnerImage(ImageSource As String, ImageDestination As String, _
HauteurMaxi As Long, LargeurMaxi As Long) As Boolean
'---------------------------------------------------------------------------------------
' Redimensionne une image.
' Remarque : les proportions sont conservées. Le filtre prend en compte
' les ratios et adapte la taille pour ne pas dépasser les valeurs maxi définies.
'---------------------------------------------------------------------------------------
' Source: https://silkyroad.developpez.com/VBA/WindowsImageAcquisition/
'---------------------------------------------------------------------------------------
Dim Img As Object, IP As Object

' Gestion des erreurs :
On Error GoTo Gest_Err
Err.Clear

'Création conteneur pour l'image à manipuler :
Set Img = CreateObject("WIA.ImageFile")

'Création du gestionnaire de filtre :
Set IP = CreateObject("WIA.ImageProcess")

'Chargement de l'image dans le conteneur:
Img.LoadFile ImageSource

'Ajoute le filtre pour redimensionner l'image (Scale) :
IP.Filters.Add IP.FilterInfos("Scale").FilterID

'Définit la largeur maxi pour le redimensionnement :
IP.Filters(1).Properties("MaximumWidth") = LargeurMaxi

'Définit la hauteur maxi pour le redimensionnement :
IP.Filters(1).Properties("MaximumHeight") = HauteurMaxi

' Application du filtre à l'image :
Set Img = IP.Apply(Img)

'Enregistre l'image redimensionnée :
If Dir(ImageDestination) <> "" Then Kill ImageDestination
Img.SaveFile ImageDestination
RedimensionnerImage = True

' Gestion des erreurs :
Gest_Err:
If Err.Number <> 0 Then MsgBox "Erreur: " & Err.Number & " - " & Err.Description, _
vbCritical + vbOKOnly, "RedimensionnerImage"
Err.Clear
End Function
'------------------------------------------------------------------------------------------------

XI - Annexe 2 – les énumérations du module

Pour compléter les codes présentés, voici les énumérations utilisées, déclarées en en-tête du module :

'------------------------------------------------------------------------------------------------
Enum EnumMailCouleur
Couleur_Noir = 0
Couleur_Blanc = 16777215
Couleur_Rouge = 16711680
Couleur_Bleu = 255
Couleur_Rose = 16716947
Couleur_Orange = 16753920
Couleur_Jaune = 16776960
Couleur_Magenta = 16711935
Couleur_Indigo = 4915330
Couleur_Vert = 32768
End Enum

Enum EnumMailAlignement
Alignement_Gauche = 0
Alignement_Centre = 1
Alignement_Droite = 2
End Enum

Enum EnumMailStyle
Style_Normal = 0
Style_Gras = 2
Style_Italique = 4
Style_Souligne = 8
Style_Exposant = 16
Style_Indice = 32
Style_Trait = 64
Style_Centre = 128
Style_SautDeLigne = 512
End Enum
'------------------------------------------------------------------------------------------------

(1) « Le HyperText Markup Language, généralement abrégé HTML ou, dans sa dernière version, HTML5, est le langage de balisage conçu pour représenter les pages web.  » (Wikipédia)

(2) And, opérateur - Visual Basic | Microsoft Docs

(3) Table de vérité — Wikipédia (wikipedia.org)

(4) Méthode PublishObjects.Add (Excel) | Microsoft Docs

(5) Créer un compte d’utilisateur administratif | Microsoft Docs

(6) Erreur lorsque vous créez un nom d’utilisateur qui contient un caractère spécial - Office | Microsoft Docs

(7) https://excel.developpez.com/faq/?page=Messagerie#LireFichierMSG