Eugene Astafiev

How To: Use Outlook Find and FindNext methods to retrieve Task items

In my previous articles I described how to use Find and FindNext methods to retrieve Outlook mail items, contact and calendar items. Now I am going to show you how to apply the Find and FindNext methods for Outlook task items. Note, Microsoft suggests using these methods because they are faster than Restrict in case you have a small number of items in the collection. So, let’s start!

The nature of Outlook task items is a bit different than calendar items. Please pay attention to the fact with task items the Start date and Due date fields can be empty. The time doesn’t play any role here, only the date. In the sample code below I assume that task items in your profile have these fields set. The code iterates over all alive today’s tasks (not completed yet) and writes the subject, percent complete and body properties of the particular task to the debug output (see the Debug.WriteLine method for more details).

Also, keep in mind that Outlook tasks may be recurrent. That is why I set the IncludeRecurrences property to true in the code. You will not catch recurrent tasks if you don't do this before using the Find/FindNext methods!

C# & Add-in Express:

private void GetTodayTasks(Outlook.MAPIFolder folder)
{
    string searchCriteria = "[StartDate]< =\"" + DateTime.Now.ToString("MM/dd/yyyy") + 
                             "\"" + " AND [DueDate]>=\"" +
                              DateTime.Now.ToString("MM/dd/yyyy") + "\"";
    StringBuilder strBuilder = null;
    int counter = default(int);
    Outlook._TaskItem taskItem = null;
    Outlook.Items folderItems = null;
    object resultItem = null;
    try
    {
        folderItems = folder.Items;
        folderItems.IncludeRecurrences = true;
        if (folderItems.Count > 0)
        {
            resultItem = folderItems.Find(searchCriteria);
            if (resultItem != null)
            {
                strBuilder = new StringBuilder();
                do
                {
                    if (resultItem is Outlook._TaskItem)
                    {
                        counter++;
                        taskItem = resultItem as Outlook._TaskItem;
                        if (taskItem.Status != Outlook.OlTaskStatus.olTaskComplete)
                        {
                            strBuilder.AppendLine("#" + counter.ToString() +
                                "\tSubject: " + taskItem.Subject +
                                "\tPercent Complete: " + taskItem.PercentComplete +
                                "\tBody: " + taskItem.Body);
                        }
                   }
                   Marshal.ReleaseComObject(resultItem);
                   resultItem = folderItems.FindNext();
               }
               while (resultItem != null);
           }
       }
       if (strBuilder != null)
           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);
    }
}

C# & VSTO:

using System.Diagnostics;
using System.Runtime.InteropServices;
// ...
private void GetTodayTasks(Outlook.MAPIFolder folder)
{
    string searchCriteria = "[StartDate]< =\"" + DateTime.Now.ToString("MM/dd/yyyy") + 
                            "\"" + " AND [DueDate]>=\"" +
                             DateTime.Now.ToString("MM/dd/yyyy") + "\"";
    StringBuilder strBuilder = null;
    int counter = default(int);
    Outlook._TaskItem taskItem = null;
    Outlook.Items folderItems = null;
    object resultItem = null;
    try
    {
        folderItems = folder.Items;
        folderItems.IncludeRecurrences = true;
        if (folderItems.Count > 0)
        {
            resultItem = folderItems.Find(searchCriteria);
            if (resultItem != null)
            {
                strBuilder = new StringBuilder();
                do
                {
                    if (resultItem is Outlook._TaskItem)
                    {
                        counter++;
                        taskItem = resultItem as Outlook._TaskItem;
                        if (taskItem.Status != Outlook.OlTaskStatus.olTaskComplete)
                        {
                            strBuilder.AppendLine("#" + counter.ToString() +
                                "\tSubject: " + taskItem.Subject +
                                "\tPercent Complete: " + taskItem.PercentComplete +
                                "\tBody: " + taskItem.Body);
                        }
                    }
                    Marshal.ReleaseComObject(resultItem);
                    resultItem = folderItems.FindNext();
                }
                while (resultItem != null);
            }
        }
        if (strBuilder != null)
            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);
    }
}

VB.NET & Add-in Express:

