How to send outlook email automatically using Excel UserForm? - vba

Thanks for any help with this. I have a userform I've made that gathers criteria from the user and then when they hit submit it opens Outlook and emails that data to me.
I'm having 2 issues. The first is that when I try to use SENDKEYS method I'm running into the spell check feature stopping the email from actually sending without the user needing to go through it. Is there a way to bypass spell check and send the email?
Secondly, I couldn't find a way to actual send an email automatically without using SENDKEYS but I'm sure there is a better way out there to send the email rather than manipulating the window with TAB key strokes.
Private Sub SubmitButton_Click()
Dim OutApp As Object
Dim OutMail As Object
Dim strBody, RequestName, ProductName, Month, TestName, Summary As String
If Me.RequesterNameTxt.Value <> "" And Me.ProductCombo.Value <> "" And Me.MonthCombo.Value <> "" And Me.TestNameCombo <> "" Then
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
RequestName = Me.RequesterNameTxt.Value
ProductName = Me.ProductCombo.Value
Month = Me.MonthCombo.Value
TestName = Me.TestNameCombo.Value
Summary = Me.SummaryTxt.Value
strBody = "<HTML><BODY>"
strBody = "Requester Name: " & RequestName & "<BR>" & "Product Name: " & ProductName & "<BR>" & "Month: " & Month & "<BR>" & _
"Test Name: " & TestName & "<BR>" & "<BR>" & "Summary of Request: " & Summary
strBody = strBody & "</BODY></HTML>"
On Error Resume Next
With OutMail
.To = "example#gmail.com;"
.CC = ""
.bcc = ""
.Subject = "QA Service Request"
.htmlBody = strBody
.send 'This fixed my issue. I had this as .Display which opens email up and doesn't send
End With
On Error GoTo 0
Set OutMail = Nothing
Set OutApp = Nothing
Application.SendKeys ("%s")
Else: MsgBox "Please fill out all form data before submitting request. Thank you!"
End If
End Sub

You need to use the Send method of Outlook items instead. The Send method sends an item using the default account specified for the session. In a session where multiple Microsoft Exchange accounts are defined in the profile, the first Exchange account added to the profile is the primary Exchange account, and is also the default account for the session. To specify a different account to send an item, set the SendUsingAccount property to the desired Account object and then call the Send method.
Also I'd recommend using the Recipients property for adding recipients instead. The property returns a Recipients collection that represents all the recipients for the Outlook item.

Related

How to send from a shared non-Exchange account?

How can I change the .sentonbehalfofname property?
We changed shared mailbox from Exchange to normal account. Mailbox added to Outlook as a normal account.
With the following code I get:
"This message could not be sent. You do not have the permission to send the message on behalf of the specified user."
' Construct email
Set OutMail = OutApp.CreateItem(0)
With OutMail
.SentOnBehalfOfName = "bbb#aaa.com"
.BodyFormat = 2
Set editor = .GetInspector.WordEditor
editor.Content.Paste
.To = currentEmailAddress
.Subject = emailTitle & " ID:" & Range(teamMemberIDColumn & cell.Row).Value
.Display
.Send
Try this
'Construct email
Set OutMail = OutApp.CreateItem(0)
With OutMail
.SendUsingAccount = Application.Session.Accounts("bbb#aaa.com")
.BodyFormat = 2
Set editor = .GetInspector.WordEditor
editor.Content.Paste
.To = currentEmailAddress
.Subject = emailTitle & " ID:" & Range(teamMemberIDColumn & cell.Row).Value
.Display
.Send
Please note the account of bbb#aaa.com must be added and configured in your outlook for this to work.
According to the error message, you don't have permissions to send on behalf of another person. You must contact your Exchange administrator to grant such permissions.
Another possible way to send as another person is to use the MailItem.SendUsingAccount property which sets an Account object that represents the account under which the MailItem is to be sent. In that case, you need to configure the other account in the
Outlook profile. Here is the sample use case scenario:
OutMail.SendUsingAccount = Application.Session.Accounts(1)

How to include sender's details in email body?

