Using FileDialog to attach a file to an email - excel

I want to eliminate human error when it comes to selecting a file to send in an attachment in an email. Basically eliminating this code Filename = Application.InputBox("Enter File Name:", "", "File Name")'Type in File Name And replace it using FileDialog which has come to my attention as a good way of accomplishing this. I am very confused on how to use it correctly. Every time I have tried, I am able to use the application and see the file but I don't understand how it gets attached. My email coding is below.
Sub Mail_workbook_Test()
Dim OutApp As Object
Dim OutMail As Object
Dim Date1 As Date
Dim Recipient As Variant
Date1 = Format(Now, "yyyy-mm-dd")
'Date and format
UserName = Application.InputBox("Enter your name:", "", "FirstLast")
Filename = Application.InputBox("Enter File Name:", "", "File Name")
'Type in File Name
List = Application.InputBox("Enter Email List Name:", "", "ListName")
'Type in Email List
If List = "gold" Then
List = "example#mail.com; example1#mail.com; example2#mail.com"
ElseIf List = "silver" Then
List = "example#mail.com; example#mail.com"
Else
MsgBox ("Sorry, your list selection was not recognised.")
Exit Sub
End If
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
With OutMail
For Each Recipient In Split(List, ";")
.Recipients.Add Trim(Recipient)
Next
.CC = ""
.BCC = ""
.Subject = "" + Filename + "" & " " & Date1
.Body = "Hi Everyone," & Chr(10) & Chr(10) & "Please let me know if you get this!" & Chr(10) & Chr(10) & "Thanks!"""
.Attachments.Add ("C:\Users\" + UserName + "\Desktop\" + Filename + ".xlsx")
.Send '.Display
End With
Set OutMail = Nothing
Set OutApp = Nothing
End Sub
How do I get Filename = to equal the file I pick with the code below and properly attach into an email? Any advice on my coding would be great too, thank you!
Set fd = Application.FileDialog(msoFileDialogFilePicker)
With fd
.AllowMultiSelect = False
End with

Replace
Filename = Application.InputBox("Enter File Name:", "", "File Name")
with:
With Application.FileDialog(msoFileDialogOpen)
.AllowMultiSelect = False
.Show
Filename = .SelectedItems(1)
End With

Here is an excerpt from a similar subroutine of mine, hope you'll find it helpful. Place this somewhere between creating MailItem object and sending the message:
'Ask which files to open (using FileDialog)
Dim fdInputFile As FileDialog
Set fdInputFile = Application.FileDialog(msoFileDialogOpen)
With fdInputFile
.Filters.Clear
.AllowMultiSelect = True
If .Show = False Then Exit Function 'you might want to handle "Cancel" button differently
End With
'Attach all files
Dim sInputFile As Variant
For Each sInputFile In fdInputFile.SelectedItems
OutMail.Attachments.Add sInputFile, 1
Next sInputFile
PS: I think it's easier to reuse the code above when it's separated from user input, so I use a separate function for creating e-mails whereever I need to. Just feed all the input as the parameters and call .Send method when you're ready
Public Function CreateEmailMsg(cRecipients, _
Optional sSubject As String = "", _
Optional sBody As String = "", _
Optional cAttachments = Nothing) _
As Object
'
' Generate new e-mail message
'
' Parameters:
' cRecipients: String (or a Collection of Strings) containing
' e-mail addresses of recipients
' sSubject: String containing message subject line
' sBody: String containing message body (HTML or plain text)
' cAttachments: String (or a Collection of Strings) containing
' path(s) to attachments
'
' Returns MailItem object referring to the created message
' Most common methods for MailItem object are .Display and .Send
'
Dim appOL As Object
Set appOL = CreateObject("Outlook.Application")
Dim msgNew As Object
Set msgNew = appOL.CreateItem(0) 'olMailItem
Dim sItem
With msgNew
'Message body
.BodyFormat = 2 'olFormatHTML
.HTMLBody = sBody
'Recipients
If TypeName(cRecipients) = "String" Then
.Recipients.Add cRecipients
ElseIf Not cRecipients Is Nothing Then
For Each sItem In cRecipients
.Recipients.Add sItem
Next sItem
End If
'Subject
.Subject = sSubject
'Attachments
If TypeName(cAttachments) = "String" Then
.Attachments.Add cAttachments, 1
ElseIf Not cAttachments Is Nothing Then
For Each sItem In cAttachments
.Attachments.Add sItem, 1
Next sItem
End If
End With
Set CreateEmailMsg = msgNew
End Function

Related

VBA FilePicker no longer opening from ThisWork.Path

I have a workbook (located on our network) with a macro enabled so I can email exported PDF worksheets via Outlook every Friday. The exported worksheet PDF gets saved to the same location as the Workbook. Outlook then opens the FilePicker and lets me select the file that I want to attach to the email. For some reason the Filepicker is now not opening to ThisWork.path anymore; it opens to my default MyDocuments located on my native computer. The exported file still saves in the proper spot (located on the network) but the FilePicker just wont open to that location. Now, if I move this Workbook to my direct computer, the FilePicker works as it should. I have not changed anything in the VBA so I don't know why this is all the sudden not working. It worked just last week. Below is the code I believe to be relevant to the issue.
'Creates workpath string
Dim mypath As String, fname As String
mypath = ThisWorkbook.Path
fname = CreateObject("Scripting.FileSystemObject").GetBaseName(ThisWorkbook.Name)
'********************************************************
'Saves PDF with Template Text and Date based on Order Date
Sheets(1).ExportAsFixedFormat 0, mypath & "\" & "TEXT Order Sheet " & Format(Range("D7").Value, "mm-dd-yy")
ActiveSheet.Name = Format(Range("D7").Value, "mm-dd-yy")
'********************************************************
Dim xStrFile As String
Dim xFilePath As String
Dim xFileDlg As FileDialog
Dim xFileDlgItem As Variant
Dim xOutApp As Outlook.Application
Dim xMailOut As Outlook.MailItem
Application.ScreenUpdating = False
Set xOutApp = CreateObject("Outlook.Application")
Set xMailOut = xOutApp.CreateItem(olMailItem)
Set xFileDlg = Application.FileDialog(msoFileDialogFilePicker)
xFileDlg.Filters.Clear
xFileDlg.Filters.Add "pdf files", "*.pdf"
xFileDlg.AllowMultiSelect = True
xFileDlg.InitialFileName = ThisWorkbook.Path
If xFileDlg.Show = -1 Then
'********************************************************
With xMailOut
.Display
.To = "fake#email.com"
.Subject = "TEXT" & Range("D7").Value
.HTMLBody = "<p style='font-family:calibri;font-size:12.0pt'>" & "Here is our TEXT order for the week of " & Range("D7").Value & "." & " Please respond to this email to confirm that you have received the order." & .HTMLBody
For Each xFileDlgItem In xFileDlg.SelectedItems
.Attachments.Add xFileDlgItem
Next xFileDlgItem
.Display
End With
End If
Set xMailOut = Nothing
Set xOutApp = Nothing
Application.ScreenUpdating = True
'********************************************************

Excel VBA attach multiple PDFs to an email - my do loop skips first PDF for second and subsequent emails generated?

I have attempted to write a macro that scans through a folder to pick relevant PDFs belonging to a person (such as AAA) and attach them to an email to be sent to AAA, then move on to pick up PDFs belonging to BBB and attach them to an email to be sent to BBB so on and so forth. My folder containing the PDFs looks like this:
AAA_111111.pdf
AAA_222222.pdf
AAA_333333.pdf
BBB_111111.pdf
BBB_222222.pdf
BBB_333333.pdf
CCC_777777.pdf
CCC_888888.pdf
CCC_999999.pdf
CCC_444444.pdf
The person is identified by the letters before the underscore (initials) and there is a list on another Excel tab that the initials are looked up against to return their email address.
I have written the code below and it works fairly well except it has an irritating flaw that I cannot solve. It will successfully generate the email for person AAA and attach all three files listed above for them. On the next pass of the main (outer) "do while" loop it comes to person BBB but the inner "do while mfe=" loop attaches the second and third file listed for them (BBB_222222.pdf & BBB_333333.pdf) and completely ignores BBB_111111.pdf (doesn't attach it) though it seems to be able to see it on. Ditto for the third loop, the "do while mfe=" loop will attach the latter three files for CCC to an email but won't attach CCC_777777.pdf?!
Sub emailreports()
Dim OutApp As Object
Dim OutMail As Object
Dim OMail As Object, signature, mfe, sto As String
Dim emaillastrow, x, a As Long
Dim fso As Scripting.FileSystemObject
Set fso = New FileSystemObject
Dim folder, strfile As String
Dim rundate As Date
Application.ScreenUpdating = False
Application.Calculation = xlManual
Application.AutoRecover.Enabled = False
folder = Worksheets("START").Range("A14")
strfile = Dir(folder)
rundate = Worksheets("TEMPLATE").Range("E7")
b = Worksheets("START").Range("H25")
Sheets("EMAIL").Select
emaillastrow = Worksheets("EMAIL").Range("A1000000").End(xlUp).Row
If Dir(folder, vbDirectory) = "" Then
MsgBox "PDF destination file path doesn't exist.", vbcritial, "Path error"
Exit Sub
End If
Do While Len(strfile) > 0
Filename = fso.GetBaseName(folder & strfile)
mfe = Left(Filename, InStr(Filename, "_") - 1)
For x = 2 To emaillastrow
If mfe = Worksheets("EMAIL").Range("A" & x) Then
sto = sto & ";" & Worksheets("EMAIL").Range("B" & x)
End If
Next
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
On Error Resume Next
With OutMail
.Display
End With
With OutMail
.To = LCase(sto)
.CC = ""
.BCC = ""
.Subject = "Test subject text"
Do While mfe = Left(Filename, InStr(Filename, "_") - 1)
.Attachments.Add (folder & Filename)
Filename = Dir
If Filename = "" Then
Exit Do
End If
Loop
.signature.Delete
.HTMLBody = "<font face=""arial"" style=""font-size:10pt;"">" & "Test email body text" & .HTMLBody
.Display
End With
On Error GoTo 0
With Application
.EnableEvents = True
.ScreenUpdating = True
End With
Set OutMail = Nothing
Set OutApp = Nothing
Set OutAccount = Nothing
Skip:
sto = ""
strfile = Filename
Loop
Application.StatusBar = False
Application.ScreenUpdating = True
Application.Calculation = xlAutomatic
Application.AutoRecover.Enabled = True
End Sub
I thought about trying to make it somehow at the end of generating the email to take a step back but being a Do loop this is not possible. My code seems to ignore the PDF that it stopped at as part of the previous email generation and when generating the next email starts from that PDF file but only picks up and attaches subsequent PDFs. Any help would be gratefully received as I've tried all sort of things but can't make it work. This is my first post to Stackoverflow so apologies if my question and/or format is not correct or appropriate.
You could use a dictionary object to group together the filenames by prefix with one pass of the directory and then iterate the dictionary keys to create the emails with corresponding attachments. For example (outlook methods untested)
Option Explicit
Sub emailreports()
Dim dict As Scripting.Dictionary, key
Set dict = New Scripting.Dictionary
Dim folder As String, strfile As String, mfe As String
Dim sTo As String, arPDF, arAddr, f
Dim ws As Worksheet, r As Long, emaillastrow As Long
folder = Worksheets("START").Range("A14")
strfile = Dir(folder & "*.pdf")
If strfile = "" Then
MsgBox "PDF destination file path doesn't exist.", vbCritical, "Path error " & folder
Exit Sub
Else
' group files by prefix
Do While strfile <> ""
mfe = Left(strfile, InStr(strfile, "_") - 1)
If dict.Exists(mfe) Then
dict(mfe) = dict(mfe) & vbTab & strfile
Else
dict.Add mfe, strfile
End If
strfile = Dir ' get next pdf
Loop
End If
Set ws = Worksheets("EMAIL")
emaillastrow = ws.Cells(Rows.Count, "A").End(xlUp).Row
' read email address lookup into array
arAddr = ws.Range("A2:B" & emaillastrow)
' prepare one email per key
Dim OutApp As Object, OutMail As Object, OMail As Object
'Set OutApp = CreateObject("Outlook.Application")
For Each key In dict.Keys
' build array of file names for one key
mfe = Trim(key)
arPDF = Split(dict(mfe), vbTab)
' get email addresses
sTo = ""
For r = 1 To UBound(arAddr)
If mfe = arAddr(r, 1) Then
sTo = sTo & arAddr(r, 2) & ";"
End If
Next
Debug.Print key, sTo
'Set OutMail = OutApp.CreateItem(0)
'With OutMail
'.To = LCase(sTo)
'.cc = ""
'.BCC = ""
'.Subject = "Test subject text"
' attach pdfs
For Each f In arPDF
'.Attachments.Add folder & f
Debug.Print , folder & f
Next
'.signature.Delete
'.HTMLBody = "<font face=""arial"" style=""font-size:10pt;"">" & "Test email body text" & .HTMLBody
'.Display
'End With
Next
'OutApp.quit
End Sub
On Error Resume Next seems to mask errors and hide skip reason. Try to use more specialized filename mask:
...
folder = Worksheets("START").Range("A14")
If Dir(folder, vbDirectory) = "" Then
MsgBox "PDF destination file path doesn't exist.", vbcritial, "Path error"
Exit Sub
End If
strfile = Dir(fso.BuildPath(folder, "*_*.pdf")
rundate = Worksheets("TEMPLATE").Range("E7")
b = Worksheets("START").Range("H25")
'Sheets("EMAIL").Select 'no need to select a sheet
emaillastrow = Worksheets("EMAIL").Range("A1000000").End(xlUp).Row
...

Attaching multiple PDFs from selected folder to email

I am trying to allow users to select the folder where they have kept multiple PDFs and extract them.
Unless I put the specific pathname, I am unable to get the macro to run correctly.
This works, if instead of referencing the function I reference the specific pathname:
StrPath = "C:\Users\Mark\OneDrive - Corporation\Desktop\Work file\RemA\Canada\"
My full code, which does not attach any PDFs:
Option Explicit
Private Function selectfolder()
'Defining the Variables
Dim user_name As String 'sequence of characters: alphabets, numbers, special characters
user_name = Environ("username") 'to pick up the username from work environment
'Prompt for folder creation
With Application.FileDialog(msoFileDialogFolderPicker) 'standard wording
.Title = "Select the folder to save"
.InitialFileName = "C:\Users\" & user_name & "\OneDrive - Corporation\Desktop\Work file" 'base directory to open
.AllowMultiSelect = False
If .Show <> -1 Then Exit Function 'if user does not press OK, end the function'
selectfolder = .SelectedItems(1)
End With
End Function
Sub sendremindermail()
'Defining the Variables
Dim outlookapp As Object
Dim outlookmailitem As Object
Dim myattachments As Object
Dim StrPath As String
Dim StrFile As String
Dim network, Fldr As String
'If user does not choose a folder
StrPath = selectfolder()
If StrPath = "" Then
Exit Sub
End If
Set outlookapp = CreateObject("outlook.application")
Set outlookmailitem = outlookapp.createitem(0)
Set myattachments = outlookmailitem.Attachments
'Creating the email and adding attachment
With outlookmailitem
'Title of the Email
.Subject = "Test Run"
'To be sent to recipients
.To = "ABCD#gmail.com"
'Body of the email
.Body = "Dear " & ActiveSheet.Range("C6").Value & ","
.Body = .Body & "Please find attached your Finance Report for the month of " & Format(Range("C8"), "mmmm yyyy") & "."
'Attach your files
StrFile = Dir(StrPath & "*.pdf")
Do While Len(StrFile) > 0
myattachments.Add StrPath & StrFile
StrFile = Dir
Loop
'Displaying only the email. Not sending
.Display
End With
End Sub
The function selectfolder returns the path without the '' at the end, so please add '' at the end, so selectfolder has to return like "c:\temp\pdffolder', currently it is returning 'c:\temp\pdffolder', so Dir line is not returning the files.

How to Loop Through A Table Column to Filter Another Table to Send Each Filtered Table By Email?

I am trying to:
Use a value from Table A (column - person's name) to filter on Table B in separate sheet
Copy filtered Table B into the body of an email (outlook)
Send outlook email to email address for that recipient (from Table A)
Loop through the process again for the next person in Table A
Example of Table A:
Example of Table B:
So for example for the first iteration
Take Dave Jones from Table A and filter Table B for Dave Jones.
Copy the filtered Table B to the body of a new email
Send to Dave Jones (davejones#davejones.com).
Return to Table A for the next entry, in this case Anne Smith, and do the same. Repeat until the end of Table A.
I made code for setting up an email but this takes the whole worksheet and does not do any filtering. I am unable to work out how to put this loop together for multiple emails:
Sub SendWorkSheet_SENDEMAILS1()
Dim xFile As String
Dim xFormat As Long
Dim Wb As Workbook
Dim Wb2 As Workbook
Dim FilePath As String
Dim FileName As String
Dim OutlookApp As Object
Dim OutlookMail As Object
On Error Resume Next
Application.ScreenUpdating = False
Set Wb = Application.ActiveWorkbook
ActiveSheet.Copy
Set Wb2 = Application.ActiveWorkbook
Select Case Wb.FileFormat
Case xlOpenXMLWorkbook:
xFile = ".xlsx"
xFormat = xlOpenXMLWorkbook
Case xlOpenXMLWorkbookMacroEnabled:
If Wb2.HasVBProject Then
xFile = ".xlsm"
xFormat = xlOpenXMLWorkbookMacroEnabled
Else
xFile = ".xlsx"
xFormat = xlOpenXMLWorkbook
End If
Case Excel8:
xFile = ".xls"
xFormat = Excel8
Case xlExcel12:
xFile = ".xlsb"
xFormat = xlExcel12
End Select
FilePath = Environ$("temp") & "\"
FileName = Wb.name & Format(Now, "dd-mmm-yy h-mm-ss")
Set OutlookApp = CreateObject("Outlook.Application")
Set OutlookMail = OutlookApp.CreateItem(0)
Wb2.SaveAs FilePath & FileName & xFile, FileFormat:=xFormat
With OutlookMail
.to = "EMAIL ADDRESS HERE"
.CC = ""
.BCC = ""
.Subject = "Suppliers"
.HTMLBody = "Hi all," & "<br>" & "<br>" & "Please find attached etc. etc." & "<br>" & "<br>" & "Kind regards," & "<br>" & "<br>" & "Sender"
'.Body = ""
.Attachments.Add Wb2.FullName
.Display
'.Send
End With
Wb2.Close
Kill FilePath & FileName & xFile
Set OutlookMail = Nothing
Set OutlookApp = Nothing
Application.ScreenUpdating = True
End Sub
I’ve had the need to do the task you describe a number of times in the past, and the following was the solution I came up with. Great credit to Sigma Coding at https://www.youtube.com/watch?v=ZlInSp0-MdU&ab_channel=SigmaCoding
for providing the bulk of the code – the Loop and Filter stuff I added for my own specific application.
For the following to work, you need to enable a couple of references within VBA. In the VBA Editor, select Tools/References & check the boxes ‘Microsoft Outlook 16.0 Object Library’ and ‘Microsoft Word 16.0 Object Library’. If they’re not already checked, you’ll find them listed alphabetically.
The following code suggestion assumes the following:
• The Managers’ list is on Sheet1 and the range they are contained in is called “MyRange”
• The table to filter is on Sheet2 and starts from cell A1
This code works for me – let me know how you go with it.
Option Explicit
Dim Outlook As Outlook.Application
Dim OutMail As Outlook.MailItem
Dim OutInspect As Outlook.Inspector
Dim EmailTo As String
Dim OutWrdDoc As Word.Document
Dim OutWrdRng As Word.Range
Dim OutWrdTbl As Word.Table
Dim rng As Range, c As Range, MyRange As Range, myFilter As String
Sub TestEmail()
For Each c In Sheet1.Range("MyRange")
myFilter = c.Value
EmailTo = c.Offset(0, 1).Value
Sheet2.Range("A1:E1").AutoFilter Field:=2, Criteria1:="=" & myFilter
'ERROR TRAP
If EmailTo = "" Or Sheet2.Cells.SpecialCells(xlCellTypeVisible).Rows.Count = 1 Then
GoTo Missing:
End If
Set rng = Sheet2.Cells.SpecialCells(xlCellTypeVisible)
On Error Resume Next
Set Outlook = GetObject(, "Outlook.Application")
If Err.Number = 429 Then
Set Outlook = New Outlook.Application
End If
Set OutMail = Outlook.CreateItem(olMailItem)
With OutMail
.To = EmailTo
.Subject = "Suppliers"
.Body = "Please find attached etc."
.Display
Set OutInspect = .GetInspector
Set OutWrdDoc = OutInspect.WordEditor
rng.Copy
Set OutWrdRng = OutWrdDoc.Application.ActiveDocument.Content
OutWrdRng.Collapse Direction:=wdCollapseEnd
Set OutWrdRng = OutWrdDoc.Paragraphs.Add
OutWrdRng.InsertBreak
OutWrdRng.PasteExcelTable Linkedtoexcel:=True, wordformatting:=True, RTF:=True
Set OutWrdTbl = OutWrdDoc.Tables(1)
OutWrdTbl.AllowAutoFit = True
OutWrdTbl.AutoFitBehavior (wdAutoFitWindow)
.Send
Application.CutCopyMode = False
Sheet2.AutoFilterMode = False
End With
Missing:
Next c
End Sub

Adding default signature, that consists of images, in Outlook using Excel VBA

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
My signature should be as shown below.
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.
Also the paths mentioned in the htmlbody are incomplete. See the below images
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

Resources