'VSTO Outlook How to get the previous AppointmentItem in a chain of AppointmentItems within recurring meetings

I am currently developing an Outlook Addin for AppointmentItem. In case the AppointmentItem is a member of a recurring meeting "chain" I want to retrieve/find the AppointmentItem which is the previous meeting. How can I do that?

I figured out the following part-solution:

Outlook.AppointmentItem item = (Outlook.AppointmentItem)inspector.CurrentItem;
if (item.IsRecurring) {
    Outlook.RecurrencePattern pattern = item.GetRecurrencePattern(); 
    Outlook.OlRecurrenceType occurenceType = pattern.RecurrenceType;
    int dayFactor = 0;
    switch (occurenceType) {
        case Outlook.OlRecurrenceType.olRecursDaily:                            
           dayFactor = 1;
           break;
        case Outlook.OlRecurrenceType.olRecursWeekly:
        default:
           dayFactor = 7;
           break;
        // TODO handly all other cases of RecurrenceType
    }
    Outlook.AppointmentItem lastItem = pattern.GetOccurrence(item.StartInStartTimeZone.AddDays(-1*pattern.Interval*dayFactor));                         

But this handles only very few "easy" cases. Especially when it comes to calculate e.g. every first tuesday per month it gets too tricky for me. Any input? This code sample might be usefull, too: http://www.outlookcode.com/codedetail.aspx?id=1414



Solution 1:[1]

In fact I found an answer which is a little bit inefficient but very powerfull as you don't have to care about any recurring rules outlook may have. First any recurring rule does not change the time of the occurence meaning that recurring appointments take place at the very same point in time during the day. Second

GetOcurrences(DateTime) 

throws an exception if there is no AppointmentItem at the given DateTime.

And finally the RecurrencePattern gives you the

PatternStartDate

So all what you need to do is check each and every day backwards, beginning at the given AppointmentItem and ending at PatternStartDate.

This is my implementation which of course can be written better, but it works well:

if (myAppointment.IsRecurring)
{
    Outlook.RecurrencePattern pattern = myAppointment.GetRecurrencePattern();

    bool doContinue = true;
    Outlook.AppointmentItem lastAppointmentItem = null ;

    int currentDay = -1;
    while (doContinue) {
        try
        {
            DateTime currentDate = myAppointment.StartInStartTimeZone.AddDays(currentDay);
            if (currentDate < pattern.PatternStartDate)
            {
                doContinue = false;
                lastAppointmentItem = null;
            }
            else
            {
                lastAppointmentItem = pattern.GetOccurrence(currentDate);
                if (lastAppointmentItem != null)
                {
                    doContinue = false;
                }
                else
                {
                    currentDay -= 1;
                }
            }
        }
        catch (Exception ex)
        {
            currentDay -= 1;
        }

    }
....

The same approach can be used to create an Array of all Orccurences. It'll take some time to calculate all and I don't know how to handle open ended series. But that was not the question for this stackoverflow item.

Solution 2:[2]

Not easily. You'd need to expand the series explicitly in your code taking into account the recurrence pattern and the exceptions or you can try all suspect dates until GetOccurrence succeeds.

If using Redemption (I am its author) is an option, its version of RDORecurrencePattern.GetOccurrence method allow to pass an integer index (besides the date a-la OOM) as a parameter, so you can build an array of occurrences.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 HHeckner
Solution 2