将事件处理程序附加到以编程方式创建的Outlook.MailItem

时间:2016-06-09 16:32:16

标签: vba email outlook

我在VBA中编写了一个回复电子邮件的Outlook 2010宏,但没有自动发送电子邮件。相反,宏只显示电子邮件,以便我可以在点击"发送"之前查看其内容。按钮。

但是,我喜欢这个第一个宏来附加另一个宏,当我点击"发送"检查器中的按钮。虽然我可以轻松地响应应用级发送事件(使用this other question中讨论的Application_ItemSend()),但我更倾向于将第二个宏仅附加到以编程方式生成的回复中所以它只适用于我用宏本身创建的电子邮件,而不是所有电子邮件。这可能吗?

更具体地说,我的项目中有一个常规模块,可以执行类似这样的操作(简化):

Public Sub replyToEmail()
    Dim responseMail As Outlook.MailItem, originalEmail As Outlook.MailItem
    Dim myHandler as New replyHandler
    Set responseMail = originalEmail.reply
    ' do something and set responseMail.Body intelligently, then
    Set myHandler.reply = responseMail ' <-- WHY DOESN'T THIS PERSIST?
    responseMail.Display ' Show me the email so I can review it
End Sub

我还有一个用于自动回复的课程模块,replyHandler,如下所示:

Public WithEvents reply As Outlook.MailItem

Private Sub reply_Send(Cancel As Boolean)
    ' Do additional processing upon Send event
    ' but why doesn't this ever get called, despite "reply" being set in the subroutine above?
End Sub

这个类模块我遇到了麻烦,因为看起来无论我在第一个宏中尝试什么,reply_Send() Sub都不会被执行。也就是说,我的问题是如何在replyToEmail()运行后运行该Sub?或者换句话说,如何在responseMail中保留对replyToEmail()的引用,以便在点击&#34时实际调用我的类模块的reply_Send()事件处理程序;发送&#34; replyToEmail()创建并显示的消息按钮?

有没有办法在不附加全局应用程序级ItemSend处理程序的情况下执行此操作?

Microsoft Help提供了一些指导,但其示例要求在创建响应电子邮件之后和单击Inspector的“发送”按钮之前运行第三个宏。 (它的内容如下:&#34;示例代码必须放在类ThisOutlookSession等类模块中,并且必须先调用SendMyMail过程才能调用Microsoft Outlook的事件过程。&# 34;)我也要自动执行此步骤。但是,再次,如何在两个Sub例程中保持对以编程方式创建的MailItem的引用?

提前致谢。

编辑澄清解决方案:

这里的问题结果是变量范围。而不是子例程本身内的Dim myHandler as New replyHandler,应该在模块级别将其声明为Public myHandler As New replyHandler。然后,稍后执行Set myHandler.reply = responseMail的行正确地将myHandler.reply变量保留到第二个子例程。

1 个答案:

答案 0 :(得分:0)

要正确处理所有Outlook项目或特定项目的事件,您需要管理Inspector Wrappers的集合。基本思想是捕获Inspectors.NewInspector事件并创建您的包装器(如果这是您要捕获的项目(例如,在撰写模式下的电子邮件))。每个包装器都有自己的事件容器。请参阅此文章以获得更好的解释:

https://msdn.microsoft.com/en-us/library/ff973716.aspx

否则,当您第一次创建回复项时,您可以获取由Reply方法返回的新撰写电子邮件的句柄,并开始处理该项目的事件。因此,您可以捕获MailItem.Send并在需要时取消它,并且只有新的回复电子邮件处于活动状态时才会触发该事件。没有其他项目会触发该特定事件。您只需要确保使用Public scope(并使用WithEvents)为要为其公开事件的项声明模块级变量。