Solved

The linked image cannot be displayed.

Posted on 2016-09-01
11
83 Views
Last Modified: 2016-09-13
I am using the following function to generate an email. On some of those emails I need to include an image in the body not as an attachment. When I send it the message displays correctly but the recipient's email has the message "The linked image cannot be displayed. The file may have been removed, renamed, or deleted. Verify that the link points to the correct location." What am I doing wrong?

Function OutlookEmail(Message As String _
                , EmailAddress As String _
                , Subject As String _
                , EditBeforeSending As Boolean _
                , Optional AttachmentPath As Variant _
                , Optional CC As String _
                , Optional BCC As String _
                , Optional EmbedImage As Boolean _
                )

    Dim objOutlook As Object
    Dim sSignature As String
    Dim AttachmentName As String
    Dim i As Integer
   
    On Error GoTo OutlookEmail_Error

    Set objOutlook = GetObject(, "Outlook.Application") ' Determine if Outlook is open
   
        Dim objMailItem As Object
        Const olMailItem As Integer = 0
        Set objMailItem = objOutlook.CreateItem(olMailItem)
               
        With objMailItem
        .display
        End With
       
        sSignature = objMailItem.HTMLBody
       
        With objMailItem
            .To = EmailAddress
            If Not IsMissing(CC) Then
                .CC = CC
            End If
            If Not IsMissing(BCC) Then
                .BCC = BCC
            End If
            .Subject = Subject
            '.Body = strBody
           
            ' Add attachments to the message.
           
            .HTMLBody = "<font face=Arial>" & Message & "</font>"
   
            If Not IsMissing(AttachmentPath) Then
                If IsArray(AttachmentPath) Then
                    For i = LBound(AttachmentPath) To UBound(AttachmentPath)
                        If AttachmentPath(i) <> "" And AttachmentPath(i) <> "False" Then
                            .Attachments.Add AttachmentPath(i)
                            If Right(AttachmentPath(i), 4) = ".jpg" _
                                Or Right(AttachmentPath(i), 4) = ".png" _
                                And EmbedImage = True Then
                                    AttachmentName = Mid(AttachmentPath(i), 1, InStrRev(AttachmentPath(i), "\") - 1)
                                    .HTMLBody = .HTMLBody & HTMLNEWLINE & HTMLNEWLINE & "<img src='cid:" & Mid(AttachmentPath(i) _
                                        , InStrRev(AttachmentPath(i), "\") + 1) _
                                        & "' align=baseline border=0>"
                            End If
                        End If
                    Next i
                Else
                    If AttachmentPath <> "" And AttachmentPath <> "False" Then
                        .Attachments.Add AttachmentPath
                        If Right(AttachmentPath, 4) = ".jpg" _
                                Or Right(AttachmentPath, 4) = ".png" _
                                And EmbedImage = True Then
                                    AttachmentName = Mid(AttachmentPath, 1, InStrRev(AttachmentPath, "\") - 1)
                                    .HTMLBody = .HTMLBody & HTMLNEWLINE & HTMLNEWLINE & "<img src='cid:" & Mid(AttachmentPath _
                                        , InStrRev(AttachmentPath, "\") + 1) _
                                        & "' align=baseline border=0 >"
                            End If
                    End If
                End If
            End If
           
            .HTMLBody = .HTMLBody & "</br></br>" & sSignature
           
            If EditBeforeSending = True Then
                .display (EditBeforeSending) ' true makes outlook modal
            Else
                .send
            End If
       End With
OutlookEmail_Exit:
        Set objOutlook = Nothing
        Set objMailItem = Nothing

    End If
   
   On Error GoTo 0
   Exit Function

OutlookEmail_Error:

    MsgBox "Error " & Err.Number & " (" & Err.Description & ") in procedure OutlookEmail of Module ModEmailFunctions"
    Resume OutlookEmail_Exit
    Resume
End Function
0
Comment
Question by:Rob4077
  • 8
  • 3
11 Comments
 
LVL 47

Accepted Solution

by:
Wayne Taylor (webtubbs) earned 500 total points
ID: 41781019
You can't just use the image path in the HTML as the recipient will not be able access that location, thereby not seeing it. What you need to do is attach it to the message, but make it hidden. You can then reference the file name in your HTML.

Try this macro instead, noting the differences in lines 49, 54, 61 & 66...

Function OutlookEmail(Message As String _
                 , EmailAddress As String _
                 , Subject As String _
                 , EditBeforeSending As Boolean _
                 , Optional AttachmentPath As Variant _
                 , Optional CC As String _
                 , Optional BCC As String _
                 , Optional EmbedImage As Boolean _
                 )

     Dim objOutlook As Object
     Dim sSignature As String
     Dim AttachmentName As String
     Dim i As Integer
     
     On Error GoTo OutlookEmail_Error

     Set objOutlook = GetObject(, "Outlook.Application") ' Determine if Outlook is open
     
         Dim objMailItem As Object
         Const olMailItem As Integer = 0
         Set objMailItem = objOutlook.CreateItem(olMailItem)
                 
         With objMailItem
         .display
         End With
         
         sSignature = objMailItem.HTMLBody
         
         With objMailItem
             .To = EmailAddress
             If Not IsMissing(CC) Then
                 .CC = CC
             End If
             If Not IsMissing(BCC) Then
                 .BCC = BCC
             End If
             .Subject = Subject
             '.Body = strBody
             
             ' Add attachments to the message.
             
             .HTMLBody = "<font face=Arial>" & Message & "</font>"
     
             If Not IsMissing(AttachmentPath) Then
                 If IsArray(AttachmentPath) Then
                     For i = LBound(AttachmentPath) To UBound(AttachmentPath)
                         If AttachmentPath(i) <> "" And AttachmentPath(i) <> "False" Then
                             .Attachments.Add AttachmentPath(i), 1, 0
                             If Right(AttachmentPath(i), 4) = ".jpg" _
                                 Or Right(AttachmentPath(i), 4) = ".png" _
                                 And EmbedImage = True Then
                                     AttachmentName = Mid(AttachmentPath(i), 1, InStrRev(AttachmentPath(i), "\") - 1)
                                     .HTMLBody = .HTMLBody & HTMLNEWLINE & HTMLNEWLINE & "<img src='cid:" & AttachmentName _
                                         & "' align=baseline border=0>"
                             End If
                         End If
                     Next i
                 Else
                     If AttachmentPath <> "" And AttachmentPath <> "False" Then
                         .Attachments.Add AttachmentPath, 1, 0
                         If Right(AttachmentPath, 4) = ".jpg" _
                                 Or Right(AttachmentPath, 4) = ".png" _
                                 And EmbedImage = True Then
                                     AttachmentName = Mid(AttachmentPath, 1, InStrRev(AttachmentPath, "\") - 1)
                                     .HTMLBody = .HTMLBody & HTMLNEWLINE & HTMLNEWLINE & "<img src='cid:" & AttachmentName _
                                         & "' align=baseline border=0 >"
                             End If
                     End If
                 End If
             End If
             
             .HTMLBody = .HTMLBody & "</br></br>" & sSignature
             
             If EditBeforeSending = True Then
                 .display (EditBeforeSending) ' true makes outlook modal
             Else
                 .send
             End If
        End With
OutlookEmail_Exit:
         Set objOutlook = Nothing
         Set objMailItem = Nothing

     End If
     
    On Error GoTo 0
    Exit Function

OutlookEmail_Error:

     MsgBox "Error " & Err.Number & " (" & Err.Description & ") in procedure OutlookEmail of Module ModEmailFunctions"
     Resume OutlookEmail_Exit
     Resume
 End Function

Open in new window

0
 

Author Comment

by:Rob4077
ID: 41781041
Awesome. Thanks so much. I will have to wait till next week to try it at the office but I am confident your amendment will work. I will close the question now and award the points. If i have any more questions I will either add to this one or raise a new one.

Thanks again!
0
 

Author Closing Comment

by:Rob4077
ID: 41781043
Thanks Wayne
0
Use Case: Protecting a Hybrid Cloud Infrastructure

Microsoft Azure is rapidly becoming the norm in dynamic IT environments. This document describes the challenges that organizations face when protecting data in a hybrid cloud IT environment and presents a use case to demonstrate how Acronis Backup protects all data.

 

Author Comment

by:Rob4077
ID: 41784249
Hi Wayne, I can see the difference in the lines you highlighted. I am not sure what the implication is of the additional parameters ( ",1 ,0") forming part of the .Attachments.Add AttachmentPath(i), 1, 0

I can understand why you told me to change the reference to just the attachment name.

Not surprisingly I got it to work, so thanks again!!!!
0
 

Author Comment

by:Rob4077
ID: 41784259
Oops, spoke too soon. It looks like it works when I send it but the message now neither has an attachment nor displays it. The original code had the attachment but did not display it. Any ideas?
0
 

Author Comment

by:Rob4077
ID: 41784270
Not quite sure what to make of this. On my Outlook the message has the image removed and no attachment, whereas on my phone the attachment is there but the image shows only the name of the attachment, yet the image in my signature footer shows perfectly.
0
 
LVL 47

Expert Comment

by:Wayne Taylor (webtubbs)
ID: 41785311
Sorry, I didn't actually check it when I first posted, but the AttachmentName variable is not being set properly. It is actually being set to the folder path of the attachment, not it's name.

With that in mind, change every line that sets the AttachmentName variable to this...

    AttachmentName = Mid(AttachmentPath, InStrRev(AttachmentPath, "\") + 1, 999)

Open in new window

0
 

Author Comment

by:Rob4077
ID: 41785490
Hi Wayne, thanks for that but I had already discovered and fixed that in testing your proposed changes - should have said -sorry.

When I look at the sent emails the result is inconsistent depending on the browser but the most glaring issue is that the image doesn't appear yet the image that is picked up in the earlier step sSignature = objMailItem.HTMLBody does appear. Any ideas?

I note that you're in Australia, like me. Zeehan Tasi I assume - beautiful, albeit cold and wet, part of the country!!!
0
 
LVL 47

Expert Comment

by:Wayne Taylor (webtubbs)
ID: 41785500
Can you view source and see what difference there is between the images? In my testing here I was able to successfully create the email with the hidden attachment, but the image visible. Oddly though when viewed in OWA the image appeared as an attachment, not embedded. Everything I've read suggests what I've done is correct...

http://www.outlookcode.com/d/code/htmlimg.htm
https://social.msdn.microsoft.com/Forums/office/en-US/55f49b6d-210b-4e4f-831d-1b7d8061a0ef/how-to-embed-picture-in-htmlbody-in-outlook?forum=outlookdev
http://www.slipstick.com/developer/code-samples/embed-images-messages-macro/

This is the test code I was using...

Sub test()

    Dim msg As MailItem, AttachmentName As String, sSignature As String
    Const AttachmentPath As String = "C:\Users\username\Pictures\photo.jpg"
    
    AttachmentName = Mid(AttachmentPath, InStrRev(AttachmentPath, "\") + 1, 999)
    Set msg = Application.CreateItem(olMailItem)
    
    With msg
        .Recipients.Add ("email@address.com")
        .Subject = "TEST MESSAGE"
        .Attachments.Add AttachmentPath ', 1, 0
        .Display
        sSignature = .HTMLBody
        .HTMLBody = "<font face=Arial>TEST MESSAGE</font>"
        .HTMLBody = .HTMLBody & "<img src='cid:" & AttachmentName & "' align=baseline border=0>"
        .HTMLBody = .HTMLBody & sSignature
    End With
    
End Sub

Open in new window

0
 

Author Comment

by:Rob4077
ID: 41785547
Hi Wayne, thank you so much for your help.

Looks like you're having the same outcome as I am. In some instances/places it's working, in others it'w  partly working and in other instances, not at all. I think it's fair to say you have answered this question and deserve the points, however it has given rise to another question which I may raise over the next few days as I get time.

Thanks again for your kind assistance.
0
 

Author Comment

by:Rob4077
ID: 41795575
In case you're still linked in, I tried replacing
"<img src='cid:" & AttachmentName & "' align=baseline border=0>"
with
<IMG src=" & AttachmentName & "" & " align=baseline border=0>"
where AttachmentName is the full name and location of the image and it works a treat no matter where I send it. The attachment is there and it is embedded in the image
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Some code to ensure data integrity when using macros within Excel. Also included code that helps secure your data within an Excel workbook.
Excel can be a tricky bit of software to get your head around. Whilst you’ll be able to eventually get to grips with the basic understanding of how to get by, there are a few Excel tips that not everybody will even know about let alone know how to d…
This Micro Tutorial demonstrates how to create Excel charts: column, area, line, bar, and scatter charts. Formatting tips are provided as well.
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…

789 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question