How to get the email address of the current logged-in user?
Asked Answered
R

5

18

I'm new to VBA and trying to get an automated word document working. At the moment there is a Button in the document that which upon pressing, will fire off an email with the document attached.

However I need to also get the email address of the current user sending the email, so I can place it inside the document before sending it off. My searches on the internet have not resulted in any usable code that meets my situation. My current code is below.

Set OL = CreateObject("Outlook.Application")
Set EmailItem = OL.CreateItem(olMailItem)

Set Doc = ActiveDocument
Doc.Save

With EmailItem
    .Subject = "Requesting Authorization Use Overtime"
    .Body = "Please review the following request for overtime" & vbCrLf & _
    "" & vbCrLf & _
    "Thanks"
    .To = "[email protected]"
    .Importance = olImportanceNormal
    .Attachments.Add Doc.FullName
    .Send
End With

Not sure if this is relevant, but when the document is being used, the Outlook application will always be open with a user signed in. Im used to having intellisense help in these sorts of situations so I can fool around with methods and properties, but there seems to be very little help from intellisense.

Riorsson answered 23/10, 2014 at 0:22 Comment(0)
C
15

Usually, the email address is the name assigned to Outlook Mail Folders.
So try this:

'~~> add these lines to your code
Dim olNS As Outlook.NameSpace
Dim olFol AS Outlook.Folder

Set olNS = OL.GetNamespace("MAPI")
Set olFol = olNS.GetDefaultFolder(olFolderInbox)

MsgBox olFol.Parent.Name '~~> most cases contains the email address

This is assuming your are using Early Bind with the object reference properly set.
Another way to access such info is directly use Namespace properties.

MsgBox olNS.Accounts.Item(1).DisplayName '~~> usually email address
MsgBox olNS.Accounts.Item(1).SmtpAddress '~~> email address
MsgBox olNS.Accounts.Item(1).UserName '~~> displays the user name

I hope any of the above somehow helps.

Cyrillus answered 23/10, 2014 at 1:12 Comment(3)
@Riorsson Glad it did. Added bonus properties you can use. :)Cyrillus
Absolutely not. The store name, especially in the older versions of Outlook, does not contain the email address of the store owner or the current user (which can be different from the current user if you have more than one store in the profile).Spritsail
@DmitryStreblechenko Yes not a very neat solution indeed which works on pre-defined scenarios only.Cyrillus
S
20

It all depends on the definition of "the current user address".

  1. The address of the primary account in Outlook can be retrieved from Appication.Session.CurrentUser (returns Recipient object). Use Recipient.Address property. Note however that for an Exchange account (Recipient.AddressEntry.Type == "EX") you will receive an EX type address. To retrieve the SMTP address, use Recipient.AddressEntry.GetExchangeUser().PrimarySmtpAddress. Be prepared to handle nulls/exceptions in case of errors. This is what you most likely need in your particular case.

    On the Extended MAPI level (C++ or Delphi), use IMAPISession::QueryIdentity (you can test it in OutlookSpy (I am its author) - click IMAPISession button, then QueryIdentity). You can then read the PR_ADDRTYPE property ("EX" vs "SMTP") and PR_EMAIL_ADDRESS (when PR_ADDRTYPE = "SMTP") or (in case of Exchange) PR_SMTP_ADDRESS (not guaranteed to be present) and PR_EMS_AB_PROXY_ADDRESSES (multivalued property will Exchange addresses, including all proxy (alias) addresses).

  2. In case of multiple accounts in the profile, an email can be sent or received through multiple accounts. In that case use MailItem.SendUsingAccount (returns Account object, can be null - in that case use Application.Session.CurentUser). This is valid both for received, sent or emails being composed (Application.ActiveInspector.CurrentItem or Application.ActiveExplorer.ActiveInlineResponse).

  3. All accounts in a given profile can be accessed using the Namespace.Accounts collection (Application.Session.Accounts). Account's address can be accessed using Account.SmtpAddress property. Note that the Outlook Object Model only exposes mail accounts. Some store accounts (such as PST) are not in the collection since they do not have an intrinsic user identity even if some other accounts (such as POP3/SMTP) can deliver to that store. If you want to access all accounts, you can use Redemption (I am its author) and its RDOSession.Accounts collection (RDOAccounts object).
    On the Extended MAPI level, the accounts are exposed through the IOlkAccountManager interface. You can play with it in OutlookSpy if you click the IOlkAccountManager button.

  4. In case of delegate Exchange stores, the store owner is not exposed through the Outlook Object Model. You can either use Extended MAPI (note that the PR_MAILBOX_OWNER_ENTRYID property is only exposed by the online store, it is not available in a cached store). You can parse the Exchange store entry id and extract the EX type address from it. You can then construct the GAL object entry id given the EX address. You can also access the store owner using Redemption and its RDOExchangeMailboxStore object and its Owner property.

