Excel macro to send an email generates runtime error 287 - excel

I referenced many websites and even copied and pasted code. I cannot get my Excel macro button to send an email.
When I click RunSub/Userform(play button) in VBAProject I get
runtime error 287
Sub Send_Email()
Dim MyOutlook As Object
Set MyOutlook = CreateObject("Outlook.Application")
Dim MyMail As Object
Set MyMail = MyOutlook.CreateItem(olMailItem)
MyMail.To = "notlistedpublicly"
MyMail.Subject = Range("B6") & "Has completed his Skills Matrix"
MyMail.Body = Range("B6") & "has completed his Skills Matrix. Please review"
MyMail.Send
End Sub

I have a similar code, I added some lines to from it to your code.
Sub Send_Email()
Dim MyOutlook As Object
Set MyOutlook = CreateObject("Outlook.Application")
Dim MyMail As Object
'I change this
'Set MyMail = MyOutlook.CreateItem(olMailItem)
Set MyMail = MyOutlook.CreateItem(0)
MyOutlook.Session.Logon
With MyMail
.To = "notlistedpublicly"
.Subject = Range("B6") & "Has completed his Skills Matrix"
.Body = Range("B6") & "has completed his Skills Matrix. Please review"
'Before try to see how the mail looks.
'.Send
.Display
End with
Set MyMail = Nothing
Set MyOutlook = Nothing
End Sub

Related

Sending an Email from Excel when Outlook not available using VBA

I want to send stakeholders an e-mail when a subordinate makes any updates in the Excel worksheet. I hope to use a Workbook_BeforeSave event where an e-mail is triggered from the subordinate's Outlook account.
The subordinate/user needs Outlook configured/installed in their system. If not mail wont be triggered.
Is there any way to overcome this, like sending the mail triggering request to a remote computer/server where Outlook is preconfigured and sending the mail from that computer/server to the stakeholder using a common or centralized Email id?
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
Dim OutApp As Outlook.Application
Dim objOutlookMsg As Outlook.MailItem
Dim objOutlookRecip As Recipient
Dim Recipients As Recipients
Set OutApp = CreateObject("Outlook.Application")
Set objOutlookMsg = OutApp.CreateItem(olMailItem)
Set Recipients = objOutlookMsg.Recipients
Set objOutlookRecip = Recipients.Add("receiver#domain.com")
objOutlookRecip.Type = 1
objOutlookMsg.SentOnBehalfOfName = "sender#domain.com"
objOutlookMsg.Subject = "Testing this macro"
objOutlookMsg.HTMLBody = "Testing this macro "
For Each objOutlookRecip In objOutlookMsg.Recipients
objOutlookRecip.Resolve
Next
objOutlookMsg.Display
objOutlookMsg.Send
Set OutApp = Nothing
End Sub
Option Explicit
Private Sub CommandButton1_Click()
On Error GoTo ErrHandler
' SET Outlook APPLICATION OBJECT.
Dim objOutlook As Object
Set objOutlook = CreateObject("Outlook.Application")
' CREATE EMAIL OBJECT.
Dim objEmail As Object
Set objEmail = objOutlook.CreateItem(olMailItem)
With objEmail
.to = "webadmin#encodedna.com"
.Subject = "This is a test message from Arun Banik"
.Body = "Hi there"
.Display ' DISPLAY MESSAGE.
End With
' CLEAR.
Set objEmail = Nothing: Set objOutlook = Nothing
ErrHandler:
'
End Sub
All you need to do is change the .Display property with .Send property.
With objEmail
.to = "arunbanik21#rediffmail.com"
.Subject = "This is a test message from Arun"
.Body = "Hi there"
.Send ' SEND THE MESSAGE.
End With
For more please check here, https://www.encodedna.com/excel/send-email-from-excel-using-vba-and-outlook.htm
Follow the steps,
We need to send emails from Outlook. Since Outlook is an outside object first thing we need to do is to set the object reference to “Microsoft Outlook 16.0 Object Library”.
In VBA, Go to Tools > References.
Now we will see the object reference library. In this window, we need to set the reference to “Microsoft Outlook 16.0 Object Library.”
After setting the object reference, click on, Ok.
Now we can access Outlook object in VBA coding
Sub SendEmail_Example1()
Dim EmailApp As Outlook.Application 'To refer to outlook application
Set EmailApp = New Outlook.Application 'To launch outlook application
Dim EmailItem As Outlook.MailItem 'To refer new outlook email
Set EmailItem = EmailApp.CreateItem(olMailItem) 'To launch new outlook
email
EmailItem.To = "Hi#gmail.com"
EmailItem.CC = "hello#gmail.com"
EmailItem.Subject = "Test Email From Excel VBA"
EmailItem.HTMLBody = "Hi," & vbNewLine & vbNewLine & "This is my first email from Excel" & _
vbNewLine & vbNewLine & _
"Regards," & vbNewLine & _
"VBA Coder" 'VbNewLine is the VBA Constant to insert a new line
EmailItem.Send
End Sub
For more, can you please give a try as mentioned in this article,
https://www.wallstreetmojo.com/vba-send-email-from-excel/

