Получить текущую встречу с Outlook

Я пишу программу, которая проверяет перспективы встреч, и в основном мне просто нужно текущее назначение - и если нет текущего назначения, то просто следующее или даже предыдущее назначение.

Я полагаю, что для этого мне нужно использовать [метод ограничения][1], чтобы ограничить набор встреч, а затем просто выбрать первое или последнее назначение в зависимости от аргумента ограничения (например, ограничиться только встречами, заканчивающимися после текущего времени, или только встречи, начинающиеся до текущего времени). У меня много проблем с фильтром String, необходимым в качестве аргумента.

Простой пример VB (фрагмент кода) выглядит следующим образом ([источник][2])

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]"

Однако попытка сделать то же самое в 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();

Прежде всего, я представляю, что поскольку фильтр является строкой, формат даты должен быть гггг / мм / дд чч: мм: сс? И я не могу найти какую-либо документацию о том, как манипулировать [Start], например, разбирать его на дату или что-то еще (и я пробовал все виды вещей, но ничего не работает). В зависимости от формата даты, который я использую, я либо получу неправильную встречу, либо программа не сможет использовать GetLast из-за фильтра, исключающего все встречи.

Google больше не может мне помочь, ребята, я видел несколько примеров людей, утверждающих, что они заставили его работать, но либо они перебирают встречи (слишком неэффективно), либо форматы даты выглядят так, что им нельзя доверять возвращать правильное назначение (например, этот парень social.msdn.microsoft.com/Forums/en-US/vsto/thread/c6a8bd21-6534-43be-b23e-1068651da92e, который, кажется, вместо этого жестко закодировал дату при использовании DateTime.Now..)

ОБНОВЛЕНИЕ: Я решил, что больше не хочу тратить впустую время, пытаясь поработать над углом Ограничения, поэтому сейчас я просто повторяю цикл, как показано ниже, но любые предложения по более эффективному коду приветствуются.

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 ответа

Решение

Следуя информации, найденной здесь, я смог заставить ее работать, используя "yyyy-MM-dd HH:mm" в качестве строки формата для вызова toString.

Надеюсь это поможет.

Это ваша проблема:

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

Я думаю, что вы собираетесь это:

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

Этот код работает для отображения встреч Outlook с сегодняшнего дня:

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;
        }
    }
}

Я не мог понять формат DateTime, но нашел эту статью:

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

Затем я понял, что у них есть концепция под названием «Запросы DASL», читая, кроме того, я обнаружил, что это связано с фильтрацией с помощью DateTime:

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

И я решил получить все сегодняшние элементы AppointmentItem следующим образом:

        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; }
    }

Я хочу быть максимально безопасным, потому что кажется, что фильтрация по DateTime связана с локальными настройками DateTime. С помощью макроса «сегодня» я впервые смог извлечь правильную информацию из хранилища встреч Outlook.

Другие вопросы по тегам