How To: Use Restrict method in Outlook to get calendar items
I described how to use Find and FindNext methods against calendar items in my previous post. Today I would like to take closer look at how to deal with calendar items using the Restrict method. In fact, this method can make you tear your hair out because of some aspects or limitations coming from the Outlook Object Model. I’d spent half a day debugging the code and investigating the issue until I found the cause.
Firstly, to retrieve all Outlook appointment items from the folder that meets the predefined condition, you need to sort the items in ascending order and set the IncludeRecurrences to true. You will not catch recurrent appointments if you don’t do this before using the Restrict method!
Secondly, Microsoft doesn’t recommend using the Count property in case you set the IncludeRecurrences property. The Count property may return unexpected results and cause an infinite loop.
Thirdly, I would recommend using the do/while or foreach loops for iterating found items. The for loop can’t be used because the Count property of the Items class may return unexpected results.
The sample code does exactly the same job we did with the Find/FindNext methods in my previous post – collects all appointments that are:
- currently in the process (were started earlier);
- going to begin and end at the specified time (in the middle of our timeline);
- start before the end border and end after the specified time (outside of the specified time).
As you remember I took the current time as the start time and midnight as the end time.
C# and Add-in Express:
using System.Text; using System.Diagnostics; // ... private void RestrictCalendarItems(Outlook.MAPIFolder folder) { DateTime dtEnd = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 23, 59, 00, 00); string restrictCriteria = "[Start]<=\"" + dtEnd.ToString("g") + "\"" + " AND [End]>=\"" + DateTime.Now.ToString("g") + "\""; StringBuilder strBuilder = null; Outlook.Items folderItems = null; Outlook.Items resultItems = null; Outlook._AppointmentItem appItem = null; int counter = default(int); object item = null; try { strBuilder = new StringBuilder(); folderItems = folder.Items; folderItems.IncludeRecurrences = true; folderItems.Sort("[Start]"); resultItems = folderItems.Restrict(restrictCriteria); item = resultItems.GetFirst(); do { if (item != null) { if (item is Outlook._AppointmentItem) { counter++; appItem = item as Outlook._AppointmentItem; strBuilder.AppendLine("#" + counter.ToString() + "\tStart: " + appItem.Start.ToString() + "\tSubject: " + appItem.Subject + "\tLocation: " + appItem.Location); } 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 and Add-in Express:
Imports System.Text Imports System.Diagnostics ' ... Private Sub RestrictCalendarItems(folder As Outlook.MAPIFolder) Dim dtEnd As DateTime = New DateTime(DateTime.Now.Year, DateTime.Now.Month, _ DateTime.Now.Day, 23, 59, 0, 0) Dim restrictCriteria As String = "[Start]<=""" + dtEnd.ToString("g") + """" + _ " AND [End]>=""" + DateTime.Now.ToString("g") + """" Dim strBuilder As StringBuilder = Nothing Dim folderItems As Outlook.Items = Nothing Dim resultItems As Outlook.Items = Nothing Dim appItem As Outlook._AppointmentItem = Nothing Dim counter As Integer = 0 Dim item As Object = Nothing Try strBuilder = New StringBuilder() folderItems = folder.Items folderItems.IncludeRecurrences = True folderItems.Sort("[Start]") resultItems = folderItems.Restrict(restrictCriteria) item = resultItems.GetFirst() Do If Not IsNothing(item) Then If (TypeOf (item) Is Outlook._AppointmentItem) Then counter = counter + 1 appItem = item strBuilder.AppendLine("#" + counter.ToString() + _ " Start: " + appItem.Start.ToString() + _ " Subject: " + appItem.Subject + _ " Location: " + appItem.Location) 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
C# and VSTO:
using System.Diagnostics; using System.Runtime.InteropServices; // ... private void RestrictCalendarItems(Outlook.MAPIFolder folder) { DateTime dtEnd = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 23, 59, 00, 00); string restrictCriteria = "[Start]<=\"" + dtEnd.ToString("g") + "\"" + " AND [End]>=\"" + DateTime.Now.ToString("g") + "\""; StringBuilder strBuilder = null; Outlook.Items folderItems = null; Outlook.Items resultItems = null; Outlook._AppointmentItem appItem = null; int counter = default(int); object item = null; try { strBuilder = new StringBuilder(); folderItems = folder.Items; folderItems.IncludeRecurrences = true; folderItems.Sort("[Start]"); resultItems = folderItems.Restrict(restrictCriteria); item = resultItems.GetFirst(); do { if (item != null) { if (item is Outlook._AppointmentItem) { counter++; appItem = item as Outlook._AppointmentItem; strBuilder.AppendLine("#" + counter.ToString() + "\tStart: " + appItem.Start.ToString() + "\tSubject: " + appItem.Subject + "\tLocation: " + appItem.Location); } 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 and VSTO:
Imports System.Diagnostics Imports System.Runtime.InteropServices ' ... Private Sub RestrictCalendarItems(folder As Outlook.MAPIFolder) Dim dtEnd As DateTime = New DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 23, 59, 0, 0) Dim restrictCriteria As String = "[Start]<=""" + dtEnd.ToString("g") + """" + _ " AND [End]>=""" + DateTime.Now.ToString("g") + """" Dim strBuilder As StringBuilder = Nothing Dim folderItems As Outlook.Items = Nothing Dim resultItems As Outlook.Items = Nothing Dim appItem As Outlook._AppointmentItem = Nothing Dim counter As Integer = 0 Dim item As Object = Nothing Try strBuilder = New StringBuilder() folderItems = folder.Items folderItems.IncludeRecurrences = True folderItems.Sort("[Start]") resultItems = folderItems.Restrict(restrictCriteria) item = resultItems.GetFirst() Do If Not IsNothing(item) Then If (TypeOf (item) Is Outlook._AppointmentItem) Then counter = counter + 1 appItem = item strBuilder.AppendLine("#" + counter.ToString() + _ " Start: " + appItem.Start.ToString() + _ " Subject: " + appItem.Subject + _ " Location: " + appItem.Location) 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
You can use the Output window in Visual Studio when debugging the code or the DebugView utility to see the results.
See you on our forums and in the e-mail support!
3 Comments
Hello, just a quick note that there’s a type in your example, [Start]< = should be <=. Thanks.
Hi Josh,
Thank you for pointing out this misprint. Fixed!
You made my day! I tried for one day now to include recurrencies and filter/restrict the result with some strange results. Including the line “Sort(“[Start]”)” solved the issue completely. WTF… Thx!!!