none
Cannot get current delete exception date from recurrence pattern RRS feed

  • Question

  • Hi,

    I am working on a outlook sync application which syncs the appointment changes to database. In that, in ItamChange event I am trying to update the database with changes including the recurrence changes. The issue is, when ever I delete a recurrence occurrence, outlook fires ItemChange event. But when I try to get deleted occurrence, I cannot get current one but all the other delete occurrences. When I delete another occurrence in the series then I get previously deleted occurrence. Following is the code that I've written. Please help...

    if(recurPatt.Exceptions != null)
    {
    	logDebug("[Items_ItemChange] - Has exceptions");
    	for (int idx = 1; idx <= recurPatt.Exceptions.Count; idx++)
    	{
    		Outlook.Exception exep = recurPatt.Exceptions[idx];
    		if (exep.Deleted)
    		{
    			logDebug("[Items_ItemChange] - Delete exception: " + exep.OriginalDate);
    			logDebug("[Items_ItemChange] - OriginalDate FRMT: " + exep.OriginalDate.ToString("yyyyMMddTHHmmssZ"));
    			var dt = exep.OriginalDate;
    			dt = dt.AddHours(recurPatt.StartTime.Hour);
    			dt = dt.AddMinutes(recurPatt.StartTime.Minute);
    			logDebug("[Items_ItemChange] - Delete exception FRMT: " + dt.ToString("yyyyMMddTHHmmssZ"));
    
    			rp.ExceptFor(dt);
    		}
    		else
    		{
    
    			if (exep.AppointmentItem != null)
    			{
    				logDebug("[Items_ItemChange] - Has excep appointment with Subject: " + exep.AppointmentItem.Subject);
    			}
    		}
    	}
    }

    This code goes under ItemChange event. Another interesting point is, if I create an exception to series (not delete) then I get the exception appointmentitem.  

    Also, how do I differentiate between parent and recurrence exception appointment. The both are having same GlobalAppointmentId?
    Monday, March 13, 2017 2:38 PM

Answers

  • Hello Pradeep,

    Making changes in the ItemChange event handler is not a good idea. The event can be fired recursively.

    When you work with recurring appointment items, you should release any prior references, obtain new references to the recurring appointment item before you access or modify the item, and release these references as soon as you are finished and have saved the changes. This practice applies to the recurring AppointmentItem object, and any Exception or RecurrencePattern object. To release a reference in Visual Basic for Applications (VBA) or Visual Basic, set that existing object to Nothing. In C#, explicitly release the memory for that object. Use System.Runtime.InteropServices.Marshal.ReleaseComObject to release an Outlook object when you have finished using it. Then set a variable to Nothing in Visual Basic (null in C#) to release the reference to the object. Read more about that in the Systematically Releasing Objects article.

    Note that even after you release your reference and attempt to obtain a new reference, if there is still an active reference, held by another add-in or Outlook, to one of the above objects, your new reference will still point to an out-of-date copy of the object. Therefore, it is important that you release your references as soon as you are finished with the recurring appointment.


    profile for Eugene Astafiev at Stack Overflow, Q&A for professional and enthusiast programmers

    Monday, March 13, 2017 2:46 PM
  • Do not use events for any kind of sync. They are designed for the UI purposes, not any kind of synchronization.

    You can use the events as hints to run your sync sooner rather that later, but do not rely on them as the sole driver of your sync logic.


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    Monday, March 13, 2017 4:16 PM

All replies

  • Hello Pradeep,

    Making changes in the ItemChange event handler is not a good idea. The event can be fired recursively.

    When you work with recurring appointment items, you should release any prior references, obtain new references to the recurring appointment item before you access or modify the item, and release these references as soon as you are finished and have saved the changes. This practice applies to the recurring AppointmentItem object, and any Exception or RecurrencePattern object. To release a reference in Visual Basic for Applications (VBA) or Visual Basic, set that existing object to Nothing. In C#, explicitly release the memory for that object. Use System.Runtime.InteropServices.Marshal.ReleaseComObject to release an Outlook object when you have finished using it. Then set a variable to Nothing in Visual Basic (null in C#) to release the reference to the object. Read more about that in the Systematically Releasing Objects article.

    Note that even after you release your reference and attempt to obtain a new reference, if there is still an active reference, held by another add-in or Outlook, to one of the above objects, your new reference will still point to an out-of-date copy of the object. Therefore, it is important that you release your references as soon as you are finished with the recurring appointment.


    profile for Eugene Astafiev at Stack Overflow, Q&A for professional and enthusiast programmers

    Monday, March 13, 2017 2:46 PM
  • Hi Eugene,

    Thanks for the reply. But I have one question. As I said I need to sync all the changes to a database. That includes the ItemRemove, Delete as well as any changes to the mail content. Some times user can right click and delete the appointment or cancel a meeting request. In that case can you guide me towards better way without using ItemChange and ItemRemove also BeforeDelete. In that case I don't need to keep the itemcollection in the global.

    Many Thanks

    Pradeep

    Monday, March 13, 2017 3:24 PM
  • Do not use events for any kind of sync. They are designed for the UI purposes, not any kind of synchronization.

    You can use the events as hints to run your sync sooner rather that later, but do not rely on them as the sole driver of your sync logic.


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    Monday, March 13, 2017 4:16 PM
  • Hi Dimitry,

    Thanks for the tip, I made changes to code so that I don't use this event anymore. I am using Application_ItemLoad event to hookup the BeforeDelete event for the appointment item. Following is the code;

    private void Application_ItemLoad(object Item)
    {
    	logDebug("[Application_ItemLoad] - Fired");
    	if(Item is Outlook.AppointmentItem)
    	{
    		(Item as Outlook.AppointmentItem).BeforeDelete += AItem_BeforeDelete;
    	}
    }

    Later I am using a timer to sync the updates to database. I am getting the updates by applying the filter on the items collection. But even now, I am not getting the last deleted time of the recurrence occurrence.

    Apart from that, when there is an exception to recurrence both master and olApptOccurrence having same EntryId as well as GlobalAppointmentId. The only way is the difference between properties like subject or time or body etc. Is there any better way to handle master and occurrence separately?

    Tuesday, March 14, 2017 6:12 AM