Eugene Astafiev

How To: Retrieve Outlook Contact items using Restrict method

In one of my previous articles, where I described how to use the Restrict method to retrieve Outlook mail items from a folder, I demonstrated the way of using the Restrict method against mail items. Now I am going to use this method against Contact items in Outlook.

I want to draw your attention to the fact that the Restrict method works much faster than the Find and FindNext methods if there is a large number of items in the folder and only a few items are expected to be found. Use the Find and FindNext methods in case of a relatively small number of items in a folder.

The code below gets the collection of contact items from the specified folder (using the Restrict method of the Items class), then iterates over the returned items and writes the first and last name of the particular contact item to the debug output. You can use the Output window in Visual Studio or the DebugView utility to intercept such output. In general, there are no breaking changes compared to using mail items. I have just modified the filtering criteria ;-)

C# and Add-in Express:

using System.Text;
using System.Diagnostics;
// ...
private void RestrictCoWorkers(Outlook.MAPIFolder folder)
{
    string restrictCriteria = "[CompanyName] = \"Add-in Express\" ";
    StringBuilder strBuilder = null;
    Outlook.Items folderItems = null;
    Outlook.Items resultItems = null;
    Outlook._ContactItem contact = null;
    int counter = default(int);
    object item = null;
    try
    {
        strBuilder = new StringBuilder();
        folderItems = folder.Items;
        resultItems = folderItems.Restrict(restrictCriteria);
        for(int i=1; resultItems.Count>=i; i++)
        {
            item = resultItems.Item(i);
            if (item is Outlook._ContactItem)
            {
                counter++;
                contact = item as Outlook._ContactItem;
                strBuilder.AppendLine("#" + counter.ToString() +
                                      "\tFist Name: " + contact.FirstName+
                                      "\tLast Name: " + contact.LastName);
            }
            Marshal.ReleaseComObject(item);
        }
        if (strBuilder.Length > 0)
            Debug.WriteLine(strBuilder.ToString());
        else
            Debug.WriteLine("There is no match in the "
                             + folder.Name + " folder.");
    }
    catch (Exception ex)
    {
        System.Windows.Forms.MessageBox.Show(ex.Message);
    }
    finally
    {
        if (folderItems != null) Marshal.ReleaseComObject(folderItems);
        if (resultItems != null) Marshal.ReleaseComObject(resultItems);
    }
}

VB.NET and Add-in Express:

Imports System.Text
Imports System.Diagnostics
' ...
Private Sub RestrictCoWorkers(folder As Outlook.MAPIFolder)
    Dim restrictCriteria As String = "[CompanyName] = ""Add-in Express"" "
    Dim strBuilder As StringBuilder = Nothing
    Dim folderItems As Outlook.Items = Nothing
    Dim resultItems As Outlook.Items = Nothing
    Dim contact As Outlook._ContactItem = Nothing
    Dim counter As Integer = 0
    Dim item As Object = Nothing
    Try
        strBuilder = New StringBuilder()
        folderItems = folder.Items
        resultItems = folderItems.Restrict(restrictCriteria)
        For i As Integer = 1 To resultItems.Count
            item = resultItems.Item(i)
            If TypeOf (item) Is Outlook._ContactItem Then
                counter += 1
                contact = item
                strBuilder.AppendLine("#" + counter.ToString() + _
                                      " - Subject: " + contact.Subject)
            End If
            Marshal.ReleaseComObject(item)
        Next
        If (strBuilder.Length > 0) Then
            Debug.WriteLine(strBuilder.ToString())
        Else
            Debug.WriteLine("There is no match in the " _
                             + folder.Name + " folder.")
        End If
    Catch ex As Exception
        System.Windows.Forms.MessageBox.Show(ex.Message)
    Finally
        If Not IsNothing(folderItems) Then Marshal.ReleaseComObject(folderItems)
        If Not IsNothing(resultItems) Then Marshal.ReleaseComObject(resultItems)
    End Try
End Sub

C# and VSTO:

using System.Runtime.InteropServices;
using System.Diagnostics;
// ...
private void RestrictCoWorkers(Outlook.MAPIFolder folder)
{
    string restrictCriteria = "[CompanyName] = \"Add-in Express\" ";
    StringBuilder strBuilder = null;
    Outlook.Items folderItems = null;
    Outlook.Items resultItems = null;
    Outlook._ContactItem contact = null;
    int counter = default(int);
    object item = null;
    try
    {
        strBuilder = new StringBuilder();
        folderItems = folder.Items;
        resultItems = folderItems.Restrict(restrictCriteria);
        for (int i = 1; resultItems.Count >= i; i++)
        {
            item = resultItems[i];
            if (item is Outlook._ContactItem)
            {
                counter++;
                contact = item as Outlook._ContactItem;
                strBuilder.AppendLine("#" + counter.ToString() +
                                      "\tFist Name: " + contact.FirstName +
                                      "\tLast Name: " + contact.LastName);
             }
             Marshal.ReleaseComObject(item);
         }
         if (strBuilder.Length > 0)
             Debug.WriteLine(strBuilder.ToString());
         else
             Debug.WriteLine("There is no match in the "
                              + folder.Name + " folder.");
     }
     catch (Exception ex)
     {
         System.Windows.Forms.MessageBox.Show(ex.Message);
     }
     finally
     {
         if (folderItems != null) Marshal.ReleaseComObject(folderItems);
         if (resultItems != null) Marshal.ReleaseComObject(resultItems);
     }
}

VB.NET and VSTO:

Imports System.Runtime.InteropServices
Imports System.Diagnostics
' ...
Private Sub RestrictCoWorkers(folder As Outlook.MAPIFolder)
    Dim restrictCriteria As String = "[CompanyName] = ""Add-in Express"" "
    Dim strBuilder As StringBuilder = Nothing
    Dim folderItems As Outlook.Items = Nothing
    Dim resultItems As Outlook.Items = Nothing
    Dim contact As Outlook._ContactItem = Nothing
    Dim counter As Integer = 0
    Dim item As Object = Nothing
    Try
        strBuilder = New StringBuilder()
        folderItems = folder.Items
        resultItems = folderItems.Restrict(restrictCriteria)
        For i As Integer = 1 To resultItems.Count
            item = resultItems.Item(i)
            If TypeOf (item) Is Outlook.ContactItem Then
                counter += 1
                contact = item
                strBuilder.AppendLine("#" + counter.ToString() + _
                                      " - Subject: " + contact.Subject)
            End If
            Marshal.ReleaseComObject(item)
        Next
        If (strBuilder.Length > 0) Then
            Debug.WriteLine(strBuilder.ToString())
        Else
            Debug.WriteLine("There is no match in the " _
                             + folder.Name + " folder.")
        End If
    Catch ex As Exception
        System.Windows.Forms.MessageBox.Show(ex.Message)
    Finally
        If Not IsNothing(folderItems) Then Marshal.ReleaseComObject(folderItems)
        If Not IsNothing(resultItems) Then Marshal.ReleaseComObject(resultItems)
    End Try
End Sub

See you on our forums and in the e-mail support!

6 Comments

  • Zach says:

    Hi, can this be made to work in VBA? Right now I’m looping through each contact to see if the .FullName is like a cell value. It takes roughly 10 seconds. If this could speed that up, I’d be a happy camper.

  • Andrei Smolin (Add-in Express Team) says:

    Hello Zach,

    You take the “VB.NET and Add-in Express” example as a base. In VBA you will delete Marshal.ReleaseComObject calls, change the declarations so that they don’t contain the initialization parts, replace Try/Catch/Finally with On Error Goto {a label}, replace Debug.WriteLine with Debug.Print, replace Dim contact As Outlook._ContactItem with Dim contact As Outlook.ContactItem, and replace strBuilder.AppendLine(“a” + “b”) with this construct:

    Dim s as String

    s = s + “a” + “b”

  • Andreas Vogt says:

    Hi,
    I am trying to use this function in my VSTO Project (Visual Studio 2017 and Office 365).
    I would like to call the function from MS-Word via a Ribbon Toolbar to get a List of Outlook contacts from my local MS-Outlook contacts Folder.
    (Later on I would like to insert the address data to my Word-Document..)

    Unfortunatelly I get some errors if I use your solution:

    First I added “Microsoft.Office.Interop.” before each Outlook. – call because I got “Type Oulook.Items is not defined”..

    Then I made the function public not private

    Now If I call the funktion:
    Globals.ThisAddIn.Getoutlookcontacts(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderSuggestedContacts)
    I get “olFoldersuggestedContacts is cannot be converted to MAPI folder”..
    Any ideas?

    thanks

  • Andrei Smolin (Add-in Express Team) says:

    I assume your Getoutlookcontacts() accepts a parameter of the Outlook.MAPIFolder type. If so, you can get the MAPIFolder first and pass it to that method then. E.g. Outlook.Namespace.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderSuggestedContacts).

  • duck says:

    Hi
    could i using restrict method for activeExplorer.selection.
    thinks.

  • Andrei Smolin (Add-in Express Team) says:

    Hello Duck,

    No. That method is only available on the Items and Table objects, see

    https://docs.microsoft.com/en-us/office/vba/api/Outlook.Items.Restrict
    https://docs.microsoft.com/en-us/office/vba/api/outlook.table.restrict

Post a comment

Have any questions? Ask us right now!