How do I reply to outlook mail using vba in excel with mail thread?

I am looking for VBA code in excel to reply to a selected mail but the below code creates seperate mail which does not have previous messages in conversation (thread) in body. I searched online, but most of them are old codes which are not working currently. Please help.
Sub Test_template()
Dim emailApplication As Object
Dim emailItem As Object
Set emailApplication = CreateObject("Outlook.Application")
Set emailItem = emailApplication.ActiveExplorer.Selection.Item(1).ReplyAll
emailItem.bcc = "XYZ.com"
emailItem.Body = "Hi, have a nice day "
emailItem.Display
Set emailItem = Nothing
Set emailApplication = Nothing
End Sub
Is this what you are trying? I have commented the code and provided relevant MSDN links. If you still get stuck then simply ask.
Option Explicit
Sub Sample()
Dim OutlookApp As Object
Dim OutlookMail As Object
Set OutlookApp = CreateObject("Outlook.Application")
Set OutlookMail = OutlookApp.ActiveExplorer.Selection.Item(1)
'~~> Get MailItem.GetConversation method (Outlook)
' https://learn.microsoft.com/en-us/office/vba/api/outlook.mailitem.getconversation
Dim OutlookConversation As Object
Set OutlookConversation = OutlookMail.GetConversation
'~~> Conversation.GetTable method (Outlook)
' https://learn.microsoft.com/en-us/office/vba/api/outlook.conversation.gettable
Dim OutlookTable As Object
Set OutlookTable = OutlookConversation.GetTable
'~~> Obtains a 2D array from the Table.
' https://learn.microsoft.com/en-us/office/vba/api/outlook.table.getarray
Dim OutlookAr As Variant
OutlookAr = OutlookTable.GetArray(OutlookTable.GetRowCount)
Dim OutlookReplyToThisMail As Object
Set OutlookReplyToThisMail = OutlookMail.Session.GetItemFromID(OutlookAr(UBound(OutlookAr), 0))
Dim MyMessage As String: MyMessage = "Hi, have a nice day "
With OutlookReplyToThisMail.ReplyAll
.BCC = "XYZ.com"
.HTMLBody = MyMessage & .HTMLBody
.Display
End With
End Sub
.ReplyAll produces the expected result but is overwritten by emailItem.Body = "Hi, have a nice day ".
Option Explicit
Sub Test_template()
Dim emailApplication As Object
Dim emailItem As Object
'Set emailApplication = CreateObject("Outlook.Application")
' mail has to be slelected in Outlook application so it has to be open already
Set emailApplication = GetObject(, "Outlook.Application")
Set emailItem = emailApplication.ActiveExplorer.Selection.Item(1).ReplyAll
emailItem.BCC = "XYZ.com"
'emailItem.Body = "Hi, have a nice day "
emailItem.Body = "Hi, have a nice day " & emailItem.Body
' or
'emailItem.htmlBody = "Hi, have a nice day " & emailItem.htmlBody
emailItem.Display
Set emailItem = Nothing
Set emailApplication = Nothing
End Sub

