Change account settings in Outlook 2010 using VBA - vba

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.

Related

Extract SMTP address from Outlook Nickname

I would like to display a message when sending to an external address. I used various stack overflow questions to create the VBA below. I use Office 365.
I found that a recipient which Outlook has assigned as an Outlook nickname does not resolve with an SMTP address.
Instead, the Recipients.Item(i).Address attribute resolves to something like
/o=NT5/ou=00000000000000000000000000000000/cn=122E0E7203FE4F448EC35B53EE8523A4
from which I am unable to extract the SMTP address. I need to check if this recipient is an external recipient.
I tried using the Recipients.Item(i).Name attribute (which just includes the first part of the address before the #) and attempted to resolve this using Session.CreateRecipient, but this fails. I also tried the same with the Recipients.Item(i).Address attribute.
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean)
Dim xMailItem As Outlook.MailItem
Dim xRecipients As Outlook.Recipients
Dim i As Long
Dim xRecipientAddress As String
Dim xExternal As Integer
On Error Resume Next
xExternal = 0
If Item.Class <> olMail Then
Exit Sub
End If
Set xMailItem = Item
Set xRecipients = xMailItem.Recipients
For i = xRecipients.Count To 1 Step -1
xRecipientAddress = xRecipients.Item(i).Address
If Left(xRecipientAddress, 1) <> "/" Then
'external address
If InStrRev(LCase(xRecipientAddress), "#email.domain") = 0 Then
'Any other SMTP Email domain
xExternal = 1
End If
Else
'catch for outlook nickname cache
If Left(xRecipientAddress, 6) = "/o=NT5" Then
'Code to get SMTP address from outlook nickname
End If
End If
Next
Note the #email.domain is updated in my code to our SMTP domain name
The code should assign xExternal = 1 if any external recipients are found in the recipients list. This should include any recipients Outlook has created an Outlook Nickname for and those with just SMTP addresses.
Use:
If Left(xRecipientAddress, 6) = "/o=NT5" Then
Debug.Print xRecipients.Item(i).AddressEntry.GetExchangeUser.PrimarySmtpAddress
End If
Also, i don't think /0=NT5 will be consistent, so might want to change that.

How to set Outlook From email address from Word VBA

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.

Edit, send and save email to file system

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

QTP, send mailer address

I am sending an email using the QTP outlook object model.
Here is the piece of code.
'Create an object of type Outlook
Set objOutlook = CreateObject("Outlook.Application")
Set myMail = objOutlook.CreateItem(0)
'Set the email properties
myMail.To = "some_mail_id#gmail.com"
myMail.CC = "some_mail_id_2#gmail.com; some_other_mail#yahoo.com" 'Sending mails to multiple ids
myMail.BCC = "" 'If BCC is not required, then this line can be omitted
myMail.Subject = "Sending mail from MS Outlook using QTP"
myMail.Body= "Test Mail Contents"
myMail.Attachments.Add("D:\Attachment.txt") 'Path of the file to be attached
'Send the mail
myMail.Send
Now I needed to retrieve the sender email address & store it in an environment variable. myMail.Sender or myMail.sendermailaddres both of them are not working me.
The following code will give you the first email address the user you're connected to Outlook has access to:
objOutlook.Session.Accounts.Item(0)
I use a loop to find the account I want to send from like this:
iAccount = 0
For iLoop = 1 To oOutlook.Session.Accounts.Count
If UCase(Trim(oOutlook.Session.Accounts.Item(iLoop))) = UCase(Trim(EmailData("SendFrom"))) Then
iAccount = iLoop
Exit For
End If
Next
where EmailData is a Dictionary object containing the items I'm using for the mail item. When creating the mail item I use Set oMailItem.SendUsingAccount = oOutlook.Session.Accounts.Item(iAccount) to specify the account it should be sent from.

Always CC when sending "On Behalf Of"

