I'd like to build\edit the mail signiture in Excel:
1st cell : |Regards, |
2nd cell (Name) : |Asaf Gilad |
3rd Cell (Title): |PMO |
4th cell (Mail) : |Asaf#mail.com |
So that when I click send, the body of the message will look like:
Dear sir
................................
....... Message Content ........
................................
................................
Regards,
Asaf Gilad
PMO
Asaf#mail.com
The signiture contains pictures as well.
I managed to save the range as picture and send that picture as attachment, but the picture turned out to be empty in the body, dispite the fact that it was sent correctly as attachment.
Here is the code I use:
Public Sub ExportEmail(recipentName As String)
On Error GoTo err:
Dim olApp As Outlook.Application
Dim olNs As Outlook.Namespace
Dim olMail As Outlook.MailItem
Dim strEmailTo As String, strEmailCC As String, strEmailBCC As String
Dim FNAME As String
Dim oRange As Range
Dim oChart As Chart
Dim oImg As Picture
strEmailTo = ""
strEmailCC = ""
strEmailBCC = ""
strEmailTo = "a#a.com"
strEmailCC = "b#b.com
If strEmailTo "" Then
Set olApp = New Outlook.Application
Set olNs = olApp.GetNamespace("MAPI")
olNs.Logon
Set olMail = olApp.CreateItem(olMailItem)
olMail.To = strEmailTo
olMail.CC = strEmailCC
olMail.BCC = strEmailBCC
olMail.Subject = " My Subject"
Set oRange = Sheets(1).Range("A1:Z100")
Set oChart = Charts.Add
oRange.CopyPicture xlScreen, xlPicture
oChart.Paste
FNAME = Environ$("temp") & "\testPic.gif"
oChart.Export Filename:=FNAME, FilterName:="GIF"
olMail.Attachments.Add FNAME
olMail.HTMLBody = "" & _
""
olMail.Attachments.Add FNAME
olMail.Send
End If
Application.StatusBar = False
Application.ScreenUpdating = True
Application.DisplayAlerts = True
Kill FNAME
Set olApp = Nothing
Set olNs = Nothing
Set oRange = Nothing
Set oChart = Nothing
Set oImg = Nothing
Exit Sub
err:
MsgBox err.Description
End Sub
This is a good question, Asaf. When I have built automated e-mail solutions, I've found it difficult to get the signature line in. It's possible, but not easy. Maybe it's updated in 2010, but I haven't checked yet.
What I do is place the entire body into a text file on a drive, complete with any html tags that I want for formatting. This gives me great flexibility in both making nicely formatted e-mails where I can assign variables as well.
I then access those files through the Microsoft Scripting Runtime library.
See below code snippets:
Option Explicit
Const strEmailBoiler As String = "\\server\path\folder\subfolder\email_text\"
Sub PrepMessage()
Dim strBody As String, strMon As String
strMon = range("Mon").Value
strFY = range("FY").Value
strBody = FileToString(strEmailBoiler, "reports_email_body.txt")
strBody = Replace(strBody, "[MONTH]", strMon)
strBody = Replace(strBody, "[YEAR]", Right(strFY, 2))
strBody = Replace(strBody, "[FILE PATH]", strFileName)
SendMail "firstname.lastname#xyz.com", "Subject Goes Here " & strMon & " YTD", strBody
End Sub
Function FileToString(ByVal strPath As String, ByVal strFile As String) As String
'requires reference to Microsoft Scripting Runtime Object Library (or late binding)
Dim ts As TextStream
Set fso = New FileSystemObject
Set ts = fso.OpenTextFile(strPath & strFile, ForReading, False, TristateUseDefault)
FileToString = ts.ReadAll
ts.Close
Set ts = Nothing
Set fso = Nothing
End Function
Sub SendMail(strTo As String, strSubject As String, strHTMLBody As String, Optional strAttach As String, Optional strCC As String)
'requires reference to Microsoft Outlook X.X Object Library (or late binding)
Dim olApp As Outlook.Application
Dim olMI As Outlook.MailItem
Set olApp = CreateObject("Outlook.Application")
Set olMI = olApp.CreateItem(olMailItem)
With olMI
.To = strTo
.Subject = strSubject
.HTMLBody = strHTMLBody
If strAttach <> vbNullString Then .Attachments.Add strAttach
.Display 'using this because of security access to Outlook
'.Send
End With
End Sub
Then my reports_email_body.txt file will look like this:
<p>Hello Person,</p>
<p>The Reports file for [MONTH] FY[YEAR] has been saved in the following location:</p>
<p>[FILE PATH]</p>
<p>Best,</p>
<br>
Scott Holtzman
<br>My Address
<br>my title
<br>whatever else...
In Excel 2010 (and possibly 2007) you can add .HTMLBody to the end of your body string. For instance, use something like this:
.HTMLBody = "<br>" & strbody & .HTMLBody
' <br> is an HTML tag to turn the text into HTML
' strbody is your text from cell C9 on the mail tab
' .HTMLBody inserts your email signature
This will at least solve your signature line problem.
I am looking for a solution for the same problem: Inserting a range as a picture.
Related
I send reports with Subject Name Like "Sales Report till 01-Sep-2022" in which only the date changes and initial like "Sales Report till*" remains the same.
Below is the code for "Replying to All" from sent items, which works well on "Replying to All" from sent items. The only problem is it's not replying on latest Sent Email.
It picks any email with "Sales Report till" whether that sent mail is from last week or last month.
I want to Reply to All on the latest Sent Email.
Sub OL_Email_Reply_To_All_WFN()
Dim olApp As Outlook.Application
Dim olNs As Namespace
Dim Fldr As MAPIFolder
Dim objMail As Object
Dim objReplyToThisMail As MailItem
Dim lngCount As Long
Dim objConversation As Conversation
Dim objTable As Table
Dim objVar As Variant
Dim Path, WFN, SN As String
Dim WFN_Sub, WFN_RN, WFN_MB As String
Path = ThisWorkbook.Sheets("Main_Sheet").Range("B1") & "\" '''''Path to pick from "Main_Sheet" of ThisWorkbook
WFN = Path & ThisWorkbook.Sheets("Main_Sheet").Range("B2") ''''' Working File Name can be diffrent will change on sheet.
''''WFN_Sub = ThisWorkbook.Sheets("Main_Sheet").Range("B3")
''''WFN_RN = ThisWorkbook.Sheets("Main_Sheet").Range("B4")
''''WFN_MB = ThisWorkbook.Sheets("Main_Sheet").Range("B5")
''''WFN_SN = ThisWorkbook.Sheets("Main_Sheet").Range("B6")
'''''Original Subject Name looks like "Sales Report till 01-Sep-2022" in which date changes every everytime.
WFN_Sub = "Test Email" '''''Subject to find should be intial only
WFN_RN = "Hi Friend" '''''Recipient Name
WFN_MB = "Please ignore it's a Test Email" ''''''''''Mail Body
SN = "My Name" '''''''''Senders Name
Set olApp = Session.Application
Set olNs = olApp.GetNamespace("MAPI")
Set Fldr = olNs.GetDefaultFolder(olFolderSentMail)
lngCount = 1
ThisWorkbook.Activate
For Each objMail In Fldr.Items
If TypeName(objMail) = "MailItem" Then
If InStr(objMail.Subject, WFN_Sub) <> 0 Then
Set objConversation = objMail.GetConversation
Set objTable = objConversation.GetTable
objVar = objTable.GetArray(objTable.GetRowCount)
Set objReplyToThisMail = olApp.Session.GetItemFromID(objVar(UBound(objVar), 0))
With objReplyToThisMail.ReplyAll
.Subject = WFN_Sub & " " & Format(Now() - 1, "DD-MMM-YYYY")
.HTMLBody = WFN_RN & "<br> <br>" & WFN_MB & "<br> <br>" & "Kind Regards" & "<br>" & SN
.display
.Attachments.Add WFN
End With
Exit For
End If
End If
Next objMail
Set olApp = Nothing
Set olNs = Nothing
Set Fldr = Nothing
Set objMail = Nothing
Set objReplyToThisMail = Nothing
lngCount = Empty
Set objConversation = Nothing
Set objTable = Nothing
If IsArray(objVar) Then Erase objVar
End Sub
Before getting the last row in the table (retrieved from the conversation object) you need to sort items based on the recieved date:
'Sort by ReceivedTime in descending order
table.Sort "[ReceivedTime]", True
Only after that you may rely on the last item in the code.
There is possibly simpler code.
Option Explicit
Sub OL_Email_Reply_To_All_WFN()
' reference Microsoft Outlook XX.X Object Library
Dim olApp As Outlook.Application
Dim olNs As Outlook.Namespace
Dim olFldr As Outlook.Folder
Dim objMail As Object
Dim Path As String, WFN As String, SN As String
Dim WFN_Sub As String, WFN_RN As String, WFN_MB As String
'Path = ThisWorkbook.Sheets("Main_Sheet").Range("B1") & "\" '''''Path to pick from "Main_Sheet" of ThisWorkbook
'WFN = Path & ThisWorkbook.Sheets("Main_Sheet").Range("B2") ''''' Working File Name can be diffrent will change on sheet.
''''WFN_Sub = ThisWorkbook.Sheets("Main_Sheet").Range("B3")
''''WFN_RN = ThisWorkbook.Sheets("Main_Sheet").Range("B4")
''''WFN_MB = ThisWorkbook.Sheets("Main_Sheet").Range("B5")
''''WFN_SN = ThisWorkbook.Sheets("Main_Sheet").Range("B6")
'''''Original Subject Name looks like "Sales Report till 01-Sep-2022" in which date changes every everytime.
WFN_Sub = "Test Email" '''''Subject to find should be intial only
WFN_RN = "Hi Friend" '''''Recipient Name
WFN_MB = "Please ignore it's a Test Email" ''''''''''Mail Body
SN = "My Name" '''''''''Senders Name
Set olApp = CreateObject("Outlook.Application")
Set olNs = olApp.GetNamespace("MAPI")
Set olFldr = olNs.GetDefaultFolder(olFolderSentMail)
Dim fldrItems As Outlook.Items
Set fldrItems = olFldr.Items
fldrItems.Sort "[ReceivedTime]", True
Dim i As Long
For i = 1 To fldrItems.Count
If TypeName(fldrItems(i)) = "MailItem" Then
If InStr(fldrItems(i).Subject, WFN_Sub) <> 0 Then
Debug.Print fldrItems(i).ReceivedTime
With fldrItems(i).ReplyAll
.Subject = WFN_Sub & " " & Format(Now() - 1, "DD-MMM-YYYY")
.htmlbody = WFN_RN & "<br> <br>" & WFN_MB & "<br> <br>" & "Kind Regards" & "<br>" & SN
.Display
'.Attachments.Add WFN
End With
Exit For
End If
End If
Next
Set olApp = Nothing
Set olNs = Nothing
Set olFldr = Nothing
Set fldrItems = Nothing
Set objMail = Nothing
End Sub
My default email signature is overwritten by an embedded image. The signature shows up at first and then the picture takes its place.
I want this code to work for other people. How can I add the default email signature?
Sub Send_Email()
Dim pdfPath As String, pdfName As String
'PDF name same as the workbook.name
pdfName = "VW Fuel Marks_" & Format(Date, "m.d.yyyy")
'PDF save path same as workbook path, where the workbook is saved
pdfPath = ThisWorkbook.Path & "\" & pdfName & ".pdf"
'Selecting sheets (if any of the sheets hidden it will run to an error)
ThisWorkbook.Sheets(Array("Daily Dashboard-Page1", "Daily Dashboard-Page2", "Daily Dashboard-Page3", "Daily Dashboard-Page4")).Select
'Create pdf and open it (if a pdf with a same name is already opened it will run to an error)
ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:=pdfPath, Quality:=xlQualityStandard, IncludeDocProperties:=True, _
IgnorePrintAreas:=False, OpenAfterPublish:=True
Application.Worksheets(19).Range("A1:T42").CopyPicture xlScreen, xlPicture
Dim OApp As Object, OMail As Object, Signature As String
Dim cell As Range, S As String, WMBody As String, lFile As Long
Set OApp = CreateObject("Outlook.Application")
Set OMail = OApp.CreateItem(0)
With OMail
.Display
End With
Signature = OMail.HTMLBody
With OMail
.To = Range("AG3").Value
.CC = Range("AG4").Value
.Subject = Range("A1").Value
.HTMLBody = Replace(Signature, "<div class=WordSection1><p class=MsoNormal><o:p>", "<div class=WordSection1><p class=MsoNormal><o:p>" & sBody)
.Attachments.Add pdfPath
OMail.Display
End With
'.Attachments.Add
Set ins = OMail.GetInspector
'need add reference to Microsoft Word Object Library
Dim doc As Word.Document
Set doc = ins.WordEditor
doc.Select
doc.Application.Selection.Paste
OMail.Display
Set OMail = Nothing
Set OApp = Nothing
End Sub
You need to insert the content right after the opening <body> tag. In that case the rest content will be preserved as is.
With OMail
.Display
End With
Signature = OMail.HTMLBody
With OMail
.To = Range("AG3").Value
.CC = Range("AG4").Value
.Subject = Range("A1").Value
' here you need to find the <body> tag and insert the new content right after it
.HTMLBody = ...
.Attachments.Add pdfPath
OMail.Display
End With
You can use VBA string functions to find the <body> tag and paste the content right after it.
You select the body then paste over it.
Set doc = ins.WordEditor
doc.Select
doc.Application.Selection.Paste
Instead paste at the top, in a smaller size.
Set doc = ins.WordEditor
doc.Range(0, 0).Paste
This pastes at the top with size matching your code.
Set doc = ins.WordEditor
Dim wdRange As Word.Range
Set wdRange = doc.Range(0, 0)
wdRange.Select
doc.Application.Selection.Paste
I want to attach a chart in the email when the user clicks on a button.
The code isn't adding the chart.
The naming is correct and I am not receiving any errors (except ones I've implemented to help test).
If ChartNameLine = "" Then
GoTo ErrorMsgs
Else
Dim xOutApp As Object
Dim xOutMail As Object
Dim xChartName As String
Dim xPath As String
Dim xChart As ChartObject
Dim xChartPath As String
On Error Resume Next
xChartName = Application.InputBox("Please Enter the Chart name: ", "KuTools for Excel", , , , , , 2)
'xChartName = ChartNameLine
Set xChart = Worksheets(.HTMLBody).ChartObjects(xChartName)
xChart.Chart.ChartArea.Copy
errorCode = 101
'If xChart Is Nothing Then GoTo ErrorMsgs
xOutApp = CreateObject("Outlook.Application")
Set xOutMail = xOutApp.CreateItem(0)
xChartPath = ThisWorkbook.path & "\" & Environ("USERNAME") & VBA.Format(VBA.Now(), "DD_MM_YY_HH_MM_SS") & ".bmp"
xPath = "<p align='Left'><img src= " / "cid:" & Mid(xChartPath, InStrRev(xChartPath, "\") + 1) & """ width = 800 height = 500> <br> <br>"
xChart.Chart.Export xChartPath
With xOutMail
.To = ToLine
.Subject = SubjectLine
.Attachments.Add xChartPath
.HTMLBody = xPath
.Display
End With
Kill xChartPath
'Set xOutMail = Nothing
'Set xOutApp = Nothing
End If
Using code from "Extend Office"
Create a chart in a new workbook with a sheet named "test". The chart should be named "Chart 1".
With no other code in the new workbook.
Option Explicit ' Consider this mandatory
' Tools | Options | Editor tab
' Require Variable Declaration
' If desperate declare as Variant
Sub AddWorksheetTestChartToMail()
Dim xOutApp As Object
Dim xOutMail As Object
Dim xChartName As String
Dim xPath As String
Dim xChart As ChartObject
Dim xChartPath As String
xChartName = "Chart 1"
' "test", not .HTMLBody
Set xChart = Worksheets("test").ChartObjects(xChartName)
xChart.Chart.ChartArea.Copy
' Set was missing
Set xOutApp = CreateObject("Outlook.Application")
Set xOutMail = xOutApp.CreateItem(0)
xChartPath = ThisWorkbook.Path & "\" & Environ("USERNAME") & VBA.Format(VBA.Now(), "DD_MM_YY_HH_MM_SS") & ".bmp"
Debug.Print xChartPath
' suggested fix in comment on the question post - src=""cid:"
xPath = "<p align='Left'><img src=""cid:" & Mid(xChartPath, InStrRev(xChartPath, "\") + 1) & """ width=700 height=500 > <br> <br>"
xChart.Chart.Export xChartPath
With xOutMail
.To = "ToLine"
.Subject = "SubjectLine"
.Attachments.Add xChartPath
.HTMLBody = xPath
.Display
End With
Kill xChartPath
End Sub
First of all, the HTMLBody property returns or sets a string representing the HTML body of the specified item. If you need to add an image generated in Excel you most probably need to insert it at some point in the message, not substitute the whole message by setting it to the paragraph HTML tag. So, find a suitable place in the HTML document and insert the generated HTML piece there instead of replacing the whole message body.
Second, make sure a correct image is generated and saved to the disk. And there were no problems with image generation process from the Excel side.
Third, you may need to set the PR_ATTACH_CONTENT_ID property on the attached image so Outlook could easily recognize the embedded image.
I'm writting macro that finds an e-mail and replies to it. The problem is that the text I want to reply with does not add. Could you please tell me what I'm doing wrong?
Sub Test()
Dim olApp As Object
Dim olNs As Object
Dim Fldr As Object
Dim i As Long
Set olApp = CreateObject("Outlook.Application")
Set olNs = olApp.GetNamespace("MAPI").GetDefaultFolder(olFolderInbox).Folders("Test")
i = 1
For Each olMail In olNs.Items
If InStr(olMail.Subject, "kanapka") <> 0 Then
With olMail.ReplyAll
.CC = "xyz#xyz"
.Body = "Dear All," _
& vbCrLf & "aaaaaa" 'these two lines should add
olMail.Reply.Display
End With
i = i + 1
End If
Next olMail
End Sub
Try adding this to your code:
For Each olMail In olNs.Items
If InStr(olMail.Subject, "testme") <> 0 Then
Set oReply = olMail.Reply
Set oRecip = oReply.Recipients.Add("x#y.z")
oRecip.Type = olCC
oReply.HTMLBody = "Thank you!!!" & oReply.HTMLBody
oReply.Display
Stop ' - remove this once you try the code.
End If
Next olMail
As you see, you have to declare oReply and oRecip as Objects, but these two make your life really easier.
In order to add some text to the answer, simply increment the body this way:
oReply.HTMLBody = "Thank you!!!" & oReply.HTMLBody
I have also included a Stop in your code, to make sure that it does not display plenty of emails.
The method does not concern me. Whether it is a macro, or somehow automatically fires as the email is sent.
I want to know if there is a way for outlook to automatically assign a signature based on the recipient.
Must work with Outlook 2007. If alternate methods exist, they can be added, referencing which version it works on. A lot of my macros had to be rewritten for 2007.
Method is not important, as long as it doesn't involve user interaction other than regular UI usage to send an email.
Thanks.
Based on code from here http://www.rondebruin.nl/win/s1/outlook/signature.htm
You can set it up to be called from Application_ItemSend but that is probably asking for trouble.
Sub With_Variable_Signature()
Dim itm As mailItem
Dim StrSignature As String
Dim sPath As String
Dim recip As Recipient
Set itm = ActiveInspector.currentItem
sPath = Environ("appdata") & "\Microsoft\Signatures\defaultSig.htm"
For Each recip In itm.Recipients
Debug.Print recip.name
If recip.name = "somebody" And recip.type = olTo Then ' or = olcc or = olbcc
sPath = Environ("appdata") & "\Microsoft\Signatures\customizedSig.htm"
Exit For
End If
Next
If Dir(sPath) <> "" Then
StrSignature = GetBoiler(sPath)
Else
StrSignature = ""
End If
With itm
.HTMLBody = .HTMLBody & vbNewLine & vbNewLine & StrSignature
End With
Set itm = Nothing
End Sub
Function GetBoiler(ByVal sFile As String) As String
'Dick Kusleika
Dim fso As Object
Dim ts As Object
Set fso = CreateObject("Scripting.FileSystemObject")
Set ts = fso.GetFile(sFile).OpenAsTextStream(1, -2)
GetBoiler = ts.readall
ts.Close
End Function