How to send email from a specific Outlook account using Excel?

I have code that sends emails using the default Outlook account.
I tried changing the code to send from a specific email. When I run the macro, nothing happens.
Is something wrong with the code, or is it not working due to another issue (with Outlook and the accounts/permissions associated with it)?
Sub CommandButton1_Click()
Dim wb As Workbook
Dim olApp As Outlook.Application
Dim olMail As Outlook.MailItem
Dim q As Long
Dim oAccount As Outlook.Account
Set wb = ThisWorkbook
For Each oAccount In Outlook.Application.Session.Accounts
If oAccount = "theEmailiWantToUse#domain.com" Then
For q = 2 To 3 'LastRow
eName = wb.Sheets(1).Cells(q, 2).Value
Set olApp = New Outlook.Application
Set olMail = olApp.CreateItem(olMailItem)
mailBody = "Hello, "
With olMail
.To = Worksheets("Emails").Cells(q, 4).Value
.Subject = eName
.HTMLBody = "<!DOCTYPE html><html><head><style>"
.HTMLBody = .HTMLBody & "body{font-family: Calibri, ""Times New Roman"", sans-serif; font-size: 14px}"
.HTMLBody = .HTMLBody & "</style></head><body>"
.HTMLBody = .HTMLBody & mailBody & "</body></html>"
Set .SendUsingAccount = oAccount
.Display
' .Send
End With
Next
Else
End If
Next
Set olMail = Nothing
Set olApp = Nothing
End Sub
I know I have access to the email I would like to send emails from, as I can select it from Outlook and it works.
Add this line within the olMail
.SentOnBehalfOfName = "youraddress" 'here change this
please use this routine to find Account number of sender .
Sub Which_Account_Number()
'Don't forget to set a reference to Outlook in the VBA editor
Dim OutApp As Outlook.Application
Dim I As Long
Set OutApp = CreateObject("Outlook.Application")
For I = 1 To OutApp.Session.Accounts.Count
MsgBox OutApp.Session.Accounts.Item(I) & " : This is account number " & I
Next I
End Sub
Then
.SendUsingAccount = olApp.Session.Accounts.Item(5)' whatever account index number you want to send. i have chosen 5
instead of
Set .SendUsingAccount = oAccount
This method works for me . You can further integrate this concept in your programme. Please ensure Reference to Outlook Object Library is set in Tools/References.

Make Outlook Task item through Excel Button