Imports System.Text
Imports System.Diagnostics
' ...
Private Sub GetTodayTasks(ByRef folder As Outlook.MAPIFolder)
    Dim searchCriteria As String = "[StartDate]< =\" + DateTime.Now.ToString("MM/dd/yyyy") + _ 
                                   "\" + " AND [DueDate]>=\" + _
                                    DateTime.Now.ToString("MM/dd/yyyy") + "\"
    Dim strBuilder As StringBuilder = Nothing
    Dim counter As Integer = 0
    Dim taskItem As Outlook._TaskItem = Nothing
    Dim folderItems As Outlook.Items = Nothing
    Dim resultItem As Object = Nothing
    Try
        folderItems = folder.Items
        folderItems.IncludeRecurrences = True
        If (folderItems.Count > 0) Then
            resultItem = folderItems.Find(searchCriteria)
            If Not IsNothing(resultItem) Then
                strBuilder = New StringBuilder()
                Do
                    If (TypeOf (resultItem) Is Outlook._TaskItem) Then
                        counter += 1
                        taskItem = resultItem
                        If Not (taskItem.Status = Outlook.OlTaskStatus.olTaskComplete) Then
                            strBuilder.AppendLine("#" + counter.ToString() + _
                               " Subject: " + taskItem.Subject + _
                               " Percent Complete: " + taskItem.PercentComplete.ToString() + _
                               " Body: " + taskItem.Body)
                        End If
                    End If
                    Marshal.ReleaseComObject(resultItem)
                    resultItem = folderItems.FindNext()
                Loop Until IsNothing(resultItem)
            End If
        End If
        If Not IsNothing(strBuilder) 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)
    End Try

VB.NET & VSTO:

Imports System.Runtime.InteropServices
Imports System.Diagnostics
' ...
Private Sub GetTodayTasks(ByRef folder As Outlook.MAPIFolder)
    Dim searchCriteria As String = "[StartDate]< =\" + DateTime.Now.ToString("MM/dd/yyyy") + _
                                   "\" + " AND [DueDate]>=\" + _
                                   DateTime.Now.ToString("MM/dd/yyyy") + "\"
    Dim strBuilder As StringBuilder = Nothing
    Dim counter As Integer = 0
    Dim taskItem As Outlook._TaskItem = Nothing
    Dim folderItems As Outlook.Items = Nothing
    Dim resultItem As Object = Nothing
    Try
        folderItems = folder.Items
        folderItems.IncludeRecurrences = True
        If (folderItems.Count > 0) Then
            resultItem = folderItems.Find(searchCriteria)
            If Not IsNothing(resultItem) Then
                strBuilder = New StringBuilder()
                Do
                    If (TypeOf (resultItem) Is Outlook._TaskItem) Then
                        counter += 1
                        taskItem = resultItem
                        If Not (taskItem.Status = Outlook.OlTaskStatus.olTaskComplete) Then
                            strBuilder.AppendLine("#" + counter.ToString() + _
                               " Subject: " + taskItem.Subject + _
                               " Percent Complete: " + taskItem.PercentComplete.ToString() + _
                               " Body: " + taskItem.Body)
                        End If
                    End If
                    Marshal.ReleaseComObject(resultItem)
                    resultItem = folderItems.FindNext()
                Loop Until IsNothing(resultItem)
            End If
        End If
        If Not IsNothing(strBuilder) 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)
    End Try
End Sub

As you may see the only difference between VSTO and Add-in Express based source code is using (C#)/Import (VB.NET) declaration of namespaces at the beginning of the code. Also the property name which returns an instance of the Application is different (OutlookApp is used in case of Add-in Express based add-ins and Application in VSTO).

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

4 Comments

  • Mar says:

    When choosing between Restrict and Find, what is considered a “large” or “small” number of items?

  • Eugene Astafiev says:

    Hi Mar,

    The “large” number means hundreds or thousands items in the list. The Restrict method is faster than Find/FindNext especially if a few items are expected to be found in the large collection.

  • Anand says:

    Hi,
    I have been trying to search the address book of Outlook programmtically. For that if i use “Item” method, search query only matches with the Display name where as i would like to search for an “Alias” in the Address book. In the dialogue box while searching address book, there is an option of “More Columns”. But i really don’t understand how that can be accesses programmatically. Could you please tell me how can i search for a particular “Alias” in address book.

  • Eugene Astafiev says:

    Hi Anand,

    Please try to use the AdvancedSearch method of the Outlook Application class as shown in the Advanced search in Outlook programmatically: C#, VB.NET article.

Post a comment

Have any questions? Ask us right now!