Get Outlook AppointmentItem using GlobalAppointmentID

852 Views Asked by At

I am developing a calendar for my firm that synchronizes with Outlook Calendar.

Atm I can:

  • import appointments from Outlook and show them in my calendar
  • update my appointments when Outlook appointments get updated
  • create Outlook appointments when appointments get created in my calendar

The only issue I have is updating/deleting Outlook appointments when my appointments update/delete.

I have the GlobalAppointmentID of the corresponding appointments but I can't seem to search on that ID.

I tried:

using Microsoft.Office.Interop;

private void GetAppointment(string myGlobalAppointmentID)
{
Outlook.Application oApp = new Outlook.Application();

Outlook.NameSpace mapiNamespace = oApp.GetNamespace("MAPI");

Outlook.MAPIFolder calendarFolder = mapiNamespace.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderCalendar);
Outlook.Items outlookCalendarItems = calendarFolder.Items;

Outlook.AppointmentItem appointmentItem = (Outlook.AppointmentItem)outlookCalendarItems.Find("[GlobalAppointmentID] = '{0}'", myGlobalAppointmentID));

//update or delete appointmentItem here (which I know how to do)
}

I keep getting 'Condition is not valid' Exception. Apparently Outlook does not allow to search on binary properties (such as GlobalAppointmentID).

I use the same outlookCalendarItems.Find() and calendarFolder.Items.Restrict() without problems in other instances.

I tried using Redemption but I couldn't get it to work either. Does anybody have experience or a suggestion?

3

There are 3 best solutions below

0
On BEST ANSWER

What I ended up doing after looking further: I added a text UserProperty where I put the GlobalAppointmentID("GAID") in. You can Filter on those. And it seems to do the trick.

private void AddGAIDIfNeeded(Outlook.AppointmentItem app)
        {
            bool GAIDexists = false;
            if (app.UserProperties.Count != 0)
            {
                foreach (UserProperty item in app.UserProperties)
                {
                    if (item.Name == "GAID")
                    {
                        GAIDexists = true;
                        break;
                    }
                }
            }

            if (GAIDexists == false)
            {
                app.UserProperties.Add("GAID", Outlook.OlUserPropertyType.olText);
                app.UserProperties["GAID"].Value = app.GlobalAppointmentID;
                app.Save();
            }
        }

And to find a specific AppointmentItem:

private void DeleteOutlookAppointmentByGAID(string globalAppointmentID)
        {
            Outlook.Application oApp = new Outlook.Application();
            Outlook.NameSpace mapiNamespace = oApp.GetNamespace("MAPI");
            Outlook.MAPIFolder calendarFolder = mapiNamespace.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderCalendar);
            Outlook.Items outlookCalendarItems = calendarFolder.Items;

            try
            {
                Outlook.AppointmentItem appointmentItem = null;
                appointmentItem = outlookCalendarItems.Find(String.Format("[GAID] = '{0}'", globalAppointmentID));

                if (appointmentItem != null)
                {
                    appointmentItem.Delete();
                }
            }
            catch (Exception ex)
            {
                classExecptionLogging.LogErrorToFolder(ex);
            }

        }
0
On

Yes, OOM won't let you search on binary properties (as well as recipients or attachments), but Redemption (I am its author) should work. The following script (VBA) worked just fine for me:

  set Session = CreateObject("Redemption.RDOSession")
  Session.MAPIOBJECT = Application.Session.MAPIOBJECT
  set Folder = Session.GetDefaultFolder(olFolderCalendar)
  set appt = Folder.Items.Find("GlobalAppointmentID = '040000008200E00074C5B7101A82E00800000000D0FECEE58FEAD70100000000000000001000000041C887A3FA12694F8A0402FEFFAD0BBB'")
  MsgBox appt.Subject
1
On

The Outlook object model doesn't support searching for binary properties such as GlobalAppointmentId (any other PT_BINARY property) with Items.Find/Items.FindNext/Items.Restrict.

The only workaround is to loop through all item in the Calendar folder (which is inefficient) or search using Extended MAPI (or using third-party wrappers such as Redemption.