Search code examples
vbaoutlook

Automation error in global address list lookup


I'm trying to look up a person's email address using the Outlook global address list. Here is the VBA code I use to do it.

    'Snip
    If firstName <> "" Then
        Dim o, AddressList, AddressEntry
        Dim AddressName, Address, Address2 As String
        Set o = CreateObject("Outlook.Application")
        Set AddressList = o.Session.AddressLists("Global Address List")
        AddressName = firstName
        For Each AddressEntry In AddressList.AddressEntries
            If AddressEntry.Name = AddressName Then
                Address = AddressEntry.GetExchangeUser.PrimarySmtpAddress
                Exit For
            End If
        Next AddressEntry
    End If
    'Snip

The variable "firstName" is in the format Last name, first name. This seemingly only works half of the time I try to use it. For example if I put my own name in it work perfectly fine every time but if I put in my co-worker's name I get a little pop up bubble from Outlook saying "outlook is trying to retrieve data from the Microsoft exchange server *.com" and then I get an automation error. I couldn't find anything in common between the names that don't work and the same for those that do. Any help would be very much appreciated.

EDIT: Another note I just thought of is that when I hit debug on the error window it highlights the "Next AddressEntry" line.


Solution

  • Do not loop through all items in GAL - some GALs contain tens of thousand of entries, and you will nto be able to loop through them.

    Call Application.Session.CreateRecipient (returns Recipient object), call Recipient.Resolve, then use Recipient.AddressEntry.GetExchangeUser.

    UPDATE:
    if the name is ambiguous, you will get back an error from Recipient.Resolve - Outlook Object Model does not let you recover from that - there is no way to get the list of matches and select the one you want. If using Redemption (I am its author) is an option, you can use is RDOAddressBook.ResolveNameEx method - it returns a list of matches (of one entry if the name is not ambiguous). You can also use RDIAddressList.ResolveName / ResolveNameEx if you want to resolve against a particular container only (e.g. GAL).

     Set o = CreateObject("Outlook.Application")
     ...
     set Session = CreateObject("Redemption.RDOSession")
     Session.MAPIOBJECT = o.Session.MAPIOBJECT
     set AdrrEntries = Session.AddressBook.ResolveNameEx("John")
     MsgBox AdrrEntries.Count & " names were returned by ResolveNameEx:"
     for each AE in AdrrEntries
         MsgBox AE.Name
     next