Accessing and filtering the GAL

I am trying to access the Global Address List of Exchange 5.0 with VB5 using Active Messaging but I am finding that using the filter is painfully slow.  Does anyone know of a  more efficient way of doing this i.e. replicating the Address Book option of Exchange/Outlook.
Who is Participating?
MirkwoodConnect With a Mentor Commented:
Here is some code to access the address book

HOWTO: Access MAPI Address Books with Active Messaging 1.1

Last reviewed: January 8, 1998
Article ID: Q172093 The information in this article applies to:

Microsoft Visual Basic Control Creation, Learning, Professional, and Enterprise Editions for Windows, version 5.0 Microsoft Visual Basic Standard, Professional, and Enterprise Editions, 32-bit only, for Windows, version 4.0 Microsoft Access versions 7.0, 97 Microsoft Word 97 for Windows Microsoft Excel 97 for Windows Microsoft Excel for Windows 95, version 7.0


Active Messaging 1.1 supports programmatic access to MAPI Address Books through the AddressEntries collection of an AddressList object. Each AddressList object corresponds to a MAPI address book and is a member of the AddressLists collection of the Session object. The available Address Books can be enumerated by walking the AddressLists collection, and an individual address book can be selected by indexing the AddressLists collection by name or position. The sample below walks the AddressLists collection displaying information about each accessible Address Book. The second part of the sample selects the Global Address List and then walks the Address Entries, recursively expanding Distribution Lists.


The following sample code applies to any 32-bit VBA-based product.

WARNING: ANY USE BY YOU OF THE CODE PROVIDED IN THIS ARTICLE IS AT YOUR OWN RISK. Microsoft provides this code "as is" without warranty of any kind, either express or implied, including but not limited to the implied warranties of merchantability and/or fitness for a particular purpose.

Step-by-Step Example

1.Create a new VBA project. Add a Reference to Microsoft Active Messaging 1.1 Object Library.

2.Type the following code into a module:

      Option Explicit

      Sub main()

          Dim objSession As MAPI.Session        ' use early binding for
                                                ' efficiency
          Dim collAddressLists As AddressLists
          Dim objAddressList As AddressList
          Dim collAddressEntries As AddressEntries

          On Error GoTo error_olemsg

          ' create a session and log on
          Set objSession = CreateObject("MAPI.Session")
          ' use a valid exchange profile name
          objSession.Logon ("<Your Profile Name Here>")

          'Walk the available Address Books
          Set collAddressLists = objSession.AddressLists
          For Each objAddressList In collAddressLists
               ' Display collection selection indices
               Debug.Print objAddressList.Name,
               Debug.Print objAddressList.Index,
               ' Display readonly access flag
               Debug.Print objAddressList.IsReadOnly,

               ' display count of recipients
               Set collAddressEntries = objAddressList.AddressEntries
               Debug.Print Str(collAddressEntries.Count)
               ' if any AddressEntries, display first recipient name
               If Not objAddressList.AddressEntries(1) Is Nothing Then _
                    Debug.Print objAddressList.AddressEntries(1).Name

          Next objAddressList

          ' Walk the Global Address List
          Set collAddressEntries = objSession.AddressLists( _
                   "Global Address List").AddressEntries
          WalkAddressList collAddressEntries

          'close session and logoff
          Exit Sub

               MsgBox "Error " & Str(Err) & ": " & Error$(Err)
               Exit Sub

      End Sub

      ' Walk an AddressEntries collection recursively expanding
      ' Distribution Lists

      Sub WalkAddressList(collAddressEntries As AddressEntries)
          Dim objaddressEntry As AddressEntry

          For Each objaddressEntry In collAddressEntries
               ' Display the recipient's name
               Debug.Print objaddressEntry.Name,
               ' Display the recipient's type
               Select Case objaddressEntry.DisplayType
               Case ActMsgUser
                   Debug.Print "Exchange Recipient"
               Case ActMsgDistList
                   Debug.Print "Distribution List"
                   WalkAddressList objaddressEntry.Members
                   Debug.Print "End of DL " & objaddressEntry.Name
               Case ActMsgForum
                   Debug.Print "Public Folder"
               Case ActMsgAgent
                   Debug.Print "Agent"
               Case ActMsgPrivateDistList
                   Debug.Print "Private DL"
               Case ActMsgOrganization
                   Debug.Print "Organization"
               Case ActMsgRemoteUser
                   Debug.Print "Custom Recipient"
               Case Else
                   Debug.Print "Unknown type"
               End Select

          Next objaddressEntry

      End Sub

3.Visual Basic only: Set Sub Main to run in the Project Properties, and then run.

Other VBA applications: In the Debug/Immediate Window, type "MAIN" and press the ENTER key.

4.The output will appear in the Debug/Immediate window.


The address book can have restricted entries. These will generate an "Access Denied" message:

   Error -2147024891: [Active Messaging - [E_ACCESSDENIED(80070005)]]

It is left up to the user to add extra error handling where required.


Documentation for Active Messaging is available on MSDN under the SDK Documentation/Platform SDK/Databases and Messaging Services/Active Messaging topics.

The following Microsoft Knowledge Base article lists various sources for installing Active Messaging 1.1:

   ARTICLE-ID: Q171440
   TITLE     : INFO: Where to Acquire the Active Messaging Libraries

For additional information about Collaboration Data Objects versus Active Messaging, please see the following article in the Microsoft Knowledge Base:

   ARTICLE-ID: Q176916
   TITLE     : INFO: Active Messaging and Collaboration Data Objects (CDO)

Keywords          : kbprg ActMsg vb432 VB4WIN vb5all vb5howto vbwin
Technology        : kbvba
Version           : WINDOWS:4.0 5.0 7.0 97
Platform          : WINDOWS
Issue type        : kbhowto

What exactly are you trying to do with the global address list in Exchange? Do you assume that all users of your app have a MAPI client?

budgie_bAuthor Commented:
yep.  By using MS Active Messaging 1.1. Object Model I can use the AddressEntryFilter object to filter the GAL.  What I want to do is replicate the Exchange Client/Outlook Address List.  However we have about 5000 mail exchange clients and this takes about 1min to filter, for example all the A's.  This is an unacceptable time.  I presume the best way to recreate the Address List is by creating a list that displays say the first 10 address and then on selection of a letter say Z will filter the first 10 of Z.  Any ideas are appreciated.

If I understand right, you want a duplicate of the global address list on each one of your workstations then filter through the list depending on whatever the user request is. So when the user types 'A' the app will extract all addresses beginning with A then if a further letter is pressed exple 'B' your app will extract all 'AB' etc...

This is what I would do:
Using OLE messaging objects is by far the fastest way of dealing with MS-Exchange servers (I have tried it as well as MAPI32.OCX and the later is soo slow). I would create/update a database recordset on the server by a another small app which extracts the list overnight for exple, then I would use SQL queries to extract very quickly the required list of adresses, the only slow part would be making the GAL into a database, but since this process is invisible to the user it does not matter too much.

budgie_bAuthor Commented:
This is what I am using and it has been too slow but as it has been outstanding for so long I have decided to give you the points.  Thanks.
All Courses

From novice to tech pro — start learning today.