XL 2016 VBA - Mail Outlook - Impossible d'insérer dans le corps du mail les "Embbeded" images

Dudu2

XLDnaute Barbatruc
Bonjour,

Je galère à essayer de placer les images "embbeded" d'un mail Outlook dans le corps du message, là où je veux qu'elles se placent et non pas à la fin du mail.

Voilà ce que ça donne avec ce .HTMLBody = <BODY><HTML>Bonjour<BR>Première image<BR><IMG src=cid:'EmbbededImage1.jpg'><BR>Deuxième image<BR><IMG src=cid:'EmbbededImage2.jpg' width='200'><BR>Fin du mail</HTML></BODY>

Et les bons attachments (qui sont bien attachés au mail !)
.Attachments.Add "H:\Téléchargements\EmbbededImage1.jpg", 1, 0
.Attachments.Add "H:\Téléchargements\EmbbededImage2.jpg", 1, 0

1628157180544.png


Merci pour toute information utile.
 
Dernière édition:
Solution
J'ai pris une approche simplificatrice pour l'envoi d'email avec Outlook en définissant une structure d'interface qu'il suffit de remplir pour s'éviter toute la mise en place dans les objets de mail Outlook.
VB:
'--------------------------------------------------------------------------------
'Interface à valoriser pour envoyer un mail Outlook via la fonction MailOutlook()
'--------------------------------------------------------------------------------
Public Type OUTLOOK_DATA
    SendUsingAccount As Variant         'Nom du compte à utiliser (ex.:moncompte@domaine.com)
                                        'Numéro de séquence (1-n) du compte OutLook à utiliser.
                                        'Si Numéro = 0, la liste...

patricktoulon

XLDnaute Barbatruc
un exemple
ici j'enregistre une plage en image et je l'envoie par mail avec outlook
VB:
'-------------------------------------
'patricktoulon
'date: 03/06/2021
'outlook en late binding
'PAS DE REFERENCE A ACTIVER
'-------------------------------------
Option Explicit
Sub test4()
    Dim oApp As Object, oEmail As Object, colAttach As Object, oAttach As Object, plage As Range, olkPA As Object
    Dim Destinataire$, CC$, Titre$, NomPdf$, NomImage$, imG$, paragraph1$, paragraph2$, xHTMLBody$
    Const PR_ATTACH_CONTENT_ID = "http://schemas.microsoft.com/mapi/proptag/0x3712001F"

    Set plage = Feuil1.[A1:c10]    ' plage à envoyer dans le corps du mail

    NomImage = ThisWorkbook.Path & "\imgTemp.gif": If Dir(NomImage) <> "" Then Kill (NomImage)    ' ne pas toucher ça
    NomPdf = ThisWorkbook.Path & "\pdfTemp.pdf": If Dir(NomPdf) <> "" Then Kill (NomPdf)   ' adapter le chemin du fichier pdf

    '------------------------------
    'exportation des fichiers temporaires
    'création du pdf avec la plage
    plage.ExportAsFixedFormat Type:=xlTypePDF, Filename:=NomPdf, Quality:=xlQualityStandard, IncludeDocProperties:=True, IgnorePrintAreas:=False, OpenAfterPublish:=False

    'creation de la capture de la plage en image
    imG = ExportRangeInImage(plage, NomImage)
    If imG = "" Then MsgBox "la copie de la plage en image n'a pas pu etre effectué": Exit Sub
    '----------------------------

    'élements du mail
    Titre = "test de mail outlook VBA shema late binding"    'titre du message

    Destinataire = "toto2@outlook.fr"    'destinataire(s) du message( si plusieurs séparer  les par une virgule)

    CC = ""    ' accusé reception

    'texte que tu veux avant la plage dans le mail(facultatif)
    paragraph1 = "envoyé à " & Time & vbCrLf & "Bonjour Mr le directeur " & vbCrLf & "veuillez trouver ci joint  le tableau des ventes de concombres"
    paragraph1 = paragraph1 & vbCrLf & " il resume les ventes du mois "

    'texte que tu veux apres la plage dans le mail(facultatif)
    paragraph2 = " vous souhaitant bonne réception" & vbCrLf & "restant a votre disposition pour tout renseignement"
    paragraph2 = paragraph2 & vbCrLf & " votre dévoué serviteur  <font face=algerian color=red>le Concombre masqué</font>"

    'création du code html du body apec les paragraphes et l'image de la plage
    xHTMLBody = "<BODY>" & Replace(paragraph1, vbCrLf, "<br>") & "<br><br>" & _
                "<center><img src=""cid:imgTemp.gif""></center><br><br>" & _
                Replace(paragraph2, vbCrLf, "<br>")
    xHTMLBody = xHTMLBody & "</BODY>"
    '----------------------------

    ''création du mail
    Set oApp = CreateObject("Outlook.Application")    'instance outlook
    Set oEmail = oApp.CreateItem(olMailItem)    'instance de l'item mail dans outlook

    Set colAttach = oEmail.Attachments    ' ça c'est la collection des attachements

    '----------------------------------------------------------------------
    ' a répéter pour chaque image placées dans le body!!!!!!!!!!!
    'on attache l'image
    Set oAttach = colAttach.Add(NomImage)    'on ajoute dans la collection d'attachements l'image de la plage
    Set olkPA = oAttach.PropertyAccessor    'collection des properties d'accessibilité de l'attachement
    olkPA.SetProperty PR_ATTACH_CONTENT_ID, "imgTemp.gif"    '' application de la propriété cid a l'attachement
    '----------------------------------------------------------------------

    oEmail.HTMLBody = xHTMLBody    ' insertion du code html dans le body du mail

    oEmail.To = Destinataire
    oEmail.Subject = Titre
    oEmail.CC = CC   ' accusé
    oEmail.Attachments.Add NomPdf    ' on attache le pdf de façon classique
    oEmail.Display
    'oEmail.Send

    ' vide les variable
    Set oEmail = Nothing
    Set colAttach = Nothing
    Set oAttach = Nothing
    Set oApp = Nothing
