none
How can I reliably find the Associated AppointmentItem RRS feed

  • Question

  • We have a database that is updated when Appointments/Meetings are added, deleted, and updated.  We store custom values in the UserProperty property of these Appointment/MeetingItmes

    Further, the database updates are called from the (CalendarFolder).ItemChange and (SentItemsFolder).ItemAdd event handlers  because the events that trigger these event handlers are fired by Outlook after network connectivity has been restored; which saves us the headache of programming some sort of polling.

    THE PROBLEM:
    Create Meeting and Send it to another person.
    Now Cancel that meeting and send the Cancelation.

    In your "Sent Items" folder you will find the Meeting Cancelation you've just sent.

    In the "Deleted Items" folder you will find the AppointmentItem that has just been deleted from your calendar.



    Is there some combination of properties that I can use to search the DeletedItems folder that will match the AppointmentItem correspeonding to the Canceled MeetingItem in the "Sent Items" folder.


    • Edited by GermanEZI Friday, April 29, 2016 2:29 PM grammar
    Friday, April 29, 2016 2:27 PM

Answers

All replies

  • Hello German,

    You can try to use the GetAssociatedAppointment method of the MeetingItem class which returns an AppointmentItem object that represents the appointment associated with the meeting request.


    [custom.development]

    Friday, April 29, 2016 2:52 PM
  • Hi Eugene, 

    That won't work in this scenario.  Once you've sent your Cancelation message, the appointment is removed from your calendar.

    If you were to try the GetAssociatedAppointment() call from (SentItemsFolder).ItemAdd after the Cancelation, the method would return a NULL value since the Appointment has now been moved to the Deleted Items folder.

    Friday, April 29, 2016 3:00 PM
  • Expected. Then you need to find a corresponding appointment item manually by checking their properties. For example, you may use the Find/FindNext or Restrict methods of the Items class. Take a look at the following articles for more information:

    How To: Retrieve Outlook calendar items using Find and FindNext methods

    How To: Use Restrict method in Outlook to get calendar items

    Note, you can use any low-level property explorer tool such as MFCMAPI or OutlookSpy for viewing hidden property values.


    [custom.development]

    • Marked as answer by GermanEZI Friday, April 29, 2016 5:11 PM
    Friday, April 29, 2016 3:21 PM
  • Thanks,

    That's pretty much what I'm doing now.  Just for the sake of this forum here are a few things that won't work

    ConversationID - Binary field.  You can't search on this.

    GlobalAppointmentID - Same reason as above.  Moreover, the MailItem doesn't have this property

    CreationTime - The values will not necessarily be the same. As time goes my the time difference becomes greater

    LastModificationTime - same as CreationTime

    Subject - This one is tricky.  The problem here is that the Subject of the Meeting item will have the word "Canceled" prepended to it.  Better to use ConversationTopic

    ConversationTopic - You will likely have to continue to refine your search since it's possible to have more the one meeting with the same subject (ConversationTopic is the original Subject it seems)


    It looks like I'll either have to take up writing an Extended MAPI dll myself to get the low-level information that is uniquie, or just convince my boss to get Redemption.

    Being able to search Binary properties would have made this problem a complete no-brainer.

    Friday, April 29, 2016 3:32 PM
  • GlobalAppointmentID is what Outlook itself uses to find the appointments. You are correct that OOM won't let you search for the PT_BINARY properties. You can still loop through all items in a folder (yuck!) or use Redemption (its RDOItems.Find method allows to search on PT_BINARY properties such as GlobalAppointmentID).

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

    Friday, April 29, 2016 4:06 PM
  • Redemption would no doubt make my life simpler.  For now, I'll have to rely on OutlookSpy to dig out whatever internals I can match on.

    Thanks guys!
    Friday, April 29, 2016 5:11 PM
  • If you are stuck with OOM, you can try to search on the subject and then explicitly loop through the returned matches comparing the GlobalAppointmentID property. But if subject changes, looping through all items is your only choice...

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

    Friday, April 29, 2016 5:19 PM
  • Dmitry,

    I think I may have something.  The subject is always a pain, because like you've said ... it can be changed.

    I used outlookSpy and found a few hidden goodies.

    AppointmentItems have a start and end time.  MeetingItems don't.  However, using OutlookSpy and going through the MAPI properties, I've found

    urn:schemas:calendar:dtstart
    urn:schemas:calendar:dtend

    Both the AppointmentItem and MeetingItem have these properties when you search through MAPI.  I'm having a little trouble with the query (I'm trying to get an AND to return results) but, it's still beginning to look promising.

    DateTime start = (DateTime)meetingItem.PropertyAccessor.GetProperty("urn:schemas:calendar:dtstart");
    DateTime end = (DateTime)meetingItem.PropertyAccessor.GetProperty("urn:schemas:calendar:dtend");

    string DASLfilter = "@SQL=\"urn:schemas:calendar:dtstart\" >= '" + start.AddMinutes(-1).ToString("g") + "'"; //DASLfilter+= " AND \"urn:schemas:calendar:dtend\" <= '" + end.AddMinutes(1).ToString("g") + "'"; Outlook.Items search = myDeletedItems.Restrict(DASLfilter);

    When I don't include the AND part of the filter, I get results back;  It's more than I would like, but far better than interating through the entire folder.

    FYI: I pad the minutes because I've heard that Outlook is a little funny with exact times.  I could be wrong. 




    • Edited by GermanEZI Friday, April 29, 2016 6:33 PM Formatting
    Friday, April 29, 2016 6:28 PM
  • My solution.  I'm not thrilled, but it works.  I would like to get that "end" date piece to work, but it keeps returning 0 results.  So here it is.

    (Note:  I should have a seprate object for "PropertyAccessor" so that I can release it with Marshal.ReleaseComObject().  You don't want to get sloppy)

    DateTime start = (DateTime)meetingItem.PropertyAccessor.GetProperty("urn:schemas:calendar:dtstart"); DateTime end = (DateTime)meetingItem.PropertyAccessor.GetProperty("urn:schemas:calendar:dtend"); string DASLfilter = "@SQL=\"urn:schemas:calendar:dtstart\" > '" + start.ToString("g") + "'"; //DASLfilter+= " AND \"urn:schemas:calendar:dtend\" < '" + end.ToString("g") + "'"; Outlook.Items search = myDeletedItems.Restrict(DASLfilter); for (int i = 1; i <= search.Count; i++) { if (search[i] is Outlook._AppointmentItem) { apptItem = (Outlook._AppointmentItem)search[i]; assignmentNumber = VCUtils.GetAssignmentNumber(apptItem); if (string.IsNullOrWhiteSpace(assignmentNumber) == false) { if ( apptItem.ConversationTopic == meetingItem.ConversationTopic ) { // Do database stuff here

    break; } }
    } }

    Since I am searching throught the DeletedItems folders I may not have to worry too much about the size of the result sets since folks do clean out their deleted items more often than their inbox ... I hope :)

    • Edited by GermanEZI Friday, April 29, 2016 7:32 PM Correction
    Friday, April 29, 2016 7:30 PM
  • If you are using DALS property names, your values need to be in UTC.

    But what do you do if the meeting request specified the new start time?


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

    Friday, April 29, 2016 8:57 PM
  • Good question.  Well, in this case the Meeting Request has been canceled.  Of course there's always the possibility that the Organizer updated the start time without sending an update, then subsequently canceled the meeting and sent the notification.

    In this case you're right.  I wouldn't be able to match on date.

    Here, I'm relying on the Business Requirements that won't allow such a thing.

    I've also found that Subjects can be altered without sending out updates and therefore would not be a fool proof item to use for a search.

    Other than what I'm using, I don't know of any other means of associating a canceled meeting in the SentItems folder with their associated AppointmentItems that reside in the deleted Items folder. 

    Monday, May 2, 2016 6:29 PM