Outlook.Interop Items.Find()似乎不正确

时间:2018-09-04 13:46:29

标签: c# search design-patterns outlook find

我想在网络中的Outlook日历和共享日历中搜索约会,以检查不同日历中是否有空闲时间。

获取使用我使用Items.Restrict(string Filter)预过滤的日历的所有约会项,以仅从Today或更高版本中获取项目是没有问题的。我的搜索模式如下:

"[Start] >= '" + DateTime.Today.ToString("dd.MM.yyyy HH:mm") + "' AND [End] <= '" + DateTime.Parse("01.01.2019").ToString("dd.MM.yyyy HH:mm") + "'";

一切正常(时间格式dd.MM.yyyy与dd / MM / yyyy出现问题,但这已解决)。

拿到物品后,我将搜索它们以检查约会时间是否空闲,这表示:如果开始时间或结束时间与约会重叠,或者在任何时间的开始时间和结束时间之间存在约会然后,如果找到日历,则返回该约会,否则返回null。

这是我的搜索模式({0}是临时开始时间,{1}是临时结束时间):

"(([Start] <= '{0}' AND '{0}' <= [End]) OR 
([Start] <= '{1}' AND '{1}' <= [End])) OR 
(('{0}' <= [Start] AND [Start] <= '{1}') OR 
('{0}' <= [End] AND [End] <= '{1}'))";

为进行测试,我今天从08:00到08:30进行了约诊,并搜索了下一个约见于15:18开始的约会。 因此,搜索应该返回null,因为它不会找到时间重叠,但是会从早上返回测试约会。

如果我用自己的时间和找到的约会的时间替换搜索字符串中的值({0}-> 15:18,{1}-> 16:18,[开始]-> 08:00, [结束]-> 08:30)我明白了:

((04.09.2018 08:00:00 <= '04.09.2018 15:25:09' AND '04.09.2018 15:25:09' <= 04.09.2018 08:30:00) OR (04.09.2018 08:00:00 <= '04.09.2018 16:25:09' AND '04.09.2018 16:25:09' <= 04.09.2018 08:30:00)) 
OR (('04.09.2018 15:25:09' <= 04.09.2018 08:00:00 AND 04.09.2018 08:00:00 <= '04.09.2018 16:25:09') OR ('04.09.2018 15:25:09' <= 04.09.2018 08:30:00 AND 04.09.2018 08:30:00 <= '04.09.2018 16:25:09'))

检查逻辑语句:

//False OR False is False
(
    //False OR False is False
    (
        //True AND False is False
        (
            //Is True
            04.09.2018 08:00:00 <= '04.09.2018 15:25:09' 
            AND 
            //Is False
            '04.09.2018 15:25:09' <= 04.09.2018 08:30:00
        ) 
        OR 
        //True AND False is False
        (
            //Is True
            04.09.2018 08:00:00 <= '04.09.2018 16:25:09'
            AND 
            //Is False
            '04.09.2018 16:25:09' <= 04.09.2018 08:30:00
        )
    ) 
    OR
    //Fals OR Fals is False 
    (
        //False AND True is False
        (
            //Is Fale
            '04.09.2018 15:25:09' <= 04.09.2018 08:00:00 
            AND 
            //Is True
            04.09.2018 08:00:00 <= '04.09.2018 16:25:09'
        ) 
        OR 
        //False AND True is False
        (
            //Is False
            '04.09.2018 15:25:09' <= 04.09.2018 08:30:00 
            AND 
            //Is True
            04.09.2018 08:30:00 <= '04.09.2018 16:25:09'
        )
    )
)

我只是不明白为什么该搜索模式针对该约会甚至在检查时间附近都返回True的原因。

如果我当天没有其他约会,则它可以正常工作(返回空值,而不是第二天的约会)。

