使用 VBA 运行一个或多个帐户的 Outlook 规则
运行所有帐户的所有邮件的所有规则;也可用作 Outlook 规则调试工具。
引言
一个小型 VBA 项目,用于运行所有活动 IMAP 和 Exchange 帐户的 Outlook 本地和服务器端规则。规则同时应用于已读和未读邮件。
背景
几个月前,当我的 Exchange 规则在 Outlook 2007 的收件箱中不再运行时,我开始调查此事。当它在全新安装(新的配置文件和重新创建的规则)的 Outlook 2016 中再次出现时,我非常不满需要启动“规则和通知”对话框,选择我的 Exchange 帐户,单击“立即运行规则”,在每个规则旁边打勾,然后单击“立即运行”。尽管其他人也报告了此问题,但 Microsoft 和我的托管 Exchange 提供商都无法提供指导,这让我感到沮丧。
经过大量的搜索,我偶然发现了 OutlookCode.com,Sue Mosher 在 2006 年发表了一篇标题为 Run all rules against inbox. 的文章。这正是我一直在寻找的。现在,我可以通过一个添加到“开发工具”选项卡的按钮,或者一个添加到“快速访问工具栏”的类似按钮来运行我的规则。
过了一会儿,我意识到我希望这个宏能做更多事情。我的标准 Outlook 配置文件中有八个(是的,真的)不同的电子邮件帐户。一个 Exchange(奇怪的是,这是规则出现问题的帐户),两个 POP3(这些帐户没有规则)和五个 IMAP 帐户(大多数都有规则)。顺便说一句,Outlook 2016 对 IMAP 的支持比 Outlook 2007 好得多。我只希望它也能很好地处理运行非服务器规则。
我为什么要让宏也能处理 IMAP 帐户?因为我经常在一台或多台平板电脑或手机上查看电子邮件。一旦我读过一封邮件,如果我忘记将其标记为未读,那么规则将不会被应用,除非我手动运行它们并包含已读邮件(Exchange 收件箱也是如此)。在此之前,我要么手动排序已读邮件,要么手动应用已读邮件的规则。现在,我可以通过一个工具栏按钮一次性完成所有操作。
更新代码以使其更健壮(例如,检查离线或缓存模式,这在尝试枚举规则时会导致错误)并添加多帐户处理并不困难。棘手的是如何强制规则对每个帐户的默认收件箱运行(有关详细信息,请参阅下面的要点)。
查看关于 Outlook.Rule.Execute
的稀疏文档,人们可能会认为,只需枚举每个帐户的 DeliveryStore
中的规则,就能确保规则在该帐户的收件箱上运行。我花了很长时间才明白,这种想法是错误的。更糟糕的是,我在网上找不到任何关于此如何工作的解释。弄清楚 Execute
方法如何选择默认文件夹是这个项目中棘手的部分。
Using the Code
下载MyOutlookVBA.zip并解压MyOutlookVBA.bas文件。打开 Outlook,按 Alt-F11 加载 VBA 编辑器。默认项目名称通常是Project1
;重要的是,在它旁边,括号中,您应该看到VbaProject.OTM。右键单击Modules文件夹,然后从菜单中选择“导入文件...”(Import File...)。当出现“导入文件”对话框(实际上是 File Open,但被重新利用了)时,浏览到解压MyOutlookVBA.bas的位置,然后导入它。然后单击 VBA 编辑器工具栏上的“保存文件”图标(或从菜单中选择:文件/保存VbaProject.otm)。
接下来,您需要启用 Outlook 信任中心中的宏执行。完成后,您有几种选择。您可能想要做的第一件事是,如果您还没有这样做,请在 Outlook 功能区的顶部显示“开发工具”选项卡。要运行此宏,您可以按“开发工具”功能区左侧的“宏”按钮,然后选择RunAllInboxRules
,自定义功能区,在“开发工具”功能区中添加一个部分并创建一个按钮来执行RunAllInboxRules
,将RunAllInboxRules
添加到“快速访问工具栏”,或者这些选项的组合。如果您不希望RunAllInboxRules
的结果输出到我选择的目录或文件,请在调用LogInfo
时进行更改(请参阅下面的其他子例程和跟踪规则执行)。我强烈建议时不时地检查日志文件。它会告诉您是否有规则失败,这是 Outlook 自动执行规则(或通过“对收件箱运行所有规则”手动执行)所无法做到的。这使其成为规则的简单调试工具。在rl.Execute
所在的行设置断点,可以检查规则的详细信息,尝试确定问题出在哪里……祝您好运 ;-)。
关注点
让此宏正常工作的关键是理解 Rules.Execute
的工作原理。最终,通过“规则和通知”对话框手动操作 Outlook 规则为我提供了所需的线索。这是 Outlook 2016 中“立即运行规则”的截图。
请注意对话框底部的选项:在文件夹中运行、包含子文件夹、应用于。这些选项中的每一个都对应于可以传递给 Rule.Execute
的 4 个参数中的 3 个。这促使我尝试以下代码。
rl.Execute RuleExecuteOption:=OlRuleExecuteOption.olRuleExecuteAllMessages, _
Folder:=st.GetDefaultFolder(olFolderInbox)
请注意,rl
是一个 Outlook.Rule 对象,而 st
是当前帐户的 Outlook.Store
对象(精确地说,是 DeliveryStore
)。 使用每个 Store
的 GetDefaultFolder
是将 rl.Execute
指向正确收件箱的关键。否则,它似乎会访问活动 Outlook 配置文件(在这种情况下是 Exchange)的默认收件箱。
其他子例程和跟踪规则执行
原始宏调用 MsgBox
来显示已执行规则的列表(该代码仍然存在,但已注释掉)。但是,一旦我添加了多个帐户(以及我定义的规则数量),MsgBox
的文本显示限制就裁剪了太多数据。此外,我也不喜欢每次运行规则时都弹出一个 MsgBox
。我确实想知道是否有任何规则执行问题(或者注意是否有任何规则被禁用)。这促使我添加了 LogInfo
子例程。它只是将 ruleList
文本输出到一个文本文件(文件夹位置作为参数传递(我使用 "%USERPROFILE%\My Documents\Email\"
)。请注意,末尾的反斜杠是必需的。LogFile
将在需要时创建路径中的最终目录。所有父目录都必须存在,否则 LogFile
将会出错。
重要说明
当您将 VBA 代码导入 Outlook 时,将其放在 VbaProject.otm 下的Modules文件夹中非常重要。您还需要转到 Outlook 的“工具/信任中心”,然后启用带有警告的“所有宏”宏,或者使用“无安全检查”(后者选项很危险)。
您必须确保引用您 Office 版本的 Microsoft Office 对象库以及 Outlook 对象库,然后才能运行此代码。在 VBA 编辑器中,单击“工具/引用”。对于 Outlook 2016,所需的库是
- Microsoft Outlook 16.0 对象库
- Microsoft Office 16.0 对象库
对于我的配置,我还拥有这些引用
- OLE 自动化 // LogInfo 子例程需要
- Visual Basic for Applications
历史
- 2017 年 3 月 2 日:文章/代码的初始发布
更改日志
- 2017 年 3 月 2 日
- 修复了显示 HREF 文本而不是实际链接的损坏 HTML
- 拼写和少量文本格式修复
- 2017 年 3 月 3 日 - 修复了更多拼写错误