Solved

The linked image cannot be displayed.

Posted on 2016-09-01
11
76 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
Simplifying Server Workload Migrations

This use case outlines the migration challenges that organizations face and how the Acronis AnyData Engine supports physical-to-physical (P2P), physical-to-virtual (P2V), virtual to physical (V2P), and cross-virtual (V2V) migration scenarios to address these challenges.

 

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

The Eight Noble Truths of Backup and Recovery

How can IT departments tackle the challenges of a Big Data world? This white paper provides a roadmap to success and helps companies ensure that all their data is safe and secure, no matter if it resides on-premise with physical or virtual machines or in the cloud.

Question has a verified solution.

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

Suggested Solutions

This article descibes how to create a connection between Excel and SAP and how to move data from Excel to SAP or the other way around.
Some code to ensure data integrity when using macros within Excel. Also included code that helps secure your data within an Excel workbook.
This Micro Tutorial will demonstrate the scrolling table in Microsoft Excel using the INDEX function.
Many functions in Excel can make decisions. The most simple of these is the IF function: it returns a value depending on whether a condition you describe is true or false. Once you get the hang of using the IF function, you will find it easier to us…

832 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