How To: Use Restrict method to retrieve Outlook Task items
Today I would like to show you how to filter task items using the Restrict method of the Items class which the Outlook Object Model provides for developers. I am going to include sample codes for those who use VSTO and those who develop with Add-in Express for Office and .net.
In my previous article where I described how to use Outlook Find and FindNext methods for the same task, I mentioned that the Restrict method is faster than Find/FindNext methods in case of large number of items. Don’t forget about this fact when you will be deciding whether to use Restrict or Find/FindNext!
I would like to share the following facts from my experience with you:
- 1. You won’t catch recurrent items if you didn’t sort them in ascending order and set the IncludeRecurrences to True.
- 2. The Count property of the resulting collection of items may return unexpected results.
- 3. Don’t use the for loop for iterating the resulting items collection due to fact #2.
The below code filters items in the Tasks folder according to the defined search criteria. The Subject, PercentComplete and Body properties of returned task items are added to the debug output. You can catch the debug output using the Output window from Visual Studio or using the DebugView utility.
C# & Add-in Express:
using System.Text; using System.Diagnostics; // private void RestrictTaskItems(Outlook.MAPIFolder folder) { string restrictCriteria = "[StartDate]< =\"" + DateTime.Now.ToString("MM/dd/yyyy") + "\"" + " AND [DueDate]>=\"" + DateTime.Now.ToString("MM/dd/yyyy") + "\""; StringBuilder strBuilder = null; Outlook.Items folderItems = null; Outlook.Items resultItems = null; Outlook._TaskItem taskItem = null; int counter = default(int); object item = null; try { strBuilder = new StringBuilder(); folderItems = folder.Items; folderItems.IncludeRecurrences = true; folderItems.Sort("[StartDate]"); resultItems = folderItems.Restrict(restrictCriteria); item = resultItems.GetFirst(); do { if (item != null) { if (item is Outlook._TaskItem) { counter++; taskItem = item as Outlook._TaskItem; strBuilder.AppendLine("#" + counter.ToString() + "\tSubject: " + taskItem.Subject + "\tPercent Complete: " + taskItem.PercentComplete + "\tBody: " + taskItem.Body); } Marshal.ReleaseComObject(item); item = resultItems.GetNext(); } } while (item != null); 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); } }
C# & VSTO:
using System.Runtime.InteropServices; using System.Diagnostics; // private void RestrictTaskItems(Outlook.MAPIFolder folder) { string restrictCriteria = "[StartDate]< =\"" + DateTime.Now.ToString("MM/dd/yyyy") + "\"" + " AND [DueDate]>=\"" + DateTime.Now.ToString("MM/dd/yyyy") + "\""; StringBuilder strBuilder = null; Outlook.Items folderItems = null; Outlook.Items resultItems = null; Outlook._TaskItem taskItem = null; int counter = default(int); object item = null; try { strBuilder = new StringBuilder(); folderItems = folder.Items; folderItems.IncludeRecurrences = true; folderItems.Sort("[StartDate]"); resultItems = folderItems.Restrict(restrictCriteria); item = resultItems.GetFirst(); do { if (item != null) { if (item is Outlook._TaskItem) { counter++; taskItem = item as Outlook._TaskItem; strBuilder.AppendLine("#" + counter.ToString() + "\tSubject: " + taskItem.Subject + "\tPercent Complete: " + taskItem.PercentComplete + "\tBody: " + taskItem.Body); } Marshal.ReleaseComObject(item); item = resultItems.GetNext(); } } while (item != null); 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 & Add-in Express:
Imports System.Diagnostics Imports System.Text ' Private Sub RestrictTaskItems(folder As Outlook.MAPIFolder) Dim restrictCriteria As String = "[StartDate]< =\" + _ DateTime.Now.ToString("MM/dd/yyyy") + _ "\" + " AND [DueDate]>=\" + _ DateTime.Now.ToString("MM/dd/yyyy") + "\" Dim strBuilder As StringBuilder = Nothing Dim folderItems As Outlook.Items = Nothing Dim resultItems As Outlook.Items = Nothing Dim taskItem As Outlook._TaskItem = Nothing Dim counter As Integer = 0 Dim item As Object = Nothing Try strBuilder = New StringBuilder() folderItems = folder.Items folderItems.IncludeRecurrences = True folderItems.Sort("[StartDate]") resultItems = folderItems.Restrict(restrictCriteria) item = resultItems.GetFirst() Do If Not IsNothing(item) Then If (TypeOf (item) Is Outlook._TaskItem) Then counter = counter + 1 taskItem = item strBuilder.AppendLine("#" + counter.ToString() + _ " Subject: " + taskItem.Subject + _ " Percent Complete: " + taskItem.PercentComplete.ToString() + _ " Body: " + taskItem.Body) End If Marshal.ReleaseComObject(item) item = resultItems.GetNext() End If Loop Until IsNothing(item) 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
VB.NET & VSTO:
Imports System.Diagnostics Imports System.Runtime.InteropServices ' Private Sub RestrictTaskItems(folder As Outlook.MAPIFolder) Dim restrictCriteria As String = "[StartDate]< =\" + _ DateTime.Now.ToString("MM/dd/yyyy") + _ "\" + " AND [DueDate]>=\" + _ DateTime.Now.ToString("MM/dd/yyyy") + "\" Dim strBuilder As StringBuilder = Nothing Dim folderItems As Outlook.Items = Nothing Dim resultItems As Outlook.Items = Nothing Dim taskItem As Outlook._TaskItem = Nothing Dim counter As Integer = 0 Dim item As Object = Nothing Try strBuilder = New StringBuilder() folderItems = folder.Items folderItems.IncludeRecurrences = True folderItems.Sort("[StartDate]") resultItems = folderItems.Restrict(restrictCriteria) item = resultItems.GetFirst() Do If Not IsNothing(item) Then If (TypeOf (item) Is Outlook._TaskItem) Then counter = counter + 1 taskItem = item strBuilder.AppendLine("#" + counter.ToString() + _ " Subject: " + taskItem.Subject + _ " Percent Complete: " + taskItem.PercentComplete.ToString() + _ " Body: " + taskItem.Body) End If Marshal.ReleaseComObject(item) item = resultItems.GetNext() End If Loop Until IsNothing(item) 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
If you want to learn the Outlook Object Model from the ground I would recommend using the Object Browser which comes with the VBA environment. You can read more about this in the Getting help with COM objects, properties and methods section of the online documentation.
See you on our forums and in the e-mail support!
7 Comments
Is it nessesary to use DoWhile loop to iterate through the items? I’ve found that simple for(i = 1; i < resultItems.Count; i++) works in 1.5 times faster (by RedGate Profiler results).
Hi Mikhail,
Thank you for your comment.
Of course, it is not necessary to use the Do/While loop to iterate through the items. I used it as an example, but you can use any other loop instead.
thanks for telling me how to sort… outlook items…
Hey .. if i want to filter all the tasks that have “no” due date .. how would i do that? In the above example, i tried doing [DueDate]=”None” and [Due]=”No Date” and both of them didn’t work. Can you please help me out here.
Hello KP,
Try restrictCriteria = “Not [DueDate] < \01/01/4501\".
how do i filter tasks u8sing the task id?
Hello Linta,
You cannot use the EntryID field in Restrict; see https://msdn.microsoft.com/en-us/library/office/ff869597(v=office.15).aspx. If you have the EntryID of a task, you can find it using Namespace.GetItemFromID(); see https://msdn.microsoft.com/en-us/library/office/ff869893(v=office.15).aspx.