none
Finding which recurring appointment changed in ItemChange event RRS feed

  • Question

  • When I modify a recurring appointment my ItemChange (for the calendar folder's Items) is passed the master appointment item, as expected.  If I then grab the recurrence pattern and loop through the Exceptions I see all of the changes. I'm not sure how to handle two problems.

    1) The exception only gives me the original Start date.  How do I know what the original End date was?

    2) I'm not seeing how to identify which of the items in the Exception list is the one that was just modified.

    Thursday, January 30, 2014 11:31 PM

Answers

  • You have to be prepared for some events firing multiple times. For example, item.PropertyChange on a contact will fire multiple times if you change FirstName, as that affects other properties such as FullName and FileAs.

    As long you eventually get an event that does what you want you just have to process the other events as quickly as possible so you don't miss the event you want.


    Ken Slovak MVP - Outlook

    Thursday, February 6, 2014 2:54 PM
    Moderator

All replies

  • Hi Scott,

    Did you want to know the end data of recurring appointment? If I understand correctly, you can get the original end date via RecurrencePattern.PatternEndDate.

    >> I'm not seeing how to identify which of the items in the Exception list is the one that was just modified.<<There is no such method we can track the appointment item that which we modified before.

    Below article may be helpful:
    How to: Create an Exception Appointment in a Recurring Appointment Series

    Best regards
    Fei


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.


    Friday, January 31, 2014 3:10 AM
    Moderator
  • When an appointment is selected in the Explorer and fires an Explorer.SelectionChange() event you can check the item and if it's recurring you can grab the Exceptions collection and if the item is changed you can compare the contents of Exceptions to see what was added.

    Similarly, when an appointment is opened it will fire Inspectors.NewInspector(). Once the first Activate() event fires on the Inspector the Inspector.CurrentItem will be a strong object reference and you can check that for recurrence and the Exceptions collection.


    Ken Slovak MVP - Outlook

    Friday, January 31, 2014 3:55 PM
    Moderator
  • Thanks, Ken.  I'm very slowly trying to parse this in my head and implement in code.  Some of these items are new to me so I'm doing lots of research before I come back and ask for clarifications.

    Tuesday, February 4, 2014 6:01 PM
  • Ken, I'm just not getting something here.  I tried the below code to grab the selected item but it seems to get lost frequently.  By the time the ItemChange method is called the selection has been blanked out.

            private void activeExplorer_SelectionChange()
            {
                this.originalAppointmentExceptions.Clear();
    
                var selectedItems = this.activeExplorer.Selection;
                try {
                    foreach (object o in selectedItems) {
                        try {
                            var appt = o as Outlook.AppointmentItem;
                            if (!(appt != null && appt.BusyStatus == Outlook.OlBusyStatus.olOutOfOffice && appt.IsRecurring))
                                continue;
    
                            // If they select multiple occurrences of a recurring meeting, they will all
                            // have the same EntryID, so we only need to store one copy of it.
                            if (this.originalAppointmentExceptions.ContainsKey(appt.EntryID))
                                continue;
    
                            var recurrence = appt.GetRecurrencePattern();
                            var exceptions = recurrence.Exceptions;
    
                            try {
                                var copy = new List<Outlook.Exception>();
    
                                foreach (Outlook.Exception ex in recurrence.Exceptions)
                                    copy.Add(ex);
    
                                this.originalAppointmentExceptions[appt.EntryID] = copy;
                            } finally {
                                Marshal.FinalReleaseComObject(exceptions);
                                Marshal.FinalReleaseComObject(recurrence);
                            }
                        } finally {
                            Marshal.FinalReleaseComObject(o);
                        }
                    }
                } finally {
                    Marshal.FinalReleaseComObject(selectedItems);
                }
            }

    When ItemChange fires, I frequently see that this.originalAppointmentExceptions.Count is 0.

    Tuesday, February 4, 2014 11:04 PM
  • If the count of exceptions is 0 when the SelectionChange() event fires, is that accurate? What about when the ItemChange() event fires?

    Could other changes have been made that didn't create an Exception item?

    What do you mean by the selection having been blanked out?


    Ken Slovak MVP - Outlook

    Wednesday, February 5, 2014 3:21 PM
    Moderator
  • The selection going to 0 seems to have been my fault, so that's fixed now.  

    However, the issue now is that when I right-click on a calendar item and choose to delete an instance of a recurring appointment, the SelectionChange fires again and I get an exception on the GetRecurrencePattern() call saying I've deleted an instance of the item and it no longer exists.  

    Also, the EntryID of the appointment changes as soon as I delete one of the instances, so I'm not sure how this SelectionChange method ends up helping me the way you intended as I don't see how I related the recurrences I've stored here to the recurrences I look up in the ItemChange event.

    Wednesday, February 5, 2014 5:00 PM
  • Items in Exchange stores change the EntryID when they are deleted or moved to another folder. Items in PST file stores don't change the EntryID in those circumstances. The behavior is store dependent.

    In this case I'd probably grab something else instead of EntryID, for example the Start date of the instance. That can always be checked against an Exception.OriginalDate property for comparison purposes.

    You have to be prepared to handle both expected and unexpected errors. If you change an instance's start date or delete the instance you won't get it back except by iterating the Exceptions collection.


    Ken Slovak MVP - Outlook

    Wednesday, February 5, 2014 6:02 PM
    Moderator
  • In this case I'd probably grab something else instead of EntryID, for example the Start date of the instance. That can always be checked against an Exception.OriginalDate property for comparison purposes.

    Ken Slovak MVP - Outlook

    But the problem I'm facing is that when I select an appointment that is recurring, I don't get the actual instance as the selection, I get the master appointment item, correct?  So I can't store the start date of the selected item.

    Also, once I delete the appointment instance, the SelectionChange method seems to be called again, and when I call GetRecurrence() on the AppointmentItem that I find in the selection, an exception is thrown.

    Wednesday, February 5, 2014 7:10 PM
  • Check  it out, run a test.

    Set up a test recurring daily appointment starting today and running for 10 days and select the 3rd instance. Then in the Outlook use this VBA code in the VBA project's Immediate window:

    ? Application.ActiveExplorer.Selection.Item(1).Start

    If you select the first instance you'd get today, if the 3rd instance is selected you'd get the 7th.

    That shows that you get the expected instance start but the EntryID would be the same for all the instances.


    Ken Slovak MVP - Outlook

    Wednesday, February 5, 2014 7:26 PM
    Moderator
  • I was under the wrong assumption the item passed to the selection event was the master appointment item.  Didn't realize it was an actual instance.  Thanks!

    I'm definitely making progress here. 

    When ItemChange gets called against the default calendar folder items, I'm seeing it's a recurring item and then looping through the Exceptions on the recurrence pattern.  I created a daily recurring item and deleted a couple of the individual instances.

    When the ItemChange even runs, it seems to get the master appointment item, not the instance.  I then grab the recurrence pattern and exceptions, but the Count property of the exceptions is always 0.  If I deleted two instances of the recurrence, shouldn't there be two expections there?

    Wednesday, February 5, 2014 9:40 PM
  • Yes, 2 deletions == 2 exceptions.

    How many times is ItemChange() firing? Does it ever fire at a time when there are 2 exceptions?


    Ken Slovak MVP - Outlook

    Wednesday, February 5, 2014 10:04 PM
    Moderator
  • It's firing multiple times apprently.  When I read your message I went and deleted a third item.  This time it said 3 exceptions.  Then I deleted a 4th item right after that and it fired 3 more times, each one saying 3 exceptions.

    Wednesday, February 5, 2014 10:29 PM
  • You have to be prepared for some events firing multiple times. For example, item.PropertyChange on a contact will fire multiple times if you change FirstName, as that affects other properties such as FullName and FileAs.

    As long you eventually get an event that does what you want you just have to process the other events as quickly as possible so you don't miss the event you want.


    Ken Slovak MVP - Outlook

    Thursday, February 6, 2014 2:54 PM
    Moderator