We see lots of example on how to create a new Outlook Contact (now called People), but what about wanting to retrieve the information of an existing Contact through VBA? Well, similarily to my post List Outlook Calendar Appointments it is quite straightforward.
The Basic Solution
'---------------------------------------------------------------------------------------
' Procedure : OTLK_GetContact
' Author : Daniel Pineault, CARDA Consultants Inc.
' Website : http://www.cardaconsultants.com
' Purpose : Retrieve Outlook Contact(s)' information
' Copyright : The following is release as Attribution-ShareAlike 4.0 International
' (CC BY-SA 4.0) - https://creativecommons.org/licenses/by-sa/4.0/
' Req'd Refs: Uses Late Binding, so none required
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' sFirstName : First Name of the contact to retrieve
' sLastName : Last Name of the contact to retrieve
'
' Usage:
' ~~~~~~
' Call OTLK_GetContact("Julie", "Evans")
'
' Revision History:
' Rev Date(yyyy/mm/dd) Description
' **************************************************************************************
' 1 2018-12-09 Initial Release
'---------------------------------------------------------------------------------------
Public Function OTLK_GetContact(ByVal sFirstName As String, ByVal sLastName As String)
Dim oOutlook As Object
Dim oNS As Object
Dim oContacts As Object
Dim oFilterContacts As Object
Dim sFilter As String
Dim bOutlookOpened As Boolean
Const olFolderContacts = 10
'Get/Start Outlook
On Error Resume Next
Set oOutlook = GetObject(, "Outlook.Application") 'Bind to existing instance of Outlook
If Err.Number <> 0 Then 'Could not get instance, so create a new one
Err.Clear
Set oOutlook = CreateObject("Outlook.Application")
Else 'Was already running
bOutlookOpened = True
End If
On Error GoTo Error_Handler
Set oNS = oOutlook.GetNamespace("MAPI")
Set oContacts = oNS.GetDefaultFolder(olFolderContacts)
'Apply a filter to retrieve the specific contact(s) we seek.
sFilter = "[FirstName]='" & sFirstName & "' and [LastName]='" & sLastName & "'"
Set oFilterContacts = oContacts.Items.Restrict(sFilter)
Debug.Print oFilterContacts.Count & " appointments found."
For Each oFilterContacts In oFilterContacts 'Iterate through each contact
'Do what you want with the retrieved contact(s)' information
Debug.Print oFilterContacts.FullName, oFilterContacts.CompanyName, oFilterContacts.Email1Address
Next
If bOutlookOpened = False Then 'Since we started Outlook, we should close it now that we're done
oOutlook.Quit 'There seems to be a delay in this action taking place, but does eventually take place
End If
Error_Handler_Exit:
On Error Resume Next
If Not oFilterContacts Is Nothing Then Set oFilterContacts = Nothing
If Not oContacts Is Nothing Then Set oContacts = Nothing
If Not oNS Is Nothing Then Set oNS = Nothing
If Not oOutlook Is Nothing Then Set oOutlook = Nothing
Exit Function
Error_Handler:
MsgBox "The following error has occurred" & vbCrLf & vbCrLf & _
"Error Number: " & Err.Number & vbCrLf & _
"Error Source: OTLK_GetContact" & vbCrLf & _
"Error Description: " & Err.Description & _
Switch(Erl = 0, "", Erl <> 0, vbCrLf & "Line No: " & Erl) _
, vbOKOnly + vbCritical, "An Error has Occurred!"
Resume Error_Handler_Exit
End Function
Now the above performs a search on the contact’s First and Last names, but you can change that and search by any field you wish to.
Taking Things a Little Further
Now the above is great, but is limited to searching through the root Contacts folder and doesn’t check any user created subfolders. I wanted a solution that would work on any system regardless of how a user set things up and I didn’t want to have to hard code subfolder names in my code either. So I came up with a procedure that simply iterates through Contacts forlder as well as all its subfolder when performing the search. Below is what I put together.
'---------------------------------------------------------------------------------------
' Procedure : OTLK_GetContact
' Author : Daniel Pineault, CARDA Consultants Inc.
' Website : http://www.cardaconsultants.com
' Purpose : Retrieve Outlook Contact(s)' information
' Copyright : The following is release as Attribution-ShareAlike 4.0 International
' (CC BY-SA 4.0) - https://creativecommons.org/licenses/by-sa/4.0/
' Req'd Refs: Uses Late Binding, so none required
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' sFirstName : First Name of the contact to retrieve
' sLastName : Last Name of the contact to retrieve
'
' Usage:
' ~~~~~~
' Call OTLK_GetContact("Julie", "Evans")
'
' Revision History:
' Rev Date(yyyy/mm/dd) Description
' **************************************************************************************
' 1 2018-12-09 Initial Release
' 2 2018-12-10 Add recursive searching
'---------------------------------------------------------------------------------------
Public Function OTLK_GetContact(ByVal sFirstName As String, ByVal sLastName As String, _
Optional oFolder As Object)
Dim oOutlook As Object
Dim oNS As Object
Dim oContacts As Object
Dim oFilterContacts As Object
' Dim oFolder As Object
Dim sFilter As String
Dim bOutlookOpened As Boolean
Const olFolderContacts = 10
'Get/Start Outlook
On Error Resume Next
Set oOutlook = GetObject(, "Outlook.Application") 'Bind to existing instance of Outlook
If Err.Number <> 0 Then 'Could not get instance, so create a new one
Err.Clear
Set oOutlook = CreateObject("Outlook.Application")
Else 'Was already running
bOutlookOpened = True
End If
On Error GoTo Error_Handler
Set oNS = oOutlook.GetNamespace("MAPI")
If oFolder Is Nothing Then
Set oContacts = oNS.GetDefaultFolder(olFolderContacts)
'Let's search the default contact folder
Debug.Print "Processing Folder " & oContacts.Name
'Apply a filter to retrieve the specific contact(s) we seek.
sFilter = "[FirstName]='" & sFirstName & "' and [LastName]='" & sLastName & "'"
Set oFilterContacts = oContacts.Items.Restrict(sFilter)
Debug.Print , oFilterContacts.Count & " appointments found."
For Each oFilterContacts In oFilterContacts 'Iterate through each contact
'Do what you want with the retrieved contact(s)' information
Debug.Print , oContacts.Name, oFilterContacts.FullName, oFilterContacts.CompanyName, oFilterContacts.Email1Address
Next
Else
Set oContacts = oFolder
End If
'Recursively search through any contact folders created by the user
For Each oFolder In oContacts.Folders
Debug.Print "Processing Folder " & oFolder.Name
'Apply a filter to retrieve the specific contact(s) we seek.
sFilter = "[FirstName]='" & sFirstName & "' and [LastName]='" & sLastName & "'"
Set oFilterContacts = oFolder.Items.Restrict(sFilter)
Debug.Print , oFilterContacts.Count & " appointments found."
For Each oFilterContacts In oFilterContacts 'Iterate through each contact
'Do what you want with the retrieved contact(s)' information
Debug.Print , oFolder.Name, oFilterContacts.FullName, oFilterContacts.CompanyName, oFilterContacts.Email1Address
Next
Call OTLK_GetContact(sFirstName, sLastName, oFolder)
Next oFolder
If bOutlookOpened = False Then 'Since we started Outlook, we should close it now that we're done
oOutlook.Quit 'There seems to be a delay in this action taking place, but does eventually take place
End If
Error_Handler_Exit:
On Error Resume Next
If Not oFolder Is Nothing Then Set oFolder = Nothing
If Not oFilterContacts Is Nothing Then Set oFilterContacts = Nothing
If Not oContacts Is Nothing Then Set oContacts = Nothing
If Not oNS Is Nothing Then Set oNS = Nothing
If Not oOutlook Is Nothing Then Set oOutlook = Nothing
Exit Function
Error_Handler:
MsgBox "The following error has occurred" & vbCrLf & vbCrLf & _
"Error Number: " & Err.Number & vbCrLf & _
"Error Source: OTLK_GetContact" & vbCrLf & _
"Error Description: " & Err.Description & _
Switch(Erl = 0, "", Erl <> 0, vbCrLf & "Line No: " & Erl) _
, vbOKOnly + vbCritical, "An Error has Occurred!"
Resume Error_Handler_Exit
End Function
Very well done. Compliments!
Awesome job on this code!
I am trying to use a shared Office 365 Outlook contact list in an Access program. I tried using the wizard but it only imports full contact names including their companies as a single field but I want to import fields discretely like you show so I thought this would resolve my issues. Interestingly it doesn’t find the contact in this folder. Is there something special about shared folders that would not allow this?
I have the same issue, this looks only at the private contacts list, not at the contacts lists provided by the company.