I'm trying to do a "reply all" command using a specific template.
This is what I have so far:
Sub my_test()
Dim mail 'object/mail item iterator
Dim replyall 'object which will represent the reply email
For Each mail In Outlook.Application.ActiveExplorer.Selection
If mail.Class = olMail Then
Set replyall = mail.replyall
With replyall
.Body = "My template from a oft file"
.Display
End With
End If
Next
End Sub
In the body, I'd like to use a template which I have in a oft file in c:\mytemplate.oft.
When I reply, in the bottom I want the original email and in the top of the email body I want the text from the existing template.
The idea is to use this code (if possible), and place the context of the template body file (text and a table), inside of this reply email (in the top).
Code for Outlook. No apparent purpose for the Excel tag.
Option Explicit
Sub my_test()
Dim objItem As Object
Dim mail As MailItem
Dim replyall As MailItem
Dim templateItem As MailItem
For Each objItem In ActiveExplorer.Selection
If objItem.Class = olMail Then
Set mail = objItem
Set replyall = mail.replyall
Set templateItem = CreateItemFromTemplate("C:\template.oft")
With replyall
.HTMLBody = templateItem.HTMLBody & .HTMLBody
.Display
End With
End If
Next
End Sub
Related
I'm having trouble trying to update mailItem.ReplyAll.HTMLBody. I can't seem to add new text to the body without deleting the previous value. The following code below results in an email item that only has the previous HTMLBody in it and not the new "Hello world" text.
mMail.BodyFormat = olFormatHTML
On Error Resume Next
With mMail.ReplyAll
.HTMLBody = "Hello world" & .HTMLBody
.Display
End With
On Error GoTo 0
How do I add to the HTMLBody of a ReplyAll email while maintaining the original HTMLBody?
First of all, keep in mind that in case of the HTMLBody property you deal with a HTML web page, so the HTML formatting should be well-formed.
Second, try to split the new item after calling the ReplyAll method which creates a reply to all original recipients from the original message and a new MailItem object that represents the reply is returned.
Dim reply as Outlook.MailItem
On Error Resume Next
Set reply = mMail.ReplyAll
With reply
.HTMLBody = "<b>Hello world<b>"
.Display
End With
If you need to insert any text into message body represented by the HTML document, you need to find the opening <body> tag and insert your text right after it instead.
The original code should be sufficient unless missing parts have an impact.
Try moving .Display so HtmlBody is seen before editing.
Option Explicit
Private Sub testActiveInspector()
Dim currItem As Object
Dim replyMail As MailItem
Set currItem = ActiveInspector.CurrentItem
If currItem.Class = olMail Then
currItem.BodyFormat = olFormatHTML
Set replyMail = currItem.ReplyAll
With replyMail
.Display
.HtmlBody = "Hello world" & .HtmlBody
End With
End If
End Sub
Private Sub testSelection()
Dim currItem As Object
Dim replyMail As MailItem
Set currItem = ActiveExplorer.Selection(1)
If currItem.Class = olMail Then
currItem.BodyFormat = olFormatHTML
Set replyMail = currItem.ReplyAll
With replyMail
.Display
.HtmlBody = "Hello world" & .HtmlBody
End With
End If
End Sub
You should remove On Error Resume Next when it is followed by code to create mail. Address any errors appropriately.
You should remove On Error Resume Next in 99.9999% of all other cases.
I'm new to this and got my first Excel macro working yesterday. I've create a command button on Excel to set up an email and I want to send a range from the worksheet. I would like it to keep the formatting if possible. I believe the issue is with:
xMailBody = ThisWorkbook.Activeworksheet("Sheet1").Range("AA65:AE67")
Everything else worked okay.
Thank you very much.
Sonny
Private Sub CommandButton1_Click()
'Updated by 2022/09/16
Dim xOutApp As Object
Dim xOutMail As Object
Dim xMailBody As String
On Error Resume Next
Set xOutApp = CreateObject("Outlook.Application")
Set xOutMail = xOutApp.CreateItem(0)
xMailBody = ThisWorkbook.Activeworksheet("Sheet1").Range("AA65:AE67")
On Error Resume Next
With xOutMail
.To = Range("AD69")
.CC = ""
.BCC = ""
.Subject = Range("AD70")
.Body = xMailBody
.Display 'or use .Send
End With
On Error GoTo 0
Set xOutMail = Nothing
Set xOutApp = Nothing
End Sub
You have xMailBody declared as a string then are stating that it is the desired range.
Try DIMing it as a range!
First of all, I've noticed that you are trying to set the Body property which is a plain text string:
.Body = xMailBody
If you need to preserve formatting you can create a well-formed HTML formatting and then assign it to the HTMLBody prperty of Outlook items.
The Outlook object model supports three main ways of customizing the message body:
The Body property returns or sets a string representing the clear-text body of the Outlook item.
The HTMLBody property of the MailItem class returns or sets a string representing the HTML body of the specified item. Setting the HTMLBody property will always update the Body property immediately. For example:
Sub CreateHTMLMail()
'Creates a new e-mail item and modifies its properties.
Dim objMail As Outlook.MailItem
'Create e-mail item
Set objMail = Application.CreateItem(olMailItem)
With objMail
'Set body format to HTML
.BodyFormat = olFormatHTML
.HTMLBody = "<HTML><BODY>Enter the message text here. </BODY></HTML>"
.Display
End With
End Sub
The Word object model can be used for dealing with message bodies. In that case you can just copy the required range in Excel and then paste to the message directly using the Paste method from the Word object model. See Chapter 17: Working with Item Bodies for more information.
Also you may consider using the RangetoHTML function to convert Excel data to the HTML markup.
I am trying to copy multiple charts from Excel into Outlook, each as a bitmap, and each on its line and of the same size. The code below loops through copying each chart and successfully pasting them all as bitmaps into Outlook. However, they all occur right next to each, 1-3 in a row depending on size. I have tried adding vbNewLine, vbCrLF, and <br> as well as a few others but they all delete all the charts. Any ideas on how to get each chart on its own line so they are vertically stacked in the e-mail and of the same size? Here is the code. Thanks in advance:
Public Sub EmailCharts()
Dim Sht As Excel.Worksheet
Set Sht = ThisWorkbook.ActiveSheet
Dim OutApp As Object
Set OutApp = CreateObject("Outlook.Application")
Dim outMail As Object
Set outMail = OutApp.CreateItem(0)
Dim vInspector As Object
Set vInspector = outMail.GetInspector
Dim wEditor As Object
Set wEditor = vInspector.WordEditor
Dim objChart As Excel.ChartObject
With outMail
.Display
.to = "abc#xyz.com"
.BCC = "abc#xyz.com"
.Subject = "Subject"
For Each objChart In Sht.ChartObjects
objChart.CopyPicture (xlBitmap)
.HTMLBody = wEditor.Range(0, 0).Paste
Next
End With
Set outMail = Nothing
Set OutApp = Nothing
End Sub
In your code you mixed different approaches when dealing with a MailItem body.
.HTMLBody = wEditor.Range(0, 0).Paste
The Range.Paste method from the Word object model doesn't return any HTML string which can be assigned to the HTMLBody property. So, you need to use one or another, but not two together. I thin the Word object model is much simpler to use (the Paste method), you just need to choose a different place for each image.
The Outlook object model supports three main ways of customizing the message body:
The Body property returns or sets a string representing the clear-text body of the Outlook item.
The HTMLBody property of the MailItem class returns or sets a string representing the HTML body of the specified item. Setting the HTMLBody property will always update the Body property immediately. For example:
Sub CreateHTMLMail()
'Creates a new e-mail item and modifies its properties.
Dim objMail As Outlook.MailItem
'Create e-mail item
Set objMail = Application.CreateItem(olMailItem)
With objMail
'Set body format to HTML
.BodyFormat = olFormatHTML
.HTMLBody = "<HTML><BODY>Enter the message text here. </BODY></HTML>"
.Display
End With
End Sub
The Word object model can be used for dealing with message bodies. See Chapter 17: Working with Item Bodies for more information.
Note, the MailItem.BodyFormat property allows you to programmatically change the editor that is used for the body of an item.
I have a user who sends eMails to a large "To" list, Sometimes over 20 addresses. With this large a "To" list, the received mail sometimes ends up on the recipient's SPAM folder. Obviously, we'd like to avoid this.
My idea is to have the user create an original eMail and then run a Macro. The Macro would loop through all the eMail addresses in an Excel worksheet and then copy the original message and send it to each recipient individually.
I'm unsure as to how to copy a MailItem from the original to a new MailItem. The Excel looping works fine.
Here's my abbreviated macro:
Option Explicit
Sub Send_emails()
'.
'.
Set objDoc = objInspector.WordEditor
Set objWrdApp = objDoc.Application
Set objSelection = objWrdApp.Selection
'Loop through the Rows in the worksheet. Start at row 2 to ignore header
For lngCurrSheetRow = 2 To lngLastSheetRow
strEmailAddress = objWorksheet.Cells(lngCurrSheetRow, 1).Value
'Set objNewMail so that the new message is created and can be referenced.
Set objNewMail = Application.CreateItem(0)
With objNewMail
.Body = objSelection
.To = strEmailAddress
End With
Next lngCurrSheetRow
'.
'.
End Sub
To copy mailitem.body Example would be
Option Explicit
Sub Send_emails()
Dim olMsg As Outlook.MailItem
Set olMsg = ActiveExplorer.Selection.Item(1)
Dim objNewMail As Outlook.MailItem
Set objNewMail = Application.CreateItem(0)
With objNewMail
.Body = olMsg.Body
.Display
End With
End Sub
For HTML Body simply do HTMLBody = olMsg.HTMLBody
Can I use mailitem.entryID in Excel VBA?
I have a tool using excel where I can send an outlook email to recipients using spreadsheet as the UI to display user data. I need to store the entryID of each of the emails send to the user in the excel table. Can I set in the code (excel vba) mailitem.entryID = worksheet.cells().value ? Will it retrieve the entryID? Can you give me your input regarding this? Thank you for your help.
Dim AppOutlook As Object
Dim MailOutlook As Object
Dim Emailto, ccto, sendfrom As String
Set AppOutlook = CreateObject("Outlook.Application")
Set MailOutlook =AppOutlook.CreateItem(0)
Emailto = worksheet.Cells().Value
ccto = worksheet.Cells().Value
sendfrom = "email"
With OutMail
.SentOnBehalfOfName = sendfrom
.To = Emailto
.CC = ccto
.BCC = ""
.Subject =
.BodyFormat = olFormatHTML
.HTMLBody = "body here"
.Send
This is my code, and I plan to add the code worksheet.cells.value = MailOutlook.entryID at the last line of the code. Is it possible? and where to add the AddItem event?
You can read the EntryID property after the message is sent. You cannot do that before or immediately after sending the message - it will be changed when the message is asynchronously sent and moved to the Sent Item folder. The erliest you can access the entry id in the Sent Items folder is when the Items.ItemAdd event fires in the Sent Items folder.
The mail item may not exist any longer after calling the Send method. It can be moved to the Outbox folder for further processing by the transport provide. Item can be marked for processing by the transport provider, not being yet sent. So, we need to handle the ItemSend event in the code.
If you need to be sure that the mail item was sent for sure I'd recommend handling the ItemAdd event of the Items class (see the corresponding property of the Folder class). For example, when an Outlook item is sent, a sent copy is placed to the Sent Items folder in Outlook. You may handle the ItemAdd event for that folder to be sure that the item was sent for sure. Consider adding a user property before displaying the Outlook item and checking it in the ItemAdd event handler to identify the item uniquely.
Demo code based on your code:
Sub Test3()
Dim AppOutlook As Object
Dim MailOutlook As Object
Dim Emailto, ccto, sendfrom As String
Set AppOutlook = CreateObject("Outlook.Application")
Set MailOutlook = AppOutlook.CreateItem(0)
Emailto = Worksheets("Sheet3").Cells(1, 1).Value
ccto = Worksheets("Sheet3").Cells(2, 1).Value
sendfrom = "test#outlook.com"
With MailOutlook
.SentOnBehalfOfName = sendfrom
.To = Emailto
.CC = ccto
.BCC = ""
.Subject = "Test"
.BodyFormat = olFormatHTML
.HTMLBody = "body here"
'.Display
.Send
End With
End Sub
Some ItemAdd snippet for you reference(The current event is not the right one, we still need to test it):
Option Explicit
Private objNS As Outlook.NameSpace
Private WithEvents objItems As Outlook.Items
‘Private Sub Application_Startup()
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim objWatchFolder As Outlook.Folder
Dim AppOutlook As Object
Set AppOutlook = CreateObject("Outlook.Application")
Set objNS = AppOutlook.GetNamespace("MAPI")
'Set the folder and items to watch:
Set objWatchFolder = objNS.GetDefaultFolder(olFolderInbox)
Set objItems = objWatchFolder.Items
Set objWatchFolder = Nothing
End Sub
Private Sub objItems_ItemAdd(ByVal Item As Object)
' Your code goes here
MsgBox "Message subject: " & Item.Subject & vbcrlf & "Message sender: " & Item.SenderName &" (" & Item.SenderEmailAddress & ")"
Worksheets("Sheet3").Cells(3, 1).Value = Item.EntryID
Set Item = Nothing
End Sub
The MailItem object is part of Outlook's VBA Object library. You can see the documentation for the MailItem object on MSDN here.
To use VBA objects from a different program in Microsoft Office (eg. calling Outlook from Excel, calling Visio from Word, calling Excel from Powerpoint) you first need to make sure you have the right References selected in your Visual Basic Editor (VBE).
How to turn on Outlook references in Excel:
In Excel's VBE, go to Tools > References.
A References - VBAProject box will appear.
Under Available References: scroll down until you reach something like Microsoft Outlook 16.0 Object Library (This will differ depending on the version of Office you are using)
Tick the box and press OK.
Now the Outlook Object references have been enabled, you should be able to call Outlook objects and methods from Excel, including MailItem.