Retrieve current Outlook appointment

6.8k views Asked by At

I need the current appointment. If no current appointment then the next or even previous appointment.

I figure to use Restrict to limit the set of appointments, and then choose either the first or last appointment depending on the restrict argument (e.g. Restrict to appointments ending after current time, or appointments starting before current time).

I'm having trouble with the string filter needed as argument.

A simple VB example (code stump):

myStart = Format(Date, "mm/dd/yyyy hh:mm AMPM")    
strRestriction = "[Start] <= '" & myStart & "'"

'Restrict the Items collection
Set oResItems = oItems.Restrict(strRestriction)
'Sort
oResItems.Sort "[Start]"

I am attempting to do the same in C#.

// Create the Outlook application.
Outlook.Application oApp = new Outlook.Application();

// Get the NameSpace and Logon information.
// Outlook.NameSpace oNS = (Outlook.NameSpace)oApp.GetNamespace("mapi");
Outlook.NameSpace oNS = oApp.GetNamespace("mapi");

//Log on by using a dialog box to choose the profile.
oNS.Logon(Missing.Value, Missing.Value, true, true);

// Get the Calendar folder.
Outlook.MAPIFolder oCalendar = oNS.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderCalendar);

// Get the Items (Appointments) collection from the Calendar folder.
oItems = oCalendar.Items;
oItems.IncludeRecurrences = true;

// THIS IS THE PROBLEM AREA
String filter = "[Start] <= '" + DateTime.Now.ToString("MM/dd/yyyy hh:mm AMPM") + "'";
Outlook.Items restrictedItems = oItems.Restrict(filter);
// Take the last item on the list - should be current or next appointment
restrictedItems.Sort("[Start]");
Outlook.AppointmentItem oAppt = restrictedItems.GetLast();


// Done. Log off.
oNS.Logoff();

I imagine since the filter is a string, the date format needs to be yyyy/mm/dd HH:mm:ss? I can't find any documentation on how to manipulate the [Start], like parsing it to a date or something.

Depending on the date format, I will either get the wrong appointment, or will be unable to use GetLast due to the filter excluding all appointments.

I've seen examples, but either they loop through the appointments (too inefficient), or the date formats look like they can't be trusted to return the correct appointment (For example https://social.msdn.microsoft.com/Forums/vstudio/en-US/c6a8bd21-6534-43be-b23e-1068651da92e/retrieve-appointment-items-from-outlook-2007-calendar-restrict?forum=vsto, which seems to have the date hardcoded instead if using DateTime.Now.)

UPDATE: I'm currently looping through like shown below. Any suggestions for more efficient code?

DateTime currentTime = DateTime.Now;
foreach (Outlook.AppointmentItem item in oItems)
{
    if (item.Start <= currentTime && item.End.Subtract(new TimeSpan(0, 10, 0)) > currentTime)
    {
        appointmentArrayList.Add(item);
    }
}
4

There are 4 answers

1
Boris On BEST ANSWER

By following the information found here, I was able to get it to work using "yyyy-MM-dd HH:mm" as the format string for the toString call.

Hope this helps.

1
Papun Sahoo On

This code works to show Outlook appointments from today onwards:

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        DemoAppointmentsInRange();
    }

    private void DemoAppointmentsInRange()
    {
        Application a = new Application();
        Microsoft.Office.Interop.Outlook.Folder calFolder = a.Session.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderCalendar) as Microsoft.Office.Interop.Outlook.Folder;
        DateTime start = DateTime.Now;
        DateTime end = start.AddDays(5);
        Microsoft.Office.Interop.Outlook.Items rangeAppts = GetAppointmentsInRange(calFolder, start, end);
        if (rangeAppts != null)
        {
            foreach (Microsoft.Office.Interop.Outlook.AppointmentItem appt in rangeAppts)
            {
               Response.Write("Subject: " + appt.Subject + " "+" Start: "+appt.Start.ToString()+" "+"End:"+appt.End.ToString()+"<br/>");
            }
        }
    }
    private Microsoft.Office.Interop.Outlook.Items GetAppointmentsInRange(
    Microsoft.Office.Interop.Outlook.Folder folder, DateTime startTime, DateTime endTime)
    {
        string filter = "[Start] >= '"+ startTime.ToString("g")+ "' AND [End] <= '"  + endTime.ToString("g") + "'";
        //Response.Write(filter);
        try
        {
            Microsoft.Office.Interop.Outlook.Items calItems = folder.Items;
            calItems.IncludeRecurrences = true;
            calItems.Sort("[Start]", Type.Missing);
            Microsoft.Office.Interop.Outlook.Items restrictItems = calItems.Restrict(filter);
            if (restrictItems.Count > 0)
            {
                return restrictItems;
            }
            else
            {
                return null;
            }
        }
        catch
        {
            return null;
        }
    }
}
0
Kevin On

This is your issue:

DateTime.Now.ToString("MM/dd/yyyy hh:mm AMPM")

What I think you're going for is:

DateTime.Now.ToString("MM/dd/yyyy hh:mm tt", CultureInfo.InvariantCulture)
0
Dejan Dozet On

I couldn't figure out DateTime format, but I found this article:

https://learn.microsoft.com/en-us/office/vba/outlook/how-to/search-and-filter/filtering

Then I realized that they have a concept called "DASL Queries", reading furthermore I found this related to filtering with DateTime:

https://learn.microsoft.com/en-us/office/vba/outlook/how-to/search-and-filter/filtering-items-using-a-date-time-comparison

And I've decided to get all today's AppointmentItem(s) this way:

  public enum MacroName
    {
      today,
      tomorrow,
      yesterday,
      next7days,
      last7days,
      nextweek,
      thisweek,
      lastweek,
      nextmonth,
      thismonth,
      lastmonth
    }

    private Outlook.Items GetAppointmentsWithMacro(Outlook.Folder folder, MacroName macro)
    {

      string strFilter = "@SQL=%" + macro.ToString() + "(\"urn:schemas:calendar:dtstart\")%";

      try
      {
        Outlook.Items calItems = folder.Items;
        calItems.IncludeRecurrences = true;
        calItems.Sort("[Start]", Type.Missing);
        Outlook.Items restrictItems = calItems.Restrict(strFilter);
        if (restrictItems.Count > 0)
        {
          return restrictItems;
        }
        else
        {
          return null;
        }
      }
      catch { return null; }
    }

I want to be safest as possible because it seems that filtering by DateTime is related to local DateTime settings. By using the "today" macro I was able for the first time to extract the correct information from Outlook appointments store