5

I want to add signatures with images. Images here refer to company logo and social networking icons.

This code is written in Excel VBA and the goal is to copy paste the range as a picture in Outlook email.

Dim Rng                     As Range
Dim outlookApp              As Object
Dim outMail                 As Object

Dim wordDoc                 As Word.Document
Dim LastRow                 As Long
Dim CcAddress               As String
Dim ToAddress               As String
Dim i                       As Long
Dim EndRow                  As String

Dim Signature               As String

'// Added Microsoft word reference

Sub Excel_Image_Paste_Testing()

    On Error GoTo Err_Desc

    '\\ Define Endrow
    EndRow = Range("A65000").End(xlUp).Row

    '\\ Range for copy paste as image
    Set Rng = Range("A22:G" & EndRow)
    Rng.Copy

    '\\ Open a new mail item
    Set outlookApp = CreateObject("Outlook.Application")
    Set outMail = outlookApp.CreateItem(0)

    '\\ Display message to capture signature
    outMail.Display

    '\\ This doesnt store images because its defined as string
    'Problem lies here
    Signature = outMail.htmlBody

    '\\ Get its Word editor
    Set wordDoc = outMail.GetInspector.WordEditor
    outMail.Display

    '\\ To paste as picture
    wordDoc.Range.PasteAndFormat wdChartPicture

    '\\ TO and CC Address
    CcAddress = "xyz@gmail.com"
    ToAddress = "abc@gmail.com"

    '\\ Format email
    With outMail
        .htmlBody = .htmlBody & Signature
        .Display
        .To = ToAddress
        .CC = CcAddress
        .BCC = ""
        .Subject = "Email Subject here"
        .readreceiptrequested = True
    End With

    '\\ Reset selections
    Application.CutCopyMode = False
    Range("B1").Select

    Exit Sub
Err_Desc:
    MsgBox Err.Description

End Sub

This file is to be distributed to many people. I wouldn’t know the default .htm signature name.

(“AppData\Roaming\Microsoft\Signatures”)

People may also have many signatures but my goal is to capture their default signature.

Error signature picture after running the code
enter image description here

My signature should be as shown below.
My signature should have been this

Community
  • 1
  • 1
vds1
  • 75
  • 1
  • 10

1 Answers1

7

In this code we will let the user select the .Htm file from AppData\Roaming\Microsoft\Signatures

The problem is that we cannot directly use the html body of this file because the images are stored in a different folder named as filename_files as shown below.

enter image description here

Also the paths mentioned in the htmlbody are incomplete. See the below images

enter image description here

Here is a quick function that I wrote which will fix the paths in the html body