I have a macro in MS Word which:
Creates an Outlook email on the click of a button
Attaches the Word document to the Outlook email
I want to include the sender's details (name, email address, etc.) in the body of the email.
Dim Outlook_Object As Object
Dim Email_Object As Object
Dim This_document As Document
Application.ScreenUpdating = False
Set Outlook_Object = CreateObject("Outlook.Application")
Set Email_Object = Outlook_Object.CreateItem(olMailItem)
Set This_document = ActiveDocument
This_document.Save
With Email_Object
.Subject = "REPORT REQUEST FORM"
.Body = "This is a test email."
.To = "john.smith#gmail.com"
.Importance = olImportanceNormal
.Attachments.Add This_document.FullName
.Display
End With
Set This_document = Nothing
Set Email_Object = Nothing
Set Outlook_Object = Nothing
Application.ScreenUpdating = True
You can use the NameSpace.CurrentUser property which returns the display name of the currently logged-on user as a Recipient object. The Recipient.AddressEntry property returns the AddressEntry object corresponding to the resolved recipient. Then you can get the Name and Address properties like shown below:
Dim ns as Outlook.NameSpace
Set ns = OutlookApplication.GetNamespace("MAPI")
' to get the email address of the sender
ns.CurrentUser.AddressEntry.Address
' to get the name
ns.CurrentUser.AddressEntry.Name
To include this information to the message body you can use the Body or HTMLBody properties.
Ended up using WScript.Network
Function GetUserFullName() As String
Dim WSHnet, UserName, UserDomain, objUser
Set WSHnet = CreateObject("WScript.Network")
UserName = WSHnet.UserName
UserDomain = WSHnet.UserDomain
Set objUser = GetObject("WinNT://" & UserDomain & "/" & UserName & ",user")
GetUserFullName = objUser.FullName
End Function
Also, instead of using .body, I used .HTMLbody for the email message body [where I invoked GetUserFullName()]
.HTMLbody = "Request submitted by:" & "<br>" & GetUserFullName()

Is there a way to create a new Outlook email from Access 2002 without using the SendObject command?

I have a client that is using Access 2002 because it allows Replication. He is using this on Windows 10 with Outlook from Office 365.
The goal is to create a new email with all of the info filled in and attach a scanned proposal so that my client can review the email, make any changes that he wants and then send it.
In Access, the SendObject command creates and opens a plain text email and while this email is open my Outlook macro to scan a document and attach it to the email will not run.
So I would like to create a new Outlook email from Access that allows me to run my Outlook macro.
Or if I could get Access 2002 to create an email and attach the scanned document to it, I think I could get by with using msgboxes to verify specific items.
Below is the Access macro with the SendObject command followed by the Outlook macro.
Private Sub EmailProposal_Click()
'Access macro.
Dim stDocName As String
Dim stEmailAddress As String
Dim stSubject As String
Dim stMessage As String
stDocName = "rptProposal"
stEmailAddress = Forms!RequestForm!EmailAddress.Value
stSubject = "PROPOSAL"
stMessage = "Your proposal is attached." & vbCrLf & vbCrLf & "If you have any questions, please call us."
'Email the proposal.
DoCmd.SendObject acReport, stDocName, acFormatRTF, stEmailAddress, , , stSubject, stMessage
End Sub
Sub Scan()
'Outlook macro.
Dim myItem As Outlook.MailItem
Dim myAttachments As Outlook.Attachments
On Error Resume Next
Dim objCommonDialog As WIA.CommonDialog
Dim objImage As WIA.ImageFile
Dim strPath As String
Set objCommonDialog = New WIA.CommonDialog
'This shows the dialog box. I'd rather tell it what to do instead of having to manually choose each time.
Set objImage = objCommonDialog.ShowAcquireImage
strPath = Environ("TEMP") & "\TempScan.jpg" 'Save the scan.
If Not objImage Is Nothing Then
objImage.SaveFile strPath ' save into temp file
On Error GoTo ErrHandler
If TypeName(ActiveWindow) = "Inspector" Then
If ActiveInspector.IsWordMail And ActiveInspector.EditorType = olEditorWord Then
ActiveInspector.WordEditor.Application.Selection.Inlineshapes.AddPicture strPath 'Insert into email. I want to attach it instead.
End If
End If
Kill strPath
Else
MsgBox "The Scan macro in Outlook did not find a document." & vbCrLf & vbCrLf & _
"Please place the proposal in the printer so it can be scanned.", vbOKOnly
End If
lbl_Exit:
Set objImage = Nothing
Set objCommonDialog = Nothing
Exit Sub
ErrHandler:
Beep
Resume lbl_Exit
End Sub
It seems you just need to automate Outlook for sending out emails with the required content set up. Take a look at the following articles that give you the basics of Outlook automation:
Automating Outlook from a Visual Basic Application
Automating Outlook from Other Office Applications
Sub Send_Mail_Outlook()
Dim OutApp As Object
Dim OutMail As Object
Dim strbody As String
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
strbody = "Hi there" & vbNewLine & vbNewLine & _
"This is line 1" & vbNewLine & _
"This is line 2" & vbNewLine & _
"This is line 3" & vbNewLine & _
"This is line 4"
On Error Resume Next
With OutMail
.To = "eugene#astafiev.com"
.CC = ""
.BCC = ""
.Subject = "This is the Subject line"
.Body = strbody
'You can add a file like this
'.Attachments.Add ("C:\test.txt")
.Send 'or use .Display
End With
On Error GoTo 0
Set OutMail = Nothing
Set OutApp = Nothing
End Sub

