excel - 从 Excel VBA 访问 Outlook 电子邮件的“正文”
问题描述
从 Windows 7 上的 Office 2010 升级到 Windows 10 上的 Office 365 后,以下 Excel VBA 代码停止工作。
Sub readbodytest()
Dim OL As Outlook.Application
Dim DIB As Outlook.Folder
Dim i As Object 'Outlook.ReportItem
Dim Filter As String
Set OL = CreateObject("Outlook.Application")
Set DIB = OL.Session.GetDefaultFolder(olFolderInbox)
Const PR_SENT_REPRESENTING_EMAIL_ADDRESS = "http://schemas.microsoft.com/mapi/proptag/0x0065001E"
Filter = "@SQL=" & _
"""" & PR_SENT_REPRESENTING_EMAIL_ADDRESS & """ ci_phrasematch 'mailer-daemon' OR " & _
"""" & PR_SENT_REPRESENTING_EMAIL_ADDRESS & """ ci_phrasematch 'postmaster' OR " & _
"urn:schemas:httpmail:subject ci_phrasematch 'undeliverable' OR " & _
"urn:schemas:httpmail:subject ci_phrasematch 'returned'"
For Each i In DIB.Items.Restrict(Filter)
Debug.Print i.Body '<< Code fails here
Next
Set i = Nothing
Set DIB = Nothing
Set OL = Nothing
End Sub
在 Excel 中,它返回
运行时错误-2147467259“对象'_MailItem'的方法'Body'失败”</p>
当直接在 Outlook VBA 中运行时,代码将起作用,但在外部运行时不起作用。
代码的目的是对返回的邮件项目进行批量审查,将电子邮件正文中的信息与数据库中的记录相匹配,并更新数据库以记录失败。
在我重新编写代码以反向运行(从 Outlook VBA 到 Excel;而不是 Excel 试图从 Outlook 中检索)之前,看看是否有人有任何建议。
解决方案
使用 Application 类的 Logon 方法将用户登录到 MAPI 以获取 MAPI 会话是有意义的。这是 MSDN 所说的:
当 Outlook 尚未运行时,仅使用登录方法登录到特定配置文件。这是因为一次只能运行一个 Outlook 进程,并且该 Outlook 进程只使用一个配置文件并且只支持一个 MAPI 会话。当用户第二次启动 Outlook 时,该 Outlook 实例在同一个 Outlook 进程中运行,不会创建新进程,而是使用相同的配置文件。
如果 Outlook 未运行并且您只想使用默认配置文件启动 Outlook,请不要使用登录方法。下面的代码示例 InitializeMAPI 显示了一个更好的替代方案:首先,实例化 Outlook 应用程序对象,然后引用一个默认文件夹,例如收件箱。这具有初始化 MAPI 以使用默认配置文件并使对象模型完全正常工作的副作用。
其次,我建议在访问任何属性之前检查项目类型。并非所有项目都可能包含此类属性。
另一个可能的陷阱,很可能是处理 Outlook 对象模型时的安全问题。当您尝试访问任何敏感属性时,Outlook 可能会触发安全问题(可能是代码或 UI 保护/提示中的错误)。本文中的“安全”是指所谓的“对象模型保护”,它触发安全提示并阻止对某些功能的访问,以防止恶意程序从 Outlook 数据中获取电子邮件地址并使用 Outlook 传播病毒和垃圾邮件。您可以使用以下方法来弥补差距:
Outlook组件的安全管理器允许在运行时关闭/打开提示。
使用不生成安全提示的低级代码。或围绕该 API 的任何其他第三方包装器(例如 Redemption)。
部署组策略以避免安全提示。
运行最新的防病毒软件。
推荐阅读
- android - 使用 Retrofit 解析 XML
- conda - 带有 conda 的 qsub 激活?
- ruby-on-rails - 仅提取自上次提取以来创建的记录的最有效方法是什么?
- django - 将来自 2 个不同模型的 Django 表单保存到第三个模型中
- javascript - Javascript - 试图复制一个数组而失去参考
- javascript - 当滚动到智能手机页面的底部时,如何使顶部按钮移动到页脚上方?
- c++ - __declspec(dllexport) 强制错误的模板覆盖编译错误
- c# - 使用 Redis 和 Entity Framework Core。错误:已经有一个打开的 DataReader 与此 Connection 关联,必须先关闭
- symfony - 为什么我的插件在 shopware 6.4 升级后不起作用?
- python - 从包含两个日期的字符串的 pandas 单元格创建日期列表