'~~> Function to fix image paths in Signature .htm Files
Function FixHtmlBody(r As Variant) As String
    Dim FullPath As String, filename As String
    Dim FilenameWithoutExtn As String
    Dim foldername As String
    Dim MyData As String

    '~~> Read the html file as text file in a string variable
    Open r For Binary As #1
    MyData = Space$(LOF(1))
    Get #1, , MyData
    Close #1

    '~~> Get File Name from path
    filename = GetFilenameFromPath(r)
    '~~> Get File Name without extension
    FilenameWithoutExtn = Left(filename, (InStrRev(filename, ".", -1, vbTextCompare) - 1))
    '~~> Get the foldername where the images are stored
    foldername = FilenameWithoutExtn & "_files"
    '~~> Full Path of Folder
    FullPath = Left(r, InStrRev(r, "\")) & foldername

    '~~> Replace incomplete path with full Path
    FixHtmlBody = Replace(MyData, foldername, FullPath)
End Function

Here is the complete procedure. I have commented the code. Let me know if you still have any issues.

Sub Sample()
    Dim oOutApp As Object, oOutMail As Object
    Dim strbody As String, FixedHtmlBody As String
    Dim Ret

    '~~> Ask user to select the htm file
    Ret = Application.GetOpenFilename("Html Files (*.htm), *.htm")

    If Ret = False Then Exit Sub

    '~~> Use the function to fix image paths in the htm file
    FixedHtmlBody = FixHtmlBody(Ret)

    Set oOutApp = CreateObject("Outlook.Application")
    Set oOutMail = oOutApp.CreateItem(0)

    strbody = "<H3><B>Dear Blah Blah</B></H3>" & _
              "More Blah Blah<br>" & _
              "<br><br><B>Thank you</B>" & FixedHtmlBody

    On Error Resume Next
    With oOutMail
        .To = "Email@email.com" '<~~ Change as applicable
        .CC = ""
        .BCC = ""
        .Subject = "Example on how to insert image in signature"
        .HTMLBody = .HTMLBody & "<br>" & strbody
        .Display
    End With
    On Error GoTo 0

    Set oOutMail = Nothing
    Set oOutApp = Nothing
End Sub

'~~> Function to fix image paths in Signature .htm Files
Function FixHtmlBody(r As Variant) As String
    Dim FullPath As String, filename As String
    Dim FilenameWithoutExtn As String
    Dim foldername As String
    Dim MyData As String

    '~~> Read the html file as text file in a string variable
    Open r For Binary As #1
    MyData = Space$(LOF(1))
    Get #1, , MyData
    Close #1

    '~~> Get File Name from path
    filename = GetFilenameFromPath(r)
    '~~> Get File Name without extension
    FilenameWithoutExtn = Left(filename, (InStrRev(filename, ".", -1, vbTextCompare) - 1))
    '~~> Get the foldername where the images are stored
    foldername = FilenameWithoutExtn & "_files"

    '~~> Full Path of Folder
    FullPath = Left(r, InStrRev(r, "\")) & foldername

    '~~> To cater for spaces in signature file name
    FullPath = Replace(FullPath, " ", "%20")

    '~~> Replace incomplete path with full Path
    FixHtmlBody = Replace(MyData, foldername, FullPath)
End Function

'~~> Gets File Name from path
Public Function GetFilenameFromPath(ByVal strPath As String) As String
    If Right$(strPath, 1) <> "\" And Len(strPath) > 0 Then _
    GetFilenameFromPath = GetFilenameFromPath(Left$(strPath, Len(strPath) - 1)) + Right$(strPath, 1)
End Function

In Action

enter image description here

Siddharth Rout
  • 147,039
  • 17
  • 206
  • 250
  • Thank you Siddharth for taking time and posting it for me. My default signature has its own images within signature. Defining specific image path would be difficult since the file would be used by various stakeholders having different images of the company – vds1 Sep 23 '16 at 07:53
  • You can always save the range as an image to user's local temp directory and then use that path? – Siddharth Rout Sep 23 '16 at 07:56
  • See the updated post. You may have to refresh the page to see it. – Siddharth Rout Sep 23 '16 at 08:10
  • Thank you again for your most valuable time. I have tried this feature where range was exported as image using chart object. But the problem is the clarity of the pic in my system is kinda blur. If i do manually copy paste range as image in outlook mail the picture looks absolutely great. – vds1 Sep 23 '16 at 09:00
  • Hello Sid, i have added the actual signature how it looks like vs the one which is having no image. I hope it makes sense. – vds1 Sep 23 '16 at 09:19
  • `So I wouldn’t know default .htm signature name in` Do you think, you could prompt them via code to select the .htm file? – Siddharth Rout Sep 23 '16 at 09:29
  • Thats a very good thought. Ok so i did some research on web and found a function like GetBoiler (http://stackoverflow.com/questions/8994116/how-to-add-default-signature-in-outlook) . Using this if i can return full path of htm file of default signature how do i implement in the existing code. – vds1 Sep 23 '16 at 09:42
  • Thanks Sid. I did check this link earlier, the problem here is that the htm is assigned to a string variable and GetBoiler function is called. Moment its assigned to string (or any data type) the images goes off and the errors continues to occur. – vds1 Sep 23 '16 at 09:58
  • Can you check one thing for me? does `AppData\Roaming\Microsoft\Signatures` folder contain a ".Rtf" file besides the ".Htm" with the same name? – Siddharth Rout Sep 23 '16 at 10:32
  • Thanks Sid for helping me with your valuable time. Yes it does contain Rich text format file with the same name. – vds1 Sep 23 '16 at 10:38
  • In that case we have two options 1. We can parse the Rtf 2. we can parse the htmlbody of the htm file and fix the file paths in that so that the images are shown properly. I am writing some code for the 2 option. Will keep you updated ;) – Siddharth Rout Sep 23 '16 at 10:39
  • Many thanks Sid :) I will wait for your update and meanwhile i will look around and see if i could find something. I dont see many resource in the web that deals with my issue. Outlook should have had a function like add default signature. – vds1 Sep 23 '16 at 10:43
  • Refresh the page. I have updated my post with a new answer. – Siddharth Rout Sep 23 '16 at 11:03
  • 2
    This is Just perfect solution you have given me. Many thanks Sid for your time and effort on this case. I am very impressed with your knowledge and patience. Have a wonderful day! – vds1 Sep 23 '16 at 11:10
  • Hello Sid, This code works absolutely great but there one small problem. If the htm file name is "MySig" it works but if the signature name is "My Sig" then the image problem comes back. Is there any simple work around for this ? Seems like space issue – vds1 Sep 23 '16 at 11:45
  • Oh yes it is a minor change to the code ;) One moment – Siddharth Rout Sep 23 '16 at 11:47
  • Hello Sid, I replaced the space by %20 and it worked fine. something lik this foldername = Replace(foldername, " ", "%20") – vds1 Sep 23 '16 at 12:33
  • Strange! I tried the same thing and it failed and hence I was taking so much time to reply :D – Siddharth Rout Sep 23 '16 at 12:37
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/124038/discussion-between-siddharth-rout-and-vds1). – Siddharth Rout Sep 23 '16 at 12:40
  • It failed once for me because i added it after foldername = FilenameWithoutExtn & "_files" later i saw you have concatenated with FullPath, so i added the replace function after FullPath Variable and it worked fine. – vds1 Sep 23 '16 at 12:40
  • Sorry, my company has blocked the chat link :\ When i login from home i will be able to access it – vds1 Sep 23 '16 at 13:01
  • Thanks ok :) Just post the final code that you are using in the chat. I just want to check it. – Siddharth Rout Sep 23 '16 at 13:02
  • '\\ Get the foldername where the images are stored foldername = FilenameWithoutExtn & "_files" '\\ Full Path of Folder FullPath = Left(r, InStrRev(r, "\")) & foldername '\\ Replace space by %20 foldername = Replace(foldername, " ", "%20") '\\ Replace incomplete path with full Path FixHtmlBody = Replace(MyData, foldername, FullPath) – vds1 Sep 23 '16 at 13:06
  • Strange I did the same. Maybe something wrong with my signature file then :D – Siddharth Rout Sep 23 '16 at 13:07
  • @SiddharthRout with some delay, but thanks, this is just great. is there any way to read the default signature name from the Outlook account ? is there such a property ? – Shai Rado Mar 07 '19 at 22:19
  • @ShaiRado: To get the default signature, use `.Display` directly before setting the `.HTMLBody` or `.Body`. You will see the signature there. Provided you have set the signature for new emails from `File|options|Mail|Signatures|Choose Default Signature` – Siddharth Rout Mar 08 '19 at 03:06