'Get sender's SMTP email address with Excel VBA
I pull the Subject, received date and sender's name with the following code:
Set InboxSelect = GetObject("", "Outlook.Application").GetNamespace("MAPI").PickFolder
i = 0: EmailCount = 0
EmailCount = InboxSelect.Items.Count
While i < EmailCount
i = i + 1
blastRow = Cells(Rows.Count, 1).End(xlUp).Offset(1).Row
LastRow = Sheets("Body").Cells(Rows.Count, 1).End(xlUp).Offset(1).Row
With InboxSelect.Items(i)
MsgBox (SenderEmailAddress)
'If .senderemailaddress = "*@somethingSpecific.co.uk" Then
'EmailCount = EmailCount + 1
Sheets("Import Data").Range("A" & blastRow).Formula = .SenderName
Sheets("Import Data").Range("B" & blastRow).Formula = Format(.ReceivedTime, "dd/mm/yyyy")
Sheets("Import Data").Range("C" & blastRow).Formula = .Subject
Sheets("Body").Range("A" & LastRow).Formula = .Body
'End If
End With
Wend
What I'm trying to achieve now is an if statement that will say "If the sender's email address is '[email protected]' then execute that code. I've tried SenderEmailAddress but it returns blank when tested in a message box.
EDIT: /O=*SET1*/OU=FIRST ADMINISTRATIVE GROUP/CN=RECIPIENTS/CN=*VARIABLE1*
is now being returned in the immediate window every time with the below code:
Set InboxSelect = GetObject("", "Outlook.Application").GetNamespace("MAPI").PickFolder
i = 0: EmailCount = 0
EmailCount = InboxSelect.Items.Count
While i < EmailCount
For Each Item In InboxSelect.Items
Debug.Print Item.senderemailaddress
If Item.senderemailaddress = "/O=SET1/OU=FIRST ADMINISTRATIVE GROUP/CN=RECIPIENTS/CN=*" Then
i = i + 1
blastRow = Cells(Rows.Count, 1).End(xlUp).Offset(1).Row
LastRow = Sheets("Body").Cells(Rows.Count, 1).End(xlUp).Offset(1).Row
With InboxSelect.Items(i)
Sheets("Import Data").Range("A" & blastRow).Formula = .SenderName
Sheets("Import Data").Range("B" & blastRow).Formula = Format(.ReceivedTime, "dd/mm/yyyy")
Sheets("Import Data").Range("C" & blastRow).Formula = .Subject
'PASTING BODY IS SLOW
Sheets("Body").Range("A" & LastRow).Formula = .Body
'End If
End With
End If
Next Item
Wend
What I've attempted to do is use a wildcard symbol (the *) to act as the variation in the returned message but that hasn't worked, is there a better way to do this?
Solution 1:[1]
An example of when using the SenderEmailAddress
property returns the e-mail string as required.
Dim outlookApp As outlook.Application, oOutlook As Object
Dim oInbox As outlook.Folder, oMail As outlook.MailItem
Set outlookApp = New outlook.Application
Set oOutlook = outlookApp.GetNamespace("MAPI")
Set oInbox = oOutlook.GetDefaultFolder(olFolderInbox)
For Each oMail In oInbox.Items
Debug.Print oMail.SenderEmailAddress
Next oMail
EDIT:
The issue is that what the .SenderEmailAddress
property is returning the EX
address, whereas we want the SMTP
address. For any internal e-mail addresses, it will return the EX
type address.
To get the SMTP
address from an internal e-mail, you can use the below.
Dim outlookApp As Outlook.Application, oOutlook As Object
Dim oInbox As Outlook.Folder, oMail As Outlook.MailItem
Dim strAddress As String, strEntryId As String, getSmtpMailAddress As String
Dim objAddressentry As Outlook.AddressEntry, objExchangeUser As Outlook.ExchangeUser
Dim objReply As Outlook.MailItem, objRecipient As Outlook.Recipient
Set outlookApp = New Outlook.Application
Set oOutlook = outlookApp.GetNamespace("MAPI")
Set oInbox = oOutlook.GetDefaultFolder(olFolderInbox)
For Each oMail In oInbox.Items
If oMail.SenderEmailType = "SMTP" Then
strAddress = oMail.SenderEmailAddress
Else
Set objReply = oMail.Reply()
Set objRecipient = objReply.Recipients.Item(1)
strEntryId = objRecipient.EntryID
objReply.Close OlInspectorClose.olDiscard
strEntryId = objRecipient.EntryID
Set objAddressentry = oOutlook.GetAddressEntryFromID(strEntryId)
Set objExchangeUser = objAddressentry.GetExchangeUser()
strAddress = objExchangeUser.PrimarySmtpAddress()
End If
getSmtpMailAddress = strAddress
Debug.Print getSmtpMailAddress
Next oMail
If the e-mail is already SMTP
it will just use the .SenderEmailAddress property to return the address. If the e-mail is EX
then it will find the SMTP
address by using the .GetAddressEntryFromID()
Method.
The above is modified code from what I found on this answer. Here is also a link with how to do this within C#.
Solution 2:[2]
Public Function GetSenderAddrStr(objMail As Outlook.MailItem) As String
If objMail.SenderEmailType = "SMTP" Then
GetSenderAddrStr = objMail.SenderEmailAddress
Else
GetSenderAddrStr = objMail.Sender.GetExchangeUser().PrimarySmtpAddress
End If
End Function
Solution 3:[3]
In most cases, the sender's SMTP address will be available in a separate property, you can access it using MailItem.PropertyAccessor
- take a look at an existing message using OutlookSpy (I am its author) - click IMessage button.
Otherwise you can use ExchangeUser.PrimarySmtpAddress
Off the top of my head:
on error resume next 'PropertyAccessor can raise an exception if a property is not found
if item.SenderEmailType = "SMTP" Then
strAddress = item.SenderEmailAddress
Else
'read PidTagSenderSmtpAddress
strAddress = item.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x5D01001F")
if Len(strAddress) = 0 Then
set objSender = item.Sender
if not (objSender Is Nothing) Then
'read PR_SMTP_ADDRESS_W
strAddress = objSender.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x39FE001F")
if Len(strAddress) = 0 Then
'last resort
set exUser = objSender.GetExchangeUser
if not (exUser Is Nothing) Then
strAddress = exUser.PrimarySmtpAddress
End If
End If
End If
En If
End If
Solution 4:[4]
Cant you just use send keys to force "Control+k" in outlook? Seems like this would solve your issue and probably make for an easy slice of code.
try adding this somewhere?
Application.SendKeys("^k") 'i believe this is correct syntax, never used this yet but i think it works
Solution 5:[5]
I ended up doing
varTest = Item.senderemailaddress
If InStr(varTest, "BE WISER INSURANCE") > 0 Then
which detected the set section that wouldn't be in any emails I didn't want. Thanks very much for your help, @Iturner!
Solution 6:[6]
In most cases, the sender's SMTP address will be available on the mesage itself in a separate property (PidTagSenderSmtpAddress
= 0x5D01001F
, DASL name "http://schemas.microsoft.com/mapi/proptag/0x5D01001F"
), you can access it using MailItem.PropertyAccessor
- take a look at an existing message using OutlookSpy (I am its author) - click IMessage button.
Otherwise you can use ExchangeUser.PrimarySmtpAddress
: it is more expensive than reading the PidTagSenderSmtpAddress
property. PidTagSenderSmtpAddress
will also work if ExchangeUser
fails (which can happen if the user was deleted from GAL or if you are looking at the message in a profile different from the one where the message was created)
Off the top of my head:
on error resume next 'PropertyAccessor can raise an exception if a property is not found
if item.SenderEmailType = "SMTP" Then
strAddress = item.SenderEmailAddress
Else
'read PidTagSenderSmtpAddress
strAddress = item.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x5D01001F")
if Len(strAddress) = 0 Then
set objSender = item.Sender
if not (objSender Is Nothing) Then
'read PR_SMTP_ADDRESS_W
strAddress = objSender.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x39FE001F")
if Len(strAddress) = 0 Then
'last resort
set exUser = objSender.GetExchangeUser
if not (exUser Is Nothing) Then
strAddress = exUser.PrimarySmtpAddress
End If
End If
End If
En If
End If
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Community |
Solution 2 | FreeSoftwareServers |
Solution 3 | |
Solution 4 | Doug Coats |
Solution 5 | Josh Whitfield |
Solution 6 | Dmitry Streblechenko |