Eugene Astafiev

How To: Use Restrict method to retrieve Outlook mail items from a folder

In my previous article I demonstrated how you can use the Find and FindNext methods of the Items class in Outlook. Today I want to show you an alternative way of retrieving Outlook mail items from a folder. As the post’s title suggests, the Restrict method plays the key role in the process.

The Restrict method applies a filter, specified by the passed argument, to the collection. It returns a new collection of items that match the specified filter. Please read more about the filter format string on MSDN.

Again, I would like to draw an analogy with database programming in the. NET world. In ADO.NET, there is the System.Data.SqlClient.SqlDataAdapter class which provides the Fill method. It retrieves data from the specified data source (for instance, a database). The System.Data.DataSet class (it represents an in-memory cache of data) can be used for storing the returned data. I hope you can see the analogy with the Items class in Outlook and its Restrict method ;-) Both methods (Fill from ADO.NET and Restrict from Outlook) are used for retrieving data from the source and storing their results in the collections (DataSet in case of ADO.NET and Items in Outlook).

I have slightly modified the code from my previous article where the Find and FindNext methods were used. I simply replaced them with the Restrict method. Just like in the previous sample, the code iterates over all unread e-mails in the specified folder (see the parameter of the RestrictUnreadItems method) and writes unread e-mails’ subjects to the debug output. Note, you can use the Output window in Visual Studio or the DebugView utility to intercept such output.

C# and Add-in Express:

using System.Text;
using System.Diagnostics;
// ...
private void RestrictUnreadItems(Outlook.MAPIFolder folder)
{
    string restrictCriteria = "[UnRead] = true";
    StringBuilder strBuilder = null;
    Outlook.Items folderItems = null;
    Outlook.Items resultItems = null;
    Outlook._MailItem mail = null;
    int counter = default(int);
    object item = null;
    try
    {
        strBuilder = new StringBuilder();
        folderItems = folder.Items;
        resultItems = folderItems.Restrict(restrictCriteria);
        item = resultItems.GetFirst();
        while (item != null)
        {
            if (item is Outlook._MailItem)
            {
                counter++;
                mail = item as Outlook._MailItem;
                strBuilder.AppendLine("#" + counter.ToString() +
                                   "\tSubject: " + mail.Subject);
            }
            Marshal.ReleaseComObject(item);
            item = resultItems.GetNext();
        }
        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 RestrictUnreadItems(folder As Outlook.MAPIFolder)
    Dim restrictCriteria As String = "[UnRead] = true"
    Dim strBuilder As StringBuilder = Nothing
    Dim folderItems As Outlook.Items = Nothing
    Dim resultItems As Outlook.Items = Nothing
    Dim mail As Outlook._MailItem = Nothing
    Dim counter As Integer = 0
    Dim item As Object = Nothing
    Try
        strBuilder = New StringBuilder()
        folderItems = folder.Items
        resultItems = folderItems.Restrict(restrictCriteria)
        item = resultItems.GetFirst()
        While Not IsNothing(item)
            If TypeOf (item) Is Outlook._MailItem Then
                counter += 1
                mail = item
                strBuilder.AppendLine("#" + counter.ToString() + _
                                     " - Subject: " + mail.Subject)
            End If
            Marshal.ReleaseComObject(item)
            item = resultItems.GetNext()
        End While
        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 RestrictUnreadItems(Outlook.MAPIFolder folder)
{
    string restrictCriteria = "[UnRead] = true";
    StringBuilder strBuilder = null;
    Outlook.Items folderItems = null;
    Outlook.Items resultItems = null;
    Outlook._MailItem mail = null;
    int counter = default(int);
    object item = null;
    try
    {
        strBuilder = new StringBuilder();
        folderItems = folder.Items;
        resultItems = folderItems.Restrict(restrictCriteria);
        item = resultItems.GetFirst();
        while (item != null)
        {
            if (item is Outlook._MailItem)
            {
                counter++;
                mail = item as Outlook._MailItem;
                strBuilder.AppendLine("#" + counter.ToString() +
                                   "\tSubject: " + mail.Subject);
            }
            Marshal.ReleaseComObject(item);
            item = resultItems.GetNext();
        }
        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 RestrictUnreadItems(folder As Outlook.MAPIFolder)
    Dim restrictCriteria As String = "[UnRead] = true"
    Dim strBuilder As StringBuilder = Nothing
    Dim folderItems As Outlook.Items = Nothing
    Dim resultItems As Outlook.Items = Nothing
    Dim mail As Outlook._MailItem = Nothing
    Dim counter As Integer = 0
    Dim item As Object = Nothing
    Try
        strBuilder = New StringBuilder()
        folderItems = folder.Items
        resultItems = folderItems.Restrict(restrictCriteria)
        item = resultItems.GetFirst()
        While Not IsNothing(item)
            If TypeOf (item) Is Outlook._MailItem Then
                counter += 1
                mail = item
                strBuilder.AppendLine("#" + counter.ToString() + _
                                     " - Subject: " + mail.Subject)
            End If
            Marshal.ReleaseComObject(item)
            item = resultItems.GetNext()
        End While
        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!

2 Comments

  • https://secure.gravatar.com/avatar/bfcb7bba04567e47c82cee209ce42bb2?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Vicky says:

    Hi,

    I have also used “Subject” as a filter and it works.
    Is there a way to used the “Sent time” as a filter?
    Basically I want to filter all the mails that were sent/received in last ‘n’ days.

    Thanks in advance :)

  • https://secure.gravatar.com/avatar/29957f26ad2d8ba527fd9cc8cfa7b2e0?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Andrei Smolin (Add-in Express Team) says:

    Hello Vicky,

    You can set a suitable filter (View | View Settings |filter) on a folder and study the filter string on the SQL tab of the Filter dialog. Then you can construct any required filter string.

Post a comment

Have any questions? Ask us right now!