End Sub

Private Function ExportRangeInImage(plage As Range, CheminX As String)
'export plage en gif patricktoulon sur exceldownloads
    Dim chart1 As Object
    If Dir(CheminX) <> "" Then Kill CheminX
    With CreateObject("htmlfile").parentwindow.clipboardData.clearData("Text"): End With    'on vide le clipboard entre chaque copie pour tester vraiment le available
    plage.CopyPicture
    Set chart1 = plage.Parent.ChartObjects.Add(0, 0, 0, 0).Chart
    With chart1
        With .Parent: .Width = plage.Width: .Height = plage.Height: .Left = plage.Width + 20:
            .Parent.Shapes(.Name).Line.Visible = False
            Do: .Chart.Paste: DoEvents: Loop While .Chart.Pictures.Count = 0
            .Chart.Export CheminX, "gif"
        End With
        .Parent.Delete
    End With
    ExportRangeInImage = Dir(CheminX)
End Function

et voila comment il arrive dans ma boite mail
1628159938232.png
 
Dernière édition:

Dudu2

XLDnaute Barbatruc
Bonjour @patricktoulon,

Oui, j'ai un code qui fait ça aussi mais ça ne marche pas.

Est-ce que tu peux essayer STP dans ton code de place le CID dans une variable (Variant plutôt que String)
VB:
olkPA.SetProperty PR_ATTACH_CONTENT_ID, "imgTemp.gif"
Code:
Dim CID as variant
CID = "imgTemp.gif"
olkPA.SetProperty PR_ATTACH_CONTENT_ID, CID
Et vérifier si ça marche toujours.
 

Dudu2