Automation email in Excel

I am trying to design an excel file that will help my company with recruitment.
The task is to create a sheet for candidates that the company speaks to, we will record all the records for the candidates including their first name, last name, mobile and email address. You can see a screenshot of how everything looks here: https://imgur.com/gallery/tvAIx
As you can see there are columns for when the company speaks to the candidate and when he sends his CV to us. At the end there is also a "CV reminders" column. It has the following code =IF(ISBLANK(F2), HYPERLINK("mailto:" & D2 & "?subject=" & $O$3 & "&body=" & $P$3, "Send reminder"), "All good")
The idea is so that if CV has not been received yet, you can press the cell and it will generate a reminder email for the candidate. I want to make all the process autonomous so that it can pick out the candidate name from the relevant cell and send him a generic email like:
"Hi name from cell,
Hope you are well.
We have spoken with you on date from cell. Have you had a chance to review your CV yet? Do you have any questions?"
I am sure it is possible with VBA just don't know how. Thank you.
You should be able to handle basic VBA usage in order to achieve this.
Below is the VBA code that sends an Outlook e-mail message for Office 2000-2016. Source is http://www.rondebruin.nl
You may put the code in the SelectionChange event of the requested cell(s) and change the Body, SendTo etc. portions according to your needs. (Appearently in your case, SendTo address and some parts of Body will come from particular cells on the row of your selected cell)
Sub Mail_small_Text_Outlook()
'For Tips see: http://www.rondebruin.nl/win/winmail/Outlook/tips.htm
'Working in Office 2000-2016
Dim OutApp As Object
Dim OutMail As Object
Dim strbody As String
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
strbody = "Hi there" & vbNewLine & vbNewLine & _
"This is line 1" & vbNewLine & _
"This is line 2" & vbNewLine & _
"This is line 3" & vbNewLine & _
"This is line 4"
On Error Resume Next
With OutMail
.To = "ron#debruin.nl"
.CC = ""
.BCC = ""
.Subject = "This is the Subject line"
.Body = strbody
'You can add a file like this
'.Attachments.Add ("C:\test.txt")
.Send 'or use .Display
End With
On Error GoTo 0
Set OutMail = Nothing
Set OutApp = Nothing
End Sub

Refer to inbox of second account

