Sending an Email through a VBA macro (Excel) - excel

I've spent the last couple days trying to figure this out, I've managed to stop all the errors, however the email doesn't show up in my inbox. I've tried to change everything up and still it doesn't show up.
The main purpose is to send an entire workbook to an email with a button (I've binded the button to the macro)
Anyways, here's the code I have already
Sub Send_mail()
Dim OutApp As Object
Dim OutMail As Object
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
On Error Resume Next
With OutMail
.To = "example#email.com"
.From = "example#email.com"
.CC = ""
.BCC = ""
.Subject = "Assunto"
.Body = "Corpo"
.Attachments.Add ActiveWorkbook.FullName
.Send
End With
On Error GoTo 0
Set OutMail = Nothing
Set OutApp = Nothing
End Sub
(ps I did change the email to post this, it's not what I have in the code)

Please remove .From = "example#email.com"
Mail will go with attachment from outlook default mail address.
In Microsoft Documentation From is not listed while To, cc, BCC etc are included . So syntax wise it is wrong. It works for me after removing .From
You can see from list below
Methods
Properties
Actions
AlternateRecipientAllowed
Application
Attachments
AutoForwarded
AutoResolvedWinner
BCC
BillingInformation
Body
BodyFormat
Categories
CC
Class
Companies
Conflicts
ConversationID
ConversationIndex
ConversationTopic
CreationTime
DeferredDeliveryTime
DeleteAfterSubmit
DownloadState
EntryID
ExpiryTime
FlagRequest
FormDescription
GetInspector
HTMLBody
Importance
InternetCodepage
IsConflict
IsMarkedAsTask
ItemProperties
LastModificationTime
MarkForDownload
MessageClass
Mileage
NoAging
OriginatorDeliveryReportRequested
OutlookInternalVersion
OutlookVersion
Parent
Permission
PermissionService
PermissionTemplateGuid
PropertyAccessor
ReadReceiptRequested
ReceivedByEntryID
ReceivedByName
ReceivedOnBehalfOfEntryID
ReceivedOnBehalfOfName
ReceivedTime
RecipientReassignmentProhibited
Recipients
ReminderOverrideDefault
ReminderPlaySound
ReminderSet
ReminderSoundFile
ReminderTime
RemoteStatus
ReplyRecipientNames
ReplyRecipients
RetentionExpirationDate
RetentionPolicyName
RTFBody
Saved
SaveSentMessageFolder
Sender
SenderEmailAddress
SenderEmailType
SenderName
SendUsingAccount
Sensitivity
Sent
SentOn
SentOnBehalfOfName
Session
Size
Subject
Submitted
TaskCompletedDate
TaskDueDate
TaskStartDate
TaskSubject
To
ToDoTaskOrdinal
UnRead
UserProperties
VotingOptions
VotingResponse

Related

Select a non-default sender using Excel VBA

How can I send from a secondary Outlook account using Excel VBA?
With OutMail
.to = Text(1)
.CC = Text(2)
.BCC = ""
.Subject =text(3)
.HTMLBody = Text(10)
.Display '.send
End With
I tried ".from".
The below is from a pretty all-purpose sub I use to send emails from VBA.
It takes three parameters:
OutApp is an Outlook.Application object
SendFromAddress is a string variable containing the address to send from
OutMail is the current mailitem object, which you already have as a variable looking at your code.
'Sender Address
If Len(SendFromAddress) > 0 Then
'if directly signed into the account:
For a = 1 To OutApp.Session.accounts.Count
If LCase(OutApp.Session.accounts.Item(a)) Like LCase(SendFromAddress) Then
Outmail.sendusingaccount = OutApp.Session.accounts.Item(a)
SendFromAddress = ""
Exit For
End If
Next
'If not directly signed in (shared mailbox):
If Len(SendFromAddress) > 0 Then Outmail.SentOnBehalfOfName = SendFromAddress
End If

Modify HTMLBody of Outlook Email, based on Template, from Excel

I am trying to modify the HTML body of an Outlook email, based on a template, from Excel VBA.
My code is:
Sub Email_Button()
Dim OutApp As Outlook.Application
Dim OutMail As Outlook.MailItem
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItemFromTemplate("S:\some\path\to\file\Email.oft")
With OutMail
.Importance = olImportanceHigh
.Subject = "Subject " & Date
.Attachments.Add Application.ActiveWorkbook.FullName
.HTMLBody = WorksheetFunction.Substitute(OutMail.HTMLBody, "%target%", "replacement")
.Display
End With
' *** TIDY UP ***
Set OutMail = Nothing
Set OutApp = Nothing
End Sub
The question is very similar to this.
I get
Run Time Error 287. Application-defined or object-defined error
on the .HTMLBody modification line.
If I remove this line the email is displayed for the user to check before hitting send.
I have referenced the Microsoft Outlook 15 Object Library.
I added:
With OutMail
.bodyFormat = olFormatHTML
But got the same error on the Substitute line so I changed the substitute to:
.HTMLBody = "<HTML><BODY>Some HTML text here</BODY></HTML>"
And the body of the email was updated.
So the error is only present when trying to use substitute or its to do with the oft.
It looks like from the debugger that there is no HTML body:
I have confirmed that body type is set to HTML both programmatically:
and by opening the oft message and checking:
The cause of the issue can be related to the Substitute method, so I'd suggest running the following code to make sure everything works correctly:
Sub CreateHTMLMail()
Dim OutApp As Outlook.Application
Set OutApp = CreateObject("Outlook.Application")
'Creates a new email item and modifies its properties.
Dim objMail As Outlook.MailItem
'Create email item
Set objMail = OutApp.CreateItemFromTemplate("S:\some\path\to\file\Email.oft")
With objMail
'Set body format to HTML
.BodyFormat = olFormatHTML
.HTMLBody = "<HTML><BODY>Enter the message text here. </BODY></HTML>"
.Display
End With
End Sub
Another aspect is Outlook security prompts. Read more about that in the "A program is trying to send an e-mail message on your behalf" warning in Outlook article.
The most probable cause is Outlook Security.
For security purposes, the HTMLBody, HTMLEditor, Body and WordEditor properties all are subject to address-information security prompts because the body of a message often contains the sender's or other people's e-mail addresses.
You can find the security configurations in HKCU\Software\Policies\Microsoft\office\16.0\outlook\security\
(change 16.0 to your office version)
There are two values that you can check, promptoomaddressbookaccess and promptoomaddressinformationaccess
Change them to 2 (or ask your system administrator), restart Outlook and try again.
More info https://support.microsoft.com/en-za/help/926512/information-for-administrators-about-e-mail-security-settings-in-outlo

Excel VBA save email after sent, only show preview email not sent email

I want to save the email in my local folder, and I saw this link
https://www.mrexcel.com/forum/excel-questions/361751-vba-saving-email-only-after-send-pushed.html
which basically use the class module to save the email after sending it out.
However the problem is, the email saved is the preview email (email that is being displayed before you send the email) instead of sent email (email in which you cannot edit anything anymore)
Dim cls_OL As New clsOutlook
Public objMail_SentMsg As Object
Public Emailpath As String
Sub SendEmail()
Dim OutMail As Object
Set cls_OL.obj_OL = CreateObject("Outlook.Application")
cls_OL.obj_OL.Session.Logon
Set OutMail = cls_OL.obj_OL.CreateItem(0)
Set objMail_SentMsg = OutMail
Emailpath = "V:\test\emailname.msg"
With OutMail
On Error Resume Next
'Assume this all strings variables are fine
.HTMLBody = strmsgContent1 & strmsgContent2
.to = ToEmail
.CC = CC
.BCC = BCC
.Subject = Subject
.Display
End With
Set OutMail = Nothing
End Sub
Option Explicit
Public WithEvents obj_OL As Outlook.Application
Private Sub obj_OL_ItemSend(ByVal Item As Object, Cancel As Boolean)
objMail_SentMsg.SaveAs Emailpath
Set obj_OL = Nothing
End Sub
It saved the email succesfully but as mentioned, only saved the preview/display email not the sent email.
Thank you so much for your help.
Instead of ItemSend monitor the SentItems folder with ItemAdd.
Do not save objMail_SentMsg, save the item identified by ItemAdd as being added to the folder.
If necessary to differentiate mail not to be saved, set up some unique characteristic in the mail when it is created.

mailitem.entryID in Excel VBA

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.

How to bring up message if email closed without sending?

I know this is very basic, but having a total mind blank right now.
I have my basic code to send an email in outlook, but I need to know the line to bring up an error or message if the person closes the email without sending.
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
'Sends email
With OutMail
.to = " someone#nowhere.com"
.Subject = " Rich Request"
.HTMLBody = "Please find attached new request" .Attachments.AddApplication.ActiveWorkbook.FullName
.Display
End With
Set OutApp = Nothing

Resources