Spritsail answered 2/8, 2016 at 2:36 Comment(0)
C
15

Usually, the email address is the name assigned to Outlook Mail Folders.
So try this:

'~~> add these lines to your code
Dim olNS As Outlook.NameSpace
Dim olFol AS Outlook.Folder

Set olNS = OL.GetNamespace("MAPI")
Set olFol = olNS.GetDefaultFolder(olFolderInbox)

MsgBox olFol.Parent.Name '~~> most cases contains the email address

This is assuming your are using Early Bind with the object reference properly set.
Another way to access such info is directly use Namespace properties.

MsgBox olNS.Accounts.Item(1).DisplayName '~~> usually email address
MsgBox olNS.Accounts.Item(1).SmtpAddress '~~> email address
MsgBox olNS.Accounts.Item(1).UserName '~~> displays the user name

I hope any of the above somehow helps.

Cyrillus answered 23/10, 2014 at 1:12 Comment(3)
@Riorsson Glad it did. Added bonus properties you can use. :)Cyrillus
Absolutely not. The store name, especially in the older versions of Outlook, does not contain the email address of the store owner or the current user (which can be different from the current user if you have more than one store in the profile).Spritsail
@DmitryStreblechenko Yes not a very neat solution indeed which works on pre-defined scenarios only.Cyrillus
S
8

This answer is for Late Binding so you don't need to have reference libraries. Place the following code in a module:

    Dim OL As Object, olAllUsers As Object, oExchUser As Object, oentry As Object, myitem As Object
    Dim User As String

    Set OL = CreateObject("outlook.application")
    Set olAllUsers = OL.Session.AddressLists.Item("All Users").AddressEntries

    User = OL.Session.CurrentUser.Name

    Set oentry = olAllUsers.Item(User)

    Set oExchUser = oentry.GetExchangeUser()

    msgbox oExchUser.PrimarySmtpAddress
Surah answered 26/11, 2015 at 15:59 Comment(1)
It worked like a charm, but It also gives wrong Email address, for example it correctly gives user name as 'john, doe' but oExchUser gives as '[email protected]' it's weird.Kabyle
N
1

Functional Approach

To make this a bit more reusable, try any return the email from a function.

Late Binding Example

''
' Creates a new instance of Microsoft Outlook to get the current users
' email address.
' Late Binding Demo.
'
' @exception If any errors it will return an optional parameter for fallback values
''
Public Function GetUsersOutlookEmail(Optional ByVal errorFallback As String = "") As String
On Error GoTo catch
    With CreateObject("outlook.application")
        GetUsersOutlookEmail = .GetNamespace("MAPI").GetDefaultFolder(olFolderInbox).Parent.Name
    End With
Exit Function
catch:
    GetUsersOutlookEmail = errorFallback
End Function

Early Binding Example

''
' Creates a new instance of Microsoft Outlook to get the current users
' email address.
' Late Binding Demo.
'
' @reference Microsoft Outlook 16.0 Object Reference
' @exception If any errors it will return an optional parameter for fallback values
''
Public Function GetUsersOutlookEmail(Optional ByVal errorFallback As String = "") As String
On Error GoTo catch
    With New Outlook.Application
        GetUsersOutlookEmail = .GetNamespace("MAPI").GetDefaultFolder(olFolderInbox).Parent.Name
    End With
Exit Function
catch:
    GetUsersOutlookEmail = errorFallback
End Function

Error Handling

Anytime you are making an API call like this, there is always a potential for errors to occur. The method I choose for these demos is to provided an optional parameter for a fallback email. This make is dynamic as you can check to see if it is null, or you could provide something such as username Environ("Username") & "@outlook.com"

Narvaez answered 21/5, 2021 at 19:14 Comment(0)
S
0

Try this:

Func GetUserEmail()
 
    Dim emailAddress As String

    emailAddress = CreateObject("Outlook.Application").GetNamespace("MAPI").Accounts.Item(1).SmtpAddress

    'Return Users email
    GetUserEmail = emailAddress
 
End Func
Siphon answered 14/3 at 1:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.