'Editing an appointment programmatically
I'm using Microsoft.Office.Interop.Outlook to load appointments into the interface and to edit appointments . I can load appointments completely fine, editing does work but not 100% of the time. Sometimes I get the error The operation cannot be performed because the message has been changed
May I ask is there a better approach for editing appointments to avoid The operation cannot be performed because the message has been changed
error. Error occurs when trying to Save()
public Outlook.AppointmentItem EditOutlookAppointment(CustomAppointment appointment, int retries = 0)
{
Outlook.AppointmentItem appointReturned = null;
try
{
Outlook.Application outlookApp = new Outlook.Application();
MAPIFolder calendarFolder = outlookApp.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderCalendar);
for (int i = calendarFolder.Items.Count; i > 0; i--)
{
var appointmentItem = ((Outlook.AppointmentItem)calendarFolder.Items[i]);
if (appointmentItem.GlobalAppointmentID == appointment.UniqueId)
{
// set some properties
appointmentItem.Subject = appointment.Subject;
appointmentItem.Body = appointment.Body;
appointmentItem.Location = appointment.Location; //Set the location
appointmentItem.Start = appointment.Start;
appointmentItem.End = appointment.End;
appointmentItem.Save();
return appointmentItem;
}
}
}
catch (Exception ex)
{
//Error message implementation here
}
return appointReturned;
}
Solution 1:[1]
Firstly, errors like that are unavoidable - it means the appointment was modified between the time Outlook opened it and the time you called Save. And since Outlook really likes to cache the appointments (it always caches the appointment being edited in Outlook or the previously edited appointment), that period of time can be quite large. This can happen if the appointment was modified by the Exchange server itself or by an incoming meeting update processing.
Secondly, looping through all items in the Calendar folder can be a huge performance problem. Unfortunately Outlook won't let you search (Items.Find/FindNext
and Items.Restrict
) on binary (PT_BINARY) properties such as GlobalAppointmentID
. You'd need to use Extended MAPI (C++ or Delphi) or Redemption (I am its author - any language) for this: (RDOtems.Find/FindNext/Restrict
in Redemption allow to search on binary properties).
UPDATE. The following should work using Redemption (off the top of my head):
publicRedemption.RDOAppointmentItem EditOutlookAppointment(CustomAppointment appointment, int retries = 0)
{
try
{
Outlook.Application outlookApp = new Outlook.Application();
Redemption.RDOSession session = new Redemption.RDOSession();
session.MAPIOBJECT = outlookApp.Session.MAPIOBJECT; //share the Outlook session
RDOFolder calendarFolder = session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderCalendar);
Redemption.RDOAppointmentItem appointmentItem = calendarFolder.Items.Find("GlobalAppointmentID = '"+appointment.UniqueId + "'");
if (appointmentItem != null)
{
// set some properties
appointmentItem.Subject = appointment.Subject;
appointmentItem.Body = appointment.Body;
appointmentItem.Location = appointment.Location; //Set the location
appointmentItem.Start = appointment.Start;
appointmentItem.End = appointment.End;
appointmentItem.Save();
return appointmentItem;
}
}
catch (Exception ex)
{
//Error message implementation here
}
return null;
}
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 |