1
votes

So, essentially, what I'm trying to do is delete all appointments in Outlook that match a certain pattern (it's a simple one so there's no need for a Regex).

So, I use the following code to retrieve every item in the calendar using interop.

Outlook.Application outlook = new Outlook.Application();
Outlook.NameSpace mapiNameSpace = outlook.GetNamespace("MAPI");
Outlook.MAPIFolder calendarFolder = mapiNameSpace.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderCalendar);
Outlook.Items outlookCalendarItems = calendarFolder.Items;

And then the following code to iterate over and delete them:

foreach (Outlook.AppointmentItem appointment in outlookCalendarItems)
{
     if (appointment.Subject.Contains("On Call: Regions:"))
     {
          appointment.Delete();
     }
}

However, for some reason some of the items seem to get deleted and some of them get missed with no obvious pattern to why. The Subject of each appointment is generated in the same way for each appointment (in a different part of the application):

appt.Subject = $"On Call: {appointment.Region}";

Where appointment.Region is generated using:

Region = $"Regions: {regions.Aggregate((x, y) => x + " & " + y)}"

Which results in:

On Call: Regions: 6 & 7

On Call: Regions: NS

etc...

So if it's working for some, it should be working for all.

Any ideas?

1

1 Answers

2
votes

If deleting from the items collection you have to delete from the end to the beginning best using indexer. That means if you delete an item it is removed from the items collection and sent to the deleted folder.

This is documented for example in the MSDN

If you don't do it this way but iterate from the beginning the item is removed and the one after this replaces it. So most likely you are skipping an entry. If the following item would also comply to your filter you would not delete it. That explains why you find it on the second run.
This is not a .net collection. You are using an interop wrapper. It can behave differently from what you expect in c#.

For example try this. According to documentation the index is 1-based. Not 0-based - but better double check yourself as I can not currently test this myself:

for (int i = outlookCalenderItems.Count; i > 0; i--)
{
     if (outlookCalenderItems[i].Subject.Contains("On Call: Regions:"))
     {
          outlookCalenderItems[i].Delete();
     }
}