Getting All of a Day's Appointments in Microsoft Outlook

Jim Groves
Microsoft Corporation

Applies To: Microsoft® Outlook® 2000

October 1999

Summary: Getting access to a user's appointments for a given day can be complicated by the presence of recurring appointments on the user's calendar, especially if just one of the recurrences does not have an end date. This article shows how to retrieve all the appointments for a given day while avoiding some common pitfalls. (3 printed pages)

Introduction

Most, if not all, programmers who work with the Microsoft® Outlook® Calendar end up trying to determine which appointments on the Calendar fall on a particular day. Although at first glance that might seem to be a simple task, there are a couple of stumbling blocks that can trip up the unwary developer: the trick to specifying a particular day and the problem of recurring appointments.

The first of these stumbling blocks occurs when a programmer relies on intuition rather than logic. The intuitive way to request the appointments for a given day is to filter on the Start property of the AppointmentItem object, setting it to the day you're interested in, as shown in this example:

strToday = "[Start] = '07/01/99'"
Set myAppts = myAppts.Restrict(strToday)

The problem with this is that the Start property expects a date and a time. If the time portion is omitted, Outlook assumes that the starting time of the appointment is the beginning of the work day. Unless you have a meeting the first thing in the morning, the resulting collection will be empty.

To successfully isolate the appointments that fall on a particular day, you must specify the span of time in which the appointments start, as shown in this example:

strToday = _
    "[Start] >= '07/01/99 12:00 am' and [Start] <= '07/01/99 11:59 pm'"
Set myAppts = myAppts.Restrict(strToday)

This will return an Items collection that contains all the appointments that occur on July 1, 1999, unless there are recurring appointments that fall on that day. To make sure that recurring appointments are included in the collection, you must sort the collection by start time and then set the IncludeRecurrences property of the collection to True before you apply any filters, as in this example:

myAppts.Sort "[Start]"
myAppts.IncludeRecurrences = True
strToday = _
    "[Start] >= '07/01/99 12:00 am' and [Start] <= '07/01/99 11:59 pm'"
Set myAppts = myAppts.Restrict(strToday)

The resulting myAppts collection will contain all the appointments that fall on July 1, 1999. However, it might also exhibit one very strange characteristic: The Count property of the collection might be set to 2,147,483,647! (If you're one of those people who think in hexadecimal, you will recognize this as &H7FFFFFFF, the highest positive integer that can be expressed using 32 bits.) In other words, the collection appears to be infinite!

Fortunately, that's not really the case. It's just that when the Calendar contains any recurring appointments without an end date and the IncludeRecurrences property of the collection is set to True, the Count property of the resulting collection and of all collections that derive from it returns this impossibly high number. However, any derived collections (such as those that result from using the Restrict method) will contain only the desired appointments. You just have to be careful not to use the Count property in a loop, unless you want to tie up Outlook for a very long time.

The following example shows the correct way to display all the appointments that fall on a given day. It prompts the user for the date to be displayed, forms the filter string by using that input, and then uses the IncludeRecurrences and Restrict methods to ensure that the collection contains the correct appointments. Finally, it uses a For Each . . . Next loop to extract the individual appointments from the collection.

Sub ShowDaysAppointments()
    Dim myOlApp As New Outlook.Application
    Dim myAppt As AppointmentItem
    Dim myNS As NameSpace
    Dim myAppts As Items
    Dim strTheDay As String
    Dim strToday As String
    Dim strMsg As String

    ' Get the day from the user. User can enter 
    ' date in nearly any format.
    strTheDay = _
        InputBox("Enter the day for which you want " _
           & "to see appointments")
    ' Specify the range.
    strToday = "[Start] >= '" & strTheDay & _
        "' and [Start] < '" & strTheDay & " 11:59 pm'"
    ' Get user's appointments from Calendar folder.
    Set myNS = myOlApp.GetNamespace("MAPI")
    Set myAppts = myNS.GetDefaultFolder(olFolderCalendar).Items
    ' Sort the collection (required by IncludeRecurrences).
    myAppts.Sort "[Start]"
    ' Make sure recurring appointments are included.
    myAppts.IncludeRecurrences = True
    ' Filter the collection to include only the day's appointments.
    Set myAppts = myAppts.Restrict(strToday)
    ' Sort it again to put recurring appointments in correct order.
    myAppts.Sort "[Start]"
    ' Loop through collection and get subject and 
    ' start time of each item.
    Set myAppt = myAppts.GetFirst
    Do While TypeName(myAppt) <> "Nothing"
        strMsg = strMsg & vbLf & myAppt.Subject
        strMsg = strMsg & " at " & Format(myAppt.Start, "h:mm ampm")
        Set myAppt = myAppts.GetNext
    Loop
    ' Display the information.
    MsgBox "Your appointments for " & strTheDay & " are " _
            & vbLf & strMsg

    Set myOlApp = Nothing
    Set myAppt = Nothing
    Set myNS = Nothing
    Set myAppts = Nothing
End Sub

The important thing to remember is not to use the Count property with a For . . . Next loop when dealing with collections of AppointmentItem objects that include recurring appointments, or to depend on it to give you an accurate number of items in the collection. Other methods of enumerating the collection (such as For Each . . . Next and the GetFirst and GetNext methods) should work fine, however.