I have looked through multiple posts on this issue and for some reason i just cant get my code to work.
I have code that opens a specific email, grabs the reply to email address, closes that email, then creates a new email with the To as the sender email of the previous email.
Sometimes the address only comes over as the name and not the full xxxx#xxx.com.
Please help, i am sure it is something simple. 'Filename' below is the email that is on my share drive. Address is the variable where i want to store all of the email addresses, the 'Reply All'.
Set OutApp = GetObject(, "Outlook.Application")
Set outEmail = OutApp.Session.OpenSharedItem(Filename)
With outEmail.ReplyAll
.display
Address = .to
.Close olDiscard
Set outEmail = Nothing
End With
Use the Recipients property instead of the string To field which may contain the name of the sender, not the actual email address. Use Recipients(index), where index is the name or index number, to return a single Recipient object. The name can be a string representing the display name, the alias, or the full SMTP email address of the recipient.
The Recipient.Type returns or sets a long representing the type of recipient. For the MailItem a recipient can have one of the following OlMailRecipientType constants: olBCC, olCC, olOriginator, or olTo. So, iteraring over all recipients and checking the Type property value you can find the To recipients.
For d = 1 To myItem.Recipients.count
Debug.Print myItem.Recipients.item(d).name
Debug.Print myItem.Recipients.item(d).Type
Next
Finally, you can use all properties of the Recipient object to get the email address such as Address or just set up the new email with the same object by using the Recipients.Add method which creates a new recipient in the Recipients collection. It accepts a string which represents the name of the recipient representing the display name, the alias, or the full SMTP email address of the recipient.
Note, you can get the Sender related properties from the original item without creating a reply-all draft item.
There is no reason to create / display / close a reply just to figure out who the message sender is. Use MailItem.SenderEmailAddress or MailItem.Sender.GetExchangeUser() (in case of an Exchange address):
Set outEmail = OutApp.Session.OpenSharedItem(Filename)
if outEmail.SenderEmailType = "EX" Then
Address = outEmail.Sender.GetExchangeUser.PrimarySMTPAddress
Else
Address = outEmail.SenderEmailAddress
End If
If you need all recipients in an email, loop through the MailItem.Recipients collection and extract addresses from the Recipient.Address property or use Recipient.AddressEntry.GetExchangeUser.PrimarySMTPAddress. Make sure to exclude the current user:
Off the top of my head:
for each recip in outEmail.Recipients
set addEntry = recip.AddressEntry
if addEntry.Type = "EX" Then
Addresses = Addresses & ";" & addEntry.GetExchangeUser.PrimarySMTPAddress
Else
Addresses = Addresses & ";" & addEntry.Address
End If
next
Related
I receive invoices from suppliers that I want to forward to a QBO (Quickbooks Online) email address that handles 'receipts/invoices' wherein it reads the attachments and parses the info within - this speeds up data entry.
QBO only accepts these emails from specific email addresses (i.e., ones that are registered as accounts in QBO). So assume that QBO only accepts emails from "me#mydomain.com". I receive the invoices on "billing#mydomain.com" which is a shared Office 365 mailbox that "me#mydomain.com" has access to.
My VBA code should forward the currently selected emails (found within the billing#mydomain.com mailbox) using the me#mydomain.com sending address to mydomain#qbodocs.com.
The problem is that the forwarded email arrives in the recipient's mailbox as having come from billing#mydomain.com. When I .Display (instead of .Send), I see that the sending account is set "correctly" yet it still arrives from the wrong account.
I decided that after the window pops up (using .Display), I would change the sending account to something else, then back to the intended sending account - and it works. So there's some setting/headers other than .SentOnBehalfOfName that I need to set as I don't want any user intervention.
Option Explicit
Public Sub SendToQBO()
Dim Email As Object
Dim Sender As String
Sender = "me#mydomain.com"
For Each Email In ActiveExplorer.Selection
With Email.Forward
' Just send to myself for now until this is figured out
.To = Sender
'.To = "mydomain#qbodocs.com"
.Subject = "Sent From Outlook"
.Body = Email.Body
.SendUsingAccount = Session.Accounts(Sender)
.SentOnBehalfOfName = Sender
.Send
' Using .Display instead shows the right sending address, but it's ineffective
' unless I select another, then select it again before manually sending.
' .Display
End With
Next
End Sub
There is no need to set up two properties simultaneously on the mail item.
The MailItem.SendUsingAccount returns or sets an Account object that represents the account under which the MailItem is to be sent. The SendUsingAccount property can be used to specify the account that should be used to send the MailItem when the Send method is called. Note, corresponding account should be configured in Outlook:
Sub SendUsingAccount()
Dim oAccount As Outlook.account
For Each oAccount In Application.Session.Accounts
If oAccount.AccountType = olPop3 Then
Dim oMail As Outlook.MailItem
Set oMail = Application.CreateItem(olMailItem)
oMail.Subject = "Sent using POP3 Account"
oMail.Recipients.Add ("someone#example.com")
oMail.Recipients.ResolveAll
Set oMail.SendUsingAccount = oAccount
oMail.Send
End If
Next
End Sub
In case given permissions to the shared account you can use the MailItem.SentOnBehalfOfName property which allows setting a string indicating the display name for the intended sender of the mail message. In that case the account may not be configured in Outlook.
And the last bit which I've noticed in your code:
For Each Email In ActiveExplorer.Selection
Remember, the selection object may contain different kind of Outlook items - appointments, posts, mail items and etc. So, I'd suggest adding a check for the item type before accessing MailItem methods and properties.
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.
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 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.
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.