I am trying to create a macro in a Word form where it saves the form as a PDF, attaches it to an email, then sends the email to a predefined email address while CCing the submitter so they have a copy of the form.
I have everything working except I cannot for the life of me figure out how to get it to grab the sender email address.
Here is the macro:
Private Sub CommandButton21_Click()
Dim OL As Object
Dim EmailItem As Object
Application.ScreenUpdating = False
Set OL = CreateObject("Outlook.Application")
Set EmailItem = OL.CreateItem(olMailItem)
SubmitEmail = EmailItem.SenderEmailAddress
ActiveDocument.SaveAs2 FileName:="\\folder\folder\file.pdf", FileFormat:=wdFormatPDF
With EmailItem
.Subject = "Completed Training Selection Form"
.Body = "See Attached"
.To = "submit#test.com"
.CC = SubmitEmail
.Attachments.Add "\\folder\folder\file.pdf"
.Send
End With
Application.ScreenUpdating = True
MsgBox "Form submitted. Check your email for a copy of the form."
Set OL = Nothing
Set EmailItem = Nothing
End Sub
The macro works but it does not CC anyone. I've tried so many different ways to grab the sender address from moving the code around to stepping all the way back to the account object.
I've added SubmitEmail to the body message to confirm it is blank. Is there something more I need to do since it is a Word macro and EmailItem is an Outlook object? Could computer/network permissions affect it? The email sends just fine from the sender's account but I am at a total loss right now.
Edit: I've even done .CC = .SenderEmailAddress and still nothing.
You are adding the sender email address of the message that you just created, of course SenderEmailAddress will be "" since the message has never been submitted.
Is it supposed to be the address of the current user? Try Application.Session.CurrentUser.Address.
Related
I'm trying to use Word VBA to send a document to an email recipient. For the most part, it is not difficult. I have this code so far:
With oItem
'Set the recipient for the new email
.To = "person1#mail.com"
'Set the recipient for a copy
.CC = "ccperson#mail.com"
'Set the subject
.Subject = "Blah blah"
End With
My problem is that I have several sender email addresses configured in Outlook, and Outlook is picking the wrong one by default.
Is there a way to specify a sender email address using the method above? Needless to say, the intuitive code line for specifying a sender address (.From = me#wherever.com) does not work. Thank you.
UPDATE:
I finally got my code to work after modifying it using the suggestions from peakpeak and Dimitry below. My changes were
1) to include a reference to the Microsoft Outlook 16 object library so that I could get access to the Outlook.MailItem datatype. The mail would send fine with the code above (without the reference), but would always send with the wrong From address.
2) Declare the mail item as Outlook.MailItem. This seemed to enable the SentOnBehalfOfName field.
3) Used my desired From: email address in the SentOnBehalfOfName field.
Here is the working code:
Dim MAPIMailItem As Outlook.MailItem
Set MAPIMailItem = olkApp.CreateItem(olMailItem) 'Create a new mail message
With MAPIMailItem
.BodyFormat = olFormatPlain
.to = strTo
' SentOnBehalfOfName sets the From field on my machine,
' AFTER I declared MAPIMailItem as Outlook.MailItem
.SentOnBehalfOfName = "fromAddress#foo.com"
.Subject = strSubject
.body = strBody
.attachments.Add strAtt
'.send
.Display
End With
I use this code:
Dim WantedAccount as String ' Set to preferred account name
Set MAPISession = objOutlook.Application.Session 'Get the MAPI Outlook session
Set MAPIMailItem = objOutlook.CreateItem(olMailItem) 'Create a new mail message
With MAPIMailItem
For Each Account In MAPISession.Accounts
If Account = WantedAccount Then
.SendUsingAccount = Account
Exit For
End If
Next
If you are sending through an Exchange account, set the MailItem.SentOnBehalfOfName property (assuming you have the right to send on behalf of the specified mailbox). If you are sending through a POP3/SMTP account, set the MailItem.SendUsingAccount property.
I have the following script to run, which sends out an email acknowledgement from a template to external users that contact a shared mailbox. About once or twice a week I encounter the error listed in the Title field.
Would you be able to assist in providing code that would ignore an email address it cannot resolve and, if possible, a message to notify me when this occurs?
Sorry, I set this up a couple of years ago and learned just enough to get this to work :/
Sub AutoReplywithTemplate(Item As Outlook.MailItem)
Dim oRespond As Outlook.MailItem
' Use this for a real reply
' Set oRespond = Item.Reply
' This sends a response back using a template
Set oRespond = Application.CreateItemFromTemplate("C:\Users\dannygonzales\AppData\Roaming\Microsoft\Templates\GMS Technical Support Email Acknowledgment (Default).oft")
With oRespond
.Recipients.Add Item.SenderEmailAddress
.Subject = "GMS Technical Support Acknowledgement"
.HTMLBody = vbCrLf & oRespond.HTMLBody
' includes the original message as an attachment
' .Attachments.Add Item
' use this for testing, change to .send once you have it working as desired
.Send
End With
Set oRespond = Nothing
End Sub
Use the Recipients.ResolveAll method; it will return False if there is a problem with any of the recipient's addresses. You can evaluate Recipient.Resolved for each member of the collection to determine which one is invalid.
We currently have an email automatically created by Excel using VBA, with subject, recipient, message body with template text all filled in.
Sub CreateMail(Optional sFile As String = "")
'Create email to send to requestor with attachment sFile
'Declarations
Dim app As Outlook.Application
Dim msg As Outlook.MailItem
Dim send_to As Recipient
Dim send_tos As Recipients
'Initiations
Set app = CreateObject("Outlook.Application")
Set msg = app.CreateItem(olMailItem)
Set send_tos = msg.Recipients
Set send_to = send_tos.Add("receiver#email.com")
send_to.Type = 1
'Create message
With msg
.SentOnBehalfOfName = "sender#email.com"
.Subject = "This is the email subject"
.HTMLBody = "This is the email body" & vbCrLf
'Resolve each Recipient's name.
For Each send_to In msg.Recipients
send_to.Resolve
Next
If Len(sFile) > 0 Then
.Attachments.Add sFile
End If
.Display
End With
End sub
After making some manual changes to the email that is created, we'd like to send it and have a copy saved to a folder on the file system automatically (in addition to the usual sent folder in Outlook). Is there a way to do this all within Excel VBA?
I suspect it might be possible using Outlook VBA, however the folders are defined in Excel and we'd like to keep the code together in the one file.
What is your code for sending email? This works for me in an Excel VBA module:
Dim appOutLook As Outlook.Application
Dim MailOutLook As Outlook.MailItem
Set appOutLook = CreateObject("Outlook.Application")
Set MailOutLook = appOutLook.CreateItem(olMailItem)
With MailOutLook
.BodyFormat = olFormatRichText
.To = "email address"
.Subject = "Test"
.HTMLBody = "Test " & Now
.DeleteAfterSubmit = True 'to not retain in sent folder
.Display
.SaveAs "C:\filepath\Test.txt", 0
' .Send
End With
However, guess the real trick is allowing edit of the email before saving file. So far not seeing solution for that. Unfortunately the code execution does not pause while the message window is open. I was hoping for the pause since Office is supposed to be an integrated suite of apps - like opening a form in Access in dialog mode which does pause execution of code.
With code in Excel only, monitor the SentItems folder.
Utilizing Outlook Events From Excel
Confirm the mail from a unique ID.
The unique ID could be in the subject or body.
You could try saving the unique ID in PR_SEARCH_KEY. It is the same idea How, can get the exact sent Email from Sent Items folder? and How to uniquely identify an Outlook email as MailItem.EntryID changes when email is moved
I have a large number of forwarding email addresses which are all set to forward to the same email account. I find this is useful because if a business is hacked and my email address is stolen then I only have the change the email address for that business. For example, "amazon#mydomain.com", "ebay#mydomain.com" and "facebook#mydomain.com" would all be forwarded to "mailbox#mydomain.com".
When I want to send an email to the business, I have to go into Outlook and change the account set up to have the forwarding email address as the email address. I find this a nuisance. I know I can change who the email is from when I write it, but then the recipient sees "J Smith on behalf of newaddress#mydomain.com". I would rather it just showed the address I am using in the from field, as it does if I go into the account set up and change the email address there.
It would be nice to have a macro set up which asked me which email address I wanted to use and then sent the email for me. I have looked up how to change email account details in VBA, but it looks as if the details are all read-only. Is there a way to change my "from" email address cleanly? Or even setting up a new email account in VBA and deleting it immediately after sending it?
Try creating a userform with a combobox and a button on it. Load all your available accounts into the combobox to be able to select from it:
Private Sub UserForm_Initialize()
Dim acc As Account
For Each acc In ThisOutlookSession.Session.Accounts
Me.ComboBox1.AddItem acc.UserName
Next acc
End Sub
Then add some code to the button that selects the proper account:
Dim objApp As Outlook.Application
Dim objMail As Outlook.MailItem
Set objApp = ThisOutlookSession.Application
Set objMail = objApp.CreateItem(olMailItem)
With objMail
.To = "lala#lala.com"
.CC = ""
.BCC = ""
.Subject = "Test"
.Body = "Test"
Dim i As Integer
For i = 1 To ThisOutlookSession.Session.Accounts.Count Step 1
If ThisOutlookSession.Session.Accounts.Item(i).UserName = Me.ComboBox1.Value Then
.SendUsingAccount = ThisOutlookSession.Session.Accounts.Item(i)
End If
Next i
.Display
End With
Maybe there is an event that is called when you are creating a new email, otherwise you have to add a button or something to bring the form up.
I had this exact same problem and ended up being able to solve it by installing Outlook Redemption and using the following script...
' Redemption code below. Must install Redemption to work.
' http://www.dimastr.com/redemption/faq.htm#14
Dim sItem, Tag
Set sItem = CreateObject("Redemption.SafeMailItem")
sItem.Item = oMailItem
Tag = sItem.GetIDsFromNames("{00020386-0000-0000-C000-000000000046}", "From")
Tag = Tag Or &H1E 'the type is PT_STRING8
sItem.Fields(Tag) = GetHashedReply(oMailItem)
Tag = sItem.GetIDsFromNames("{00020386-0000-0000-C000-000000000046}", "Sender")
Tag = Tag Or &H1E 'the type is PT_STRING8
sItem.Fields(Tag) = GetHashedReply(oMailItem)
sItem.Subject = sItem.Subject 'to trick Outlook into thinking that something has changed
sItem.Save
...where oMailItem is a normal Outlook MailItem that you can get with CreateItem() or get passed to you in the ItemSend() parameters.
I have a Word document (saved as a macro-enabled template) that allows a user to fill out a "time off" form using drop-down boxes. It's set up to email the supervisor an attachment with the request; however, the document saves itself when used, which could potentially reveal sensitive information to the next person viewing the form.
Would it be possible to send the document content as plain text in the body of the email (we are using Outlook) so that the document doesn't have to be saved? Or is there a function to add that will allow for the email to send and then the contents to be reset and then re-saved?
Here is my current code:
Private Sub CommandButton21_Click()
Dim OL As Object
Dim EmailItem As Object
Dim Doc As Document
Application.ScreenUpdating = False
Set OL = CreateObject("Outlook.Application")
Set EmailItem = OL.CreateItem(olMailItem)
Set Doc = ActiveDocument
Doc.Save
With EmailItem
.Subject = "TIME OFF REQUEST"
.Body = "THE ATTACHED DOCUMENT IS A DAY OFF REQUEST"
.To = "Email"
.Importance = olImportanceNormal
.Attachments.Add Doc.FullName
.Send
End
With Application.ScreenUpdating = True
Set Doc = Nothing
Set OL = Nothing
Set EmailItem = Nothing
End Sub
The Content property of the Document class returns a Range object that represents the main document story. The Text property returns the plain, unformatted text of the range. So, here is the code you are looking for:
.Body = ActiveDocument.Content.Text
Be aware, Outlook uses Word as an email editor. You can use the Word object model for manipulating the message body. You can read more about that in the Chapter 17: Working with Item Bodies .
Finally, you may find the How to automate Outlook from another program article helpful.