I'm trying to look through a specific inbox for unread e-mails with .pdf files attached to them, and then save them into a specific folder.
I need to look through the inbox of certain account profile. My code only works if there is just one Inbox folder and one account profile.
Let's say I have two profiles;
One is xxxx#hotmail.com
The second zzzz#hotmail.com
How do I run the code on the Inbox of the second account?
(zzzz#hotmail.com)
The following is the code that I have so far;
Sub GetAttachments()
On Error GoTo GetAttachments_err
Dim ns As NameSpace
Dim Inbox As MAPIFolder
Dim Item As Object
Dim Atmt As Attachment
Dim FileName As String
Dim varResponse As VbMsgBoxResult
Set ns = GetNamespace("MAPI")
Set Inbox = ns.GetDefaultFolder(olFolderInbox)
i = 0
' Checks inbox for messages.
If Inbox.Items.Count = 0 Then
MsgBox "There are no messages in your Inbox.", vbInformation, _
"Nothing found"
Exit Sub
End If
' Checks inbox for unread messages.
If Inbox.UnReadItemCount = 0 Then
"Nothing found"
Exit Sub
End If
' Checks for unread messages with .pdf files attached to them, if yes then saves it to specific folder. _
Puts date and time from when the mail was created infront of the filename.
For Each Item In Inbox.Items
For Each Atmt In Item.Attachments
If Item.UnRead = True Then
If Right(Atmt.FileName, 3) = "pdf" Then
FileName = "C:\Users\XXX\Documents\Office Macro\" & _
Format(Item.CreationTime, "yyyymmdd_hhnnss_") & Atmt.FileName
Atmt.SaveAsFile FileName
i = i + 1
End If
End If
Next Atmt
Next Item
' Shows how many attached files there are if any are found.
If i > 0 Then
& vbCrLf & "Jag har sparat dem till C:\Users\XXX\Documents\Office Macro folder." _
& vbCrLf & vbCrLf & "Would you like to see your files?" _
vbQuestion + vbYesNo, "Finished!")
If varResponse = vbYes Then
Shell "Explorer.exe /e,C:\Users\XXX\Documents\Office Macro\", vbNormalFocus
End If
Else
MsgBox "No attached files could be found.", vbInformation, _
"Finished!"
End If
GetAttachments_exit:
Set Atmt = Nothing
Set Item = Nothing
Set ns = Nothing
Exit Sub
GetAttachments_err:
MsgBox "An unkown ghost spooked the program." _
& vbCrLf & "Please note and report the following information." _
& vbCrLf & "Macro Name: GetAttachments" _
& vbCrLf & "Error Number: " & Err.Number _
& vbCrLf & "Error Description: " & Err.Description _
, vbCritical, "Error!"
Resume GetAttachments_exit
Exit Sub
End Sub
After further inspection of the mailboxes I see that there are some differences:
xxxx#hotmail.com is of the type "IMAP/SMTP"
zzzz#hotmail.com is of the type "Exchange ActiveSync"
I've also noticed that that the account ID I would need to use is 4, as seen in this code when sending a new message with a test-macro specifying what profile you want to send the mail from by assigning profile ID in the script:
Sub Mail_small_Text_Change_Account()
'Only working in Office 2007-2013
'Don't forget to set a reference to Outlook in the VBA editor
Dim OutApp As Outlook.Application
Dim OutMail As Outlook.MailItem
Dim strbody As String
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(olMailItem)
strbody = "Hi there" & vbNewLine & vbNewLine & _
"This is line 1" & vbNewLine & _
"This is line 2" & vbNewLine & _
"This is line 3" & vbNewLine & _
"This is line 4"
On Error Resume Next
With OutMail
.To = "blabla#blabla.nl"
.CC = ""
.BCC = ""
.Subject = "This is the Subject line"
.Body = strbody
'SendUsingAccount is new in Office 2007
'Change Item(1)to the account number that you want to use
.SendUsingAccount = OutApp.Session.Accounts.Item(4) <<<< ACCOUNT ID
.Send 'or use .Display
End With
On Error GoTo 0
Set OutMail = Nothing
Set OutApp = Nothing
End Sub
Set Inbox = ns.GetDefaultFolder(olFolderInbox)
You get only the delivery store's inbox folder to find the items.
The Stores property of the Namespace class returns a Stores collection object that represents all the Store objects in the current profile. You can find the required store and then use the GetDefaultFolder method of the Store class instead. This method is similar to the GetDefaultFolder method of the NameSpace object. The difference is that this method gets the default folder on the delivery store that is associated with the account, whereas NameSpace.GetDefaultFolder returns the default folder on the default store for the current profile.
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(olMailItem)
There is no need to create a new Outlook Application instance in Outlook VBA.
The Outlook object model provides the Find/FindNext or Restrict methods of the Items class. Also you may find the AdvancedSearch method of the Application class helpful.