I often send emails on behalf of another user. I'd like to use VBA to automatically CC that user every time I send an email from/on behalf of that user.
I'm not familiar with VBA for Outlook but I'm thinking you could write an if statement that says "if sending message from UserX, cc UserX". The code should run automatically any time an email is sent on behalf.
SentOnBehalfOfName is tricky. It is usually empty until the item has been sent.
With this code in ThisOutlookSession you should find it blank.
Private Sub Application_ItemSend(ByVal item As Object, Cancel As Boolean)
Dim myRecipient As Recipient
Debug.Print " item.SentOnBehalfOfName - " & item.SentOnBehalfOfName
If item.SentOnBehalfOfName = "someone#somewhere.com" Then
Set myRecipient = item.Recipients.Add("Someone Else")
myRecipient.Type = olCC
item.Recipients.ResolveAll
End If
End Sub
At least one way to get around this:
Sub createSentOnBehalf()
Dim objMsg As mailitem
Set objMsg = Application.CreateItem(olMailItem)
objMsg.SentOnBehalfOfName = "someone#somewhere.com"
objMsg.Display
Set objMsg = Nothing
End Sub
Sub replySentOnBehalf()
Dim objMsg As mailitem
Set objMsg = ActiveInspector.currentItem.reply
objMsg.SentOnBehalfOfName = "someone#somewhere.com"
objMsg.Display
Set objMsg = Nothing
End Sub
Edit: Just realized you could set the cc while creating / replying rather than waiting until ItemSend.
Edit2: Move the cc code from itemsend
Sub createSentOnBehalf()
Dim objMsg As mailitem
Dim myRecipient As Recipient
Set objMsg = Application.CreateItem(olMailItem)
objMsg.SentOnBehalfOfName = "someone#somewhere.com"
Set myRecipient = objMsg.Recipients.Add("Someone Else")
myRecipient.Type = olCC
objMsg.Recipients.ResolveAll
objMsg.Display
Set objMsg = Nothing
End Sub
This will do what you are looking for (It is the first Google results of "always CC myself Outlook")
http://www.extendoffice.com/documents/outlook/1108-outlook-auto-cc.html
Launch your outlook 2013 or 2010, and make sure that you are in the mail section. Then click Home > Rules > Manage Rules & Alerts.
After selecting Manage Rules & Alerts option, the Rules and Alerts dialog will popup. Under E-mail Rules, click New Rule option.
In the Rules Wizard, click Apply rule on messages I send then click Next to continue.
Then another dialog pops up.
(1.) In Step 1, check through the specified account box. In Step 2, please click on the word - specified.
(2.) And then click the Account drop down list to choose the account that you want to apply this rule.
After selecting the account, and click OK to return to the previous window, you will see the selected account showing in the Rules Wizard. Then click on Next button.
(1.) In this wizard, check Cc the message to people or public group box, and then click on people or public group in step 2.
(2.) In the Rule Address dialog box, double click your cc recipient to add the address to the To-> text box, (If I want to cc myself, I will select or type my own email address in the To-> column.), finally click OK.
It returns to the previous window, and you can see the cc recipient address appearing. Then click Finish button.
Now, it returns to the very beginning dialog, click OK button, then the cc rule will be created. If you don’t want to enable the rule, uncheck it.
Then after sending or forwarding an email message to others with your specified account, your account or your specific cc recipient will always receive the same message.
It looks like you need to handle the ItemSend event of the Application class. It is fired whenever an Microsoft Outlook item is sent, either by the user through an Inspector (before the inspector is closed, but after the user clicks the Send button) or when the Send method for an Outlook item, such as MailItem, is used in a program. Note, the Cancel parameter allows to cancel the process of sending the email.
In the ItemSend event handler you can check out the SentOnBehalfOfName property of the item passed as a parameter and add the CC recipient using the Recipients property of the MailItem class. The Recipients collection provides the Add method for adding recipients.
Set myRecipient = myItem.Recipients.Add("Dan Wilson")
myRecipient.Type = OlMailRecipientType.olCC
After don't forget to call the Resolve or ResolveAll method of the Recipient class to resolve a Recipient object against the Address Book.
See How To: Fill TO,CC and BCC fields in Outlook programmatically for more information.