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
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.
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”
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
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).
Hi
could i using restrict method for activeExplorer.selection.
thinks.
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