I want to make a simple program in which I can create an Outlook Task. User fills in data and clicks the create button.
I found the following code online and it should work, but it doesn't. No task is added in my Outlook, but no error is shown either. I have the feeling it somehow goes wrong with adding the recipients of the task.
Any clue why I don't get an error but, no tasks are added?
Dim OutApp As Outlook.Application
Dim OutTask As Outlook.TaskItem
Set OutApp = CreateObject("Outlook.Application")
Set OutTask = OutApp.CreateItem(olTaskItem)
Set myRecipient = OutTask.Recipients.Add("I.wont.write.my.actual.address.in.this#example.com")
myRecipient.Type = olTo
If myRecipient.Resolved Then
With OutTask
.Display
.Subject = Cells(3, "I")
.StartDate = Now
.DueDate = Cells(2, "I")
.Body = "Please see the attached email for a service request assigned to you."
End With
End If
Set OutTask = Nothing
Set OutApp = Nothing
I just can't figure it out and it's really breaking my brain at the moment. Hope someone can hint me in the right direction!
I found the following code online and it should work, but it doesn't. No task is added in my Outlook, but no error is shown either. I have the feeling it somehow goes wrong with adding the recipients of the task.
Correct - Attempt to resolve the Recipient object myRecipient.Resolve against the Address Book before assuming its resolved If myRecipient.Resolved Then also defined variable Dim myRecipient As Outlook.Recipient for myRecipient
Option Explicit
Sub tasks()
Dim OutApp As Outlook.Application
Set OutApp = CreateObject("Outlook.Application")
Dim OutTask As Outlook.TaskItem
Set OutTask = OutApp.CreateItem(olTaskItem)
Dim myRecipient As Outlook.Recipient
Set myRecipient = OutTask.Recipients.Add("0m3r#Email.com")
myRecipient.Type = olTo
myRecipient.Resolve
If myRecipient.Resolved Then
With OutTask
.Display
.Subject = Cells(3, "I")
.StartDate = Now
.DueDate = Cells(2, "I")
.Body = "Please see the attached email."
End With
End If
Set OutTask = Nothing
Set OutApp = Nothing
End Sub
Option Explicit Statement (Visual Basic)
Forces explicit declaration of all variables in a file, or allows implicit declarations of variables.
Check this examples, run each one and see if they are usefull to you, hope one fit your needs:
Sub outlook_send_followup()
' High importance = 2
' Nothing = 1
' Low importance = 0
Dim OutApp As Object
Set OutApp = CreateObject("Outlook.Application")
Dim MyItem As Object
Set MyItem = OutApp.CreateItem(olMailItem)
With MyItem
.To = "example#hotmail.com"
.Subject = "hi, this is a task"
.SentOnBehalfOfName = "example#hotmail.com"
.HTMLBody = "<HTML MSG FORMAT HERE>"
.Importance = 1
.FlagStatus = olFlagMarked
.FlagRequest = "Follow up"
.FlagDueBy = Now
.Display
End With
Set MyItem = Nothing
Set OutApp = Nothing
End Sub
Sub create_outlook_taks()
'Const olImportanceLow = 0
'Const olImportanceNormal = 1
'Const olImportanceHigh = 2
Dim outlook_app As Object
Set outlook_app = CreateObject("Outlook.Application")
With outlook_app.CreateItem(3)
.Importance = 2
.Subject = "THIS IS A TASK"
.StartDate = Now + 5
.DueDate = Now + 10
.ReminderTime = Now - 3
.Body = "HI YOU CREATED THIS TASK"
.Display
'.Save
End With
Set outlook_app = Nothing
End Sub

Send mail through Outlook - Error 287

