【发布时间】:2016-08-01 16:13:20
【问题描述】:
我正在用 VBA 编写一个 Outlook 2010 宏来回复电子邮件,但不会自动发送电子邮件。相反,宏只是显示电子邮件,以便我可以在单击“发送”按钮之前查看其内容。
但是,我希望第一个宏附加另一个宏,当我点击检查器中的“发送”按钮时运行该宏。虽然我能够轻松响应应用程序级发送事件(使用Application_ItemSend(),如this other question 中所述),但我更愿意将第二个宏仅附加到以编程方式生成的回复中,以便它仅适用于电子邮件我使用宏本身创建,而不是所有电子邮件。这可能吗?
更具体地说,我的项目中有一个常规模块可以执行以下操作(简化):
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 都不会被执行。也就是说,我的问题是如何让 Sub 在 replyToEmail() 运行后运行?或者换一种说法,我如何在replyToEmail() 中保留对responseMail 的引用,以便在我单击replyToEmail() 创建的消息的“发送”按钮时实际调用我的类模块的reply_Send() 事件处理程序,并显示?
有没有办法在不附加全局应用程序级 ItemSend 处理程序的情况下做到这一点?
Microsoft Help 提供了一些指导,但它的示例要求在创建响应电子邮件之后和单击检查员的发送按钮之前运行第三个宏。 (上面写着:“示例代码必须放在类模块中,例如ThisOutlookSession,并且必须在Microsoft Outlook 调用事件过程之前调用SendMyMail 过程。”)我宁愿做这一步也自动。但是,同样,我怎样才能在两个Subroutines 中保留对以编程方式创建的 MailItem 的引用?
提前致谢。
编辑澄清解决方案:
这里的问题原来是变量范围。而不是子例程本身中的Dim myHandler as New replyHandler,这应该在模块级别声明为Public myHandler As New replyHandler。然后,稍后执行Set myHandler.reply = responseMail 的行将myHandler.reply 变量正确地持久化到第二个子例程。
【问题讨论】:
-
您是否正在创建一个沉没类的实例,而不仅仅是使用邮件项目?
-
如果我正确理解了您的问题,那么我尝试两者都做。我创建了类模块的一个实例,并将其
.reply成员设置为从originalEmail.reply方法返回的MailItem,并尝试将MailItem 保存在常规模块的公共成员中。两者都不起作用,我不确定为什么。也许Outlook在宏到达End Sub时释放常规模块的对象引用?