Outlook Restrict方法按组织者筛选日历约会无返回结果求助
问题根源排查
- 第一,你当前代码的遍历逻辑错误:筛选后得到的是
RestrItems集合,但你的循环里写的是Appointment := Items.Item(i);,用了未筛选的原始Items集合,这会导致就算筛选规则生效,你输出的还是全部约会,甚至可能因为两个集合数量不一致报错。 - 第二,直接用
[requiredAttendees] = 'Joe Bloggs'匹配不到的原因:requiredAttendees字段存储的是所有必填参会人的分号拼接字符串,比如格式为Joe Bloggs;张三;李四,只有当仅该用户一个必填参会人时才会匹配成功,大部分场景下都匹配不到。 - 第三,你当前用的MAPI属性筛选逻辑是对的,但要注意大小写匹配问题,Outlook的SQL筛选默认是大小写敏感的,如果要忽略大小写可以用
ci_startswith或者ci_phrasematch操作符,或者统一转成小写匹配。
修正后的完整代码
Namespace := Outlook.GetNamespace('MAPI'); // represents a NameSpace object. Recipient := Namespace.CreateRecipient('shared@mailbox.com'); Recipient.Resolve; Folder := Namespace.GetSharedDefaultFolder(Recipient, olFolderCalendar); Items := Folder.Items; Items.Sort('[Start]', true); Items.IncludeRecurrences := true; // 方案1:用requiredAttendees模糊匹配,忽略大小写 RestrictString := '@SQL="http://schemas.microsoft.com/mapi/proptag/0x0E04001F" ci_phrasematch ''joe bloggs'''; // 如果你是要严格匹配组织者而非必填参会人,用下面的方案2更准确: // RestrictString := '@SQL="http://schemas.microsoft.com/mapi/proptag/0x0065001F" ci_phrasematch ''joe bloggs'''; RestrItems := Items.Restrict(RestrictString); Memo1.clear; if (RestrItems.count = 0) then Memo1.lines.add('No appointments'); // 遍历筛选后的RestrItems集合,而非原始Items for i := 1 to RestrItems.count do begin Appointment := RestrItems.Item(i); Memo1.lines.add(' '); Memo1.lines.add(Appointment.requiredAttendees); Memo1.lines.add(Appointment.subject); Memo1.lines.add(Appointment.Start); Memo1.lines.add(Appointment.End); Memo1.lines.add(' '); end; Outlook := UnAssigned;
注:方案2里用到的
0x0065001F是组织者显示名称对应的MAPI属性ID,如果你要筛选的是会议的实际组织者,而非参会人列表里的用户,用这个属性筛选更准确,不会把其他会议里该用户作为必填参会人的结果也匹配出来。
如果需要同时保留你之前的日期筛选,直接用AND把两个条件拼接在RestrictString里即可。
内容的提问来源于stack exchange,提问作者Tarryn
相关产品推荐
相关产品推荐