I am trying to loop through a set of worksheets, save each of them as a separate workbook, and then send them as attachment by mail.
However when running the below code, I end up with error 287 triggered by .Send. I have outlook open, so that is not the problem. If I change .Send to .Display, the mails are generated as drafts as displayed properly with the correct sheet attached.
Sub SendWorksheetsByMail()
Dim wb As Workbook
Dim destinationWb As Workbook
Dim OutApp As Outlook.Application
Dim OutMail As Outlook.MailItem
Set wb = Workbooks("Test.xlsm")
Application.EnableEvents = False
Application.ScreenUpdating = False
For Each ws In wb.Worksheets
'Ignore Summary and Config
If ws.Name <> "Summary" And ws.Name <> "Config" Then
'On Error Resume Next
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(olMailItem)
ws.Copy
Set destinationWb = ActiveWorkbook
destinationWb.SaveAs "C:\****************\" & ws.Name & ".xlsx", FileFormat:=51
With OutMail
.To = "*******************"
.Subject = "Test"
.Body = "Test"
.Attachments.Add destinationWb.FullName
.Send
End With
Set OutMail = Nothing
Set OutApp = Nothing
End If
Next ws
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub
Edit: "It also fails even without an attachment. Essentially generating a message containing only the subject and text "test"."
Any suggestions for how to solve this? It would save a lot of time to not have to click Send for each individual mail, as the number of mails to send could potentially become quite large.
This is what I used to send a mail with attachment to multiple addresses, listed in column H while the name of the receiver is listed in another column
Sub Mail()
'####################################
'### Save the file as pdf ######
'####################################
Dim FSO As Object
Dim s(1) As String
Dim sNewFilePath As String
Set FSO = CreateObject("Scripting.FileSystemObject")
s(0) = ThisWorkbook.FullName
If FSO.FileExists(s(0)) Then
'//Change Excel Extension to PDF extension in FilePath
s(1) = FSO.GetExtensionName(s(0))
If s(1) <> "" Then
s(1) = "." & s(1)
sNewFilePath = Replace(s(0), s(1), ".pdf")
'//Export to PDF with new File Path
ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:=sNewFilePath, Quality:=xlQualityStandard, IncludeDocProperties:=True, IgnorePrintAreas:=False, OpenAfterPublish:=False
End If
Else
'//Error: file path not found
MsgBox "Error: this workbook may be unsaved. Please save and try again."
End If
Set FSO = Nothing
'##########################################
'### Attach the file and mail it ######
'##########################################
Dim OutApp As Object
Dim OutMail As Object
Dim sh As Worksheet
Dim cell As Range
Dim FileCell As Range
Dim rng As Range
With Application
.EnableEvents = False
.ScreenUpdating = False
End With
Set sh = Sheets("sheet")
Set OutApp = CreateObject("Outlook.Application")
For Each cell In sh.Columns("H").Cells.SpecialCells(xlCellTypeConstants)
If cell.Value Like "?*#?*.?*" Then
Set OutMail = OutApp.CreateItem(0)
With OutMail
.to = cell.Value
.Subject = "file delivery "
.Body = "Hi " & cell.Offset(0, -3).Value & " here is my file"
.Attachments.Add sNewFilePath
.Send 'Or use .Display
End With
Set OutMail = Nothing
End If
Next cell
Set OutApp = Nothing
With Application
.EnableEvents = True
.ScreenUpdating = True
End With
End Sub
Try .GetInspector before .Send. It would be like .Display without displaying.
I found a two step soultion. By changing .Send to .Display in the code above, the messages will be created as drafts in outlook and Displayed. If you do not want an extra window per e-mail, changing .Display to .Save will just put them in the draft folder.
Then I can use a macro written in Outlook to send all drafts. Code based on solution found at the mrexcel forums.
I also discovered after reading this answer on SO that the drafts folder can not be selected when running the macro.
Hope this helps others running into the same problem.
Public Sub SendDrafts()
Dim lDraftItem As Long
Dim myOutlook As Outlook.Application
Dim myNameSpace As Outlook.NameSpace
Dim myFolders As Outlook.Folders
Dim myDraftsFolder As Outlook.MAPIFolder
'Send all items in the "Drafts" folder that have a "To" address filled in.
'Setup Outlook
Set myOutlook = Outlook.Application
Set myNameSpace = myOutlook.GetNamespace("MAPI")
Set myFolders = myNameSpace.Folders
'Set Draft Folder.
Set myDraftsFolder = myFolders("*******#****.com").Folders("Drafts")
'Loop through all Draft Items
For lDraftItem = myDraftsFolder.Items.Count To 1 Step -1
'Check for "To" address and only send if "To" is filled in.
If Len(Trim(myDraftsFolder.Items.Item(lDraftItem).To)) > 0 Then
'Send Item
myDraftsFolder.Items.Item(lDraftItem).Send
End If
Next lDraftItem
'Clean-up
Set myDraftsFolder = Nothing
Set myNameSpace = Nothing
Set myOutlook = Nothing
End Sub
Might be a good idea to add code that differntiates the messages you are trying to send from other drafts that may already be in the folder.
Would still prefere a one step solution, so I will wait with marking this as a solution.
I finally found the answer googling a lot.
The problem is not with the .send method, but rather the session object.
Replace Set myOutlook = Outlook.Application with
Set objOutlook = ThisOutlookSession
This ensures that your macro is using the same outlook session that is open. Atleast it did the trick for me

Resources