我已经检查了时间格式的问题(dd.MM.yyyy与dd / MM / yyyy等),所以我想这不是问题的起因(如果我在秒中使用“ /”,则搜索模式会从明天返回一个约会,如果我在秒中使用“。”,则返回今天的约会。

我的搜索模式是否错误?是我监督了什么,还是时间格式在后台起作用?

有什么想法吗?谢谢。

编辑

此筛选是否有问题?我复制粘贴了Microsoft(msdn)制作的示例。无论我做什么,Outlook.Items.count(在Restrict()之前和之后)始终为2147483647。但是,当我输出受限制的项目时,每次运行5次。

当我阅读MAPI文件夹时,我用“ [开始]> = DateTime.Now.ToString(“ g”)”对项目进行预排序,对它们进行排序,然后查看第一个具有Date> =的项目,现在,我用另一个过滤器限制此限制项目,当我查看限制限制项目中的第一个项目时,我得到了一个5年前的日期。

所有项目->受[开始]限制>现在->受[开始]限制> = 08:00->结果:2013年以来的所有内容... -.-

1 个答案:

答案 0 :(得分:0)

因此,因为Items.Find()函数似乎有错误,或者至少没有能力处理比“ 1 AND 1”更复杂的事情,所以我不得不写一个“小解决方法”(我不喜欢它,如果有很多约会,似乎有点慢)来解决这个问题:

这是从我的日历或共享日历中获取约会项的功能(因为.Find()过滤器似乎在这里起作用,因此我对这些项进行了过滤,这样我就不会再收到旧约会或将来的约会了) :

Dictionary<DateTime, DateTime> Plunder = new Dictionary<DateTime, DateTime>();
int AppointLength = 60;    

private void GetCalendar(object username, bool Shared)
{
    Outlook.MAPIFolder oCalendar;
    Outlook.Application oApp = new Outlook.Application();
    Outlook.NameSpace oNS = oApp.GetNamespace("mapi");
    oNS.Logon(Missing.Value, Missing.Value, true, true);

    if (Shared)
    {
        Outlook.Recipient oRecip = oNS.CreateRecipient((string)username);
        oCalendar = oNS.GetSharedDefaultFolder(oRecip, Outlook.OlDefaultFolders.olFolderCalendar);
    }
    else
    {
        oCalendar = oNS.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderCalendar);
    }

    Outlook.Items oItems = oCalendar.Items;
    oItems.IncludeRecurrences = true;
    oItems.Sort("[Start]");

    string strRestriction = "[Start] >= '" + DateTime.Today.ToString("g") + "' AND [End] <= '" + dtpEndDate.Value.ToString("g") + "'";

    Outlook.Items allNew = oItems.Restrict(strRestriction);

    allNew.Sort("[Start]");

    foreach (Outlook.AppointmentItem appt in allNew)
    {
        if (Plunder.ContainsKey(appt.Start))
        {
            if (Plunder[appt.Start] < appt.End)
            {
                Plunder[appt.Start] = appt.End;
            }
        }
        else
        {
            Plunder.Add(appt.Start, appt.End);
        }
    }
}

当我想在比来字典中搜索所有日历中的所有约会项目之后

private DateTime CheckForAppointment(DateTime now)
{
    DateTime then = now.AddMinutes(AppointLength);

    var AppointmentFound = Plunder.Select(i => i).Where(d => 
        ((d.Key < now && now < d.Value) 
        || (d.Key < then && then < d.Value)) 
        || ((now < d.Key && d.Key < then) 
        || (now < d.Value && d.Value < then)));

    if (AppointmentFound.Any())
    {
        now = CheckForAppointment(((KeyValuePair<DateTime, DateTime>)AppointmentFound.First()).Value);
    }

    return now;
}

要获取下一个空闲时间段。

由于此解决方案似乎有点慢,所以有人有更好,更快的主意吗?

编辑:

如果我记得最后一次碰到的约会在“抢劫字典”中的位置,可以继续从该位置进行搜索,则可以提高速度。这应该起作用,因为掠夺者按日期排序。

相关问题