XLDnaute Barbatruc
Rien à faire, j'y arrive pas, j'y arrive pas, j'y arrive pas ! Fait suer.
VB:
With ObjOutlookMail
    .Attachments.Add ImageFileName
    ContentID = Mid(ImageFileName, InStrRev(OD.EmbbededImages(i), "\") + 1)
    With .Attachments(.Attachments.Count).PropertyAccessor
        .SetProperty PR_ATTACH_CONTENT_ID, ContentID '!!! ContentID HAS TO BE VARIANT !!!
        .SetProperty PR_ATTACHMENT_HIDDEN, True
    End With
End With
Contenu = Replace(Contenu, "<EmbbededImage1>", "<IMG src=cid:'" & ContentID & "'" & ">")
 
Dernière édition:

Dudu2

XLDnaute Barbatruc
AAAAAAAAAAAACCCCCCCCCCCCCCCHHHHHHHHHHHHHHHHHH !!
1628167762311.gif

J'ai mis la cote après src=cid: et il faut soit la mettre après src= soit pas la mettre du tout !
2 heures pour cette stupidité !
Merci pour ton exemple, ça m'a éclairé à force de regarder les détails.
 

Dudu2

XLDnaute Barbatruc
J'ai pris une approche simplificatrice pour l'envoi d'email avec Outlook en définissant une structure d'interface qu'il suffit de remplir pour s'éviter toute la mise en place dans les objets de mail Outlook.
VB:
'--------------------------------------------------------------------------------
'Interface à valoriser pour envoyer un mail Outlook via la fonction MailOutlook()
'--------------------------------------------------------------------------------
Public Type OUTLOOK_DATA
    SendUsingAccount As Variant         'Nom du compte à utiliser (ex.:moncompte@domaine.com)
                                        'Numéro de séquence (1-n) du compte OutLook à utiliser.
                                        'Si Numéro = 0, la liste des comptes est proposée pour un choix
    ReadReceiptRequested As Boolean     'True ou False
    Importance As Integer               'Low = 0, Normal = 1, High = 2
    To As String                        'Adresses mail des destinataires séparées par ";"
    CC As String                        'Adresses mail des destinataires en copie séparées par ";"
    Bcc As String                       'Adresses mail des destinataires en copie masquée séparées par ";"
    Subject As String                   'Objet du mail
    BodyFormat As Integer               'olFormatPlain = 1, olFormatHTML = 2, olFormatRichText = 3, olFormatUnspecified = 0
    Body As String                      'Message
    EmbbededImages() As String          'Tableau des chemin complets des Images intégrés dans le corps du mail
                                        '<EmbbededImage1>, <EmbbededImage2>, etc... pour y faire référénce dans le .Body
    Attachments() As String             'Tableau des chemins complets des attachements
    Action As String                    '"Display", "PrintOut", "Save", "Send"
End Type
Ensuite il suffit d'appeler la fonction MailOutlook() avec en argument cette interface.
Voir dans le fichier la fonction TestMailOutLook().

Edit: Et pour être complet j'ajoute le même type de fichier pour l'envoi en CDO.
Voir dans le fichier la fonction TestMailCDO().
 

Pièces jointes

  • Envoi de Mail avec Outlook.xlsm
    31.8 KB · Affichages: 39
  • Envoi de Mail avec CDO.xlsm
    30.2 KB · Affichages: 24
Dernière édition:

patricktoulon

XLDnaute Barbatruc
bon il y a des choses a dire

1° tu ne dissocie pas les attachement (fichier) des attachements image embed
ta corespodance array (embedimage /attachements )n'est pas une bonne idée
tu veux envoyer une piece jointe tu fait comment !!!??????

2° ton msgbox il vient quand même même si action="DISPLAY"
 

patricktoulon

XLDnaute Barbatruc
bon en fait il sont bien dissocié c'est toi qui induit en erreur en mettant le meme chemin embed1 et atach1 etc....

VB:
Sub TestMailOutLook()
    Dim OutLookInterface As OUTLOOK_DATA

    With OutLookInterface
        .SendUsingAccount = 0           '0 pour choisir le compte OutLook à utiliser
        .ReadReceiptRequested = False   'Pas d'Accusé de Réception demandé
        .Importance = 1                 'Normale
        .To = "destinataireTo1@domaine.com;destinataireTo2@domaine.com"
        .CC = "destinataireCc1@domaine.com;destinataireCc2@domaine.com"
        .Bcc = "destinataireBcc1@domaine.com;destinataireBcc2@domaine.com"
        .Subject = "Sujet du mail"
        .Body = "Bonjour<BR>Première image<BR><EmbbededImage1><BR>Deuxième image<BR><EmbbededImage2 width='200'><BR>Fin du mail"
        .BodyFormat = 2                 'Pour HTML
        ReDim .EmbbededImages(1 To 2)
         'ReDim .Attachments(1 To 2)
        
        
        '.Attachments(1) = "C:\Users\Public\Pictures\Sample Pictures\aaaa.jpg"
        '.Attachments(2) = "C:\Users\Public\Pictures\Sample Pictures\quelqu_un.jpg"
        .EmbbededImages(1) = "C:\Users\Public\Pictures\Sample Pictures\aaaa.jpg"
        .EmbbededImages(2) = "C:\Users\Public\Pictures\Sample Pictures\quelqu_un.jpg"
       .Action = "display"
    End With

    If OutLookInterface.Action <> "display" And MailOutlook(OutLookInterface) Then MsgBox "Envoi réussi."
End Sub

bon ...faire une passerelle (clone) avec une variable type ma fois si ça permet de mieux appréhender
ma fois pourquoi pas

tu pourrais ajouter la signature par exemple
 

Dudu2

XLDnaute Barbatruc
Dans le Post #7 j'ai mis à jour le fichier pour le message dans l'exemple d'utilisation, détail que tu as noté.
VB:
If MailOutlook(OutLookInterface) Then MsgBox Application.Proper(.Action) & " mail réussi."
Et aussi ajouté le cas marginal du format olFormatRichText = 3 qui doit plutôt aller dans .RTFBody.

Par contre je ne vois pas de propriété "Signature" dans les propriétés du MailItem
 

patricktoulon

XLDnaute Barbatruc
re
je vois pas trop l'utilité de cette version du msgbox
si tu met display tu le vois tout de suite , si l'ordre de ton interface c'est bien déroulé non ?

 

Dudu2

XLDnaute Barbatruc
je vois pas trop l'utilité de cette version du msgbox
si tu met display tu le vois tout de suite , si l'ordre de ton interface c'est bien déroulé non ?
Il n'y a pas que Display et Send. Il y a aussi d'autres actions Printout et Save.
C'est un MsgBox qui couvre tous les cas, dans la fonction d'exemple de mise en oeuvre, ça n'a guère d'importance.

Avec CDO j'ai aussi un vieux bout de code avec les attachments mais je n'ai pas les embedded images.
Mais CDO me créé des problèmes particuliers quand il plante, je reste bloqué sur Excel.
Dans la mesure du possible je préfère utiliser Outlook.

tu peux aussi le faire simplement toi même en html aussi ( tout es permis )
Oui bien sûr, mais en l'occurrence, si l'utilisateur a besoin d'une signature, il peut se la mettre en "Embbeded image" avec l'interface assez simplement. Je vais pas lui laver ses chaussettes non plus 🤣.
 
Dernière édition:

Discussions similaires

Statistiques des forums

Discussions
312 206
Messages
2 086 220
Membres
103 158
dernier inscrit
laufin