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

问题描述 投票:0回答:1

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

获取我使用Items.Restrict(字符串过滤器)预过滤的日历的所有约会项目只能从今天或更新获取项目是没有问题的。我的搜索模式看起来像这样:

"[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。

如果我当天没有其他约会,那就行了(返回null,而不是从第二天开始预约)。

我已经用时间格式检查了问题(dd.MM.yyyy与dd / MM / yyyy等),所以我猜这不是行为的原因(如果我使用'/'秒,那么搜索模式从明天返回约会,如果我使用'。',则返回今天的约会。

我的搜索模式错了吗?我是否监督某些事情,还是时间格式在背景中有所不同?

有任何想法吗?谢谢。

编辑

可能是,这个过滤是错误的吗?我复制了一个由微软(msdn)制作的例子。无论我做什么,Outlook.Items.count(在Restrict()之前和之后)始终是2147483647.但是当我输出限制项时,For-Each运行5次。

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

所有项目 - >受[开始]>现在限制 - >受[开始]> = 08:00限制 - >结果:2013年以后的任何事情...... - .-

c# search design-patterns outlook find
1个回答
0
投票

因为Items.Find()函数似乎是错误的或至少没有能力处理比“1和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;
}

要回到下一个免费的时间跨度。

由于这个解决方案似乎有点慢,有没有人有更好,更快的想法?

编辑:

如果我记得最后一次触摸约会的掠夺字典中的位置继续从这个位置搜索,我可以加快速度。这应该有效,因为Plunder按日期排序。

© www.soinside.com 2019 - 2024. All rights reserved.