如何解决如果以编程方式触发关闭,为什么 VBA Workbook.Close 语句在 Workbook_BeforeClose 内失败?
我想用我自己的进程拦截BeforeClose,并取消默认进程。没有按预期工作。要复制,请创建一个新工作簿,输入以下内容并保存:
ThisWorkbook 模块:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Cancel = True
Application.EnableEvents = False ' to prevent recursively calling this procedure
ThisWorkbook.Close
End Sub
在 Excel 前端,通过单击关闭-X 手动关闭工作簿。正如预期的那样,它将通过 ThisWorkbook.Close 语句关闭。在 Excel 2016 和 365 中,如果其他工作簿处于打开状态,它们将保持打开状态。
请注意,EnableEvents 现在将为 false。关闭并重新打开 Excel 以恢复它,或在直接窗格中输入:
Application.EnableEvents = True
现在重新打开同一个工作簿。在 Workbook_BeforeClose 上放置一个断点。转到前端并再次手动关闭工作簿。单步执行代码,以确认它在做什么。仍然可以正常工作。
如上所述恢复 EnableEvents。
该文件将不会关闭。单步执行代码以查看发生了什么。还是不关。为什么不呢?
解决方法
考虑这个代码:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
MsgBox "Start"
ThisWorkbook.Close
ThisWorkbook.Close
MsgBox "End"
End Sub
这似乎证实了我的评论。
如果 ThisWorkbook.Close
可以调用 ThisWorkbook.Close
,这将无限期地向“开始”消息框发送垃圾邮件。
合上书通常会给你两个“开始”和一个“结束”
- 所以它第一次回到
BeforeClose
的ThisWorkbook.Close
的开头,然后忽略它。
用 ThisWorkbook.Close
结束它给 one“开始和 one”结束
- 因为它忽略了
ThisWorkbook.Close
但是
在这种情况下,从 ThisWorkbook.Close
开始应该让它们始终表现相同。而事实并非。
Private Sub Workbook_BeforeClose(Cancel As Boolean)
ThisWorkbook.Close
ThisWorkbook.Close
Cancel = True
Application.EnableEvents = False ' to prevent recursively calling this procedure
ThisWorkbook.Close
End Sub
看看这段代码在用 ThisWorkbook.Close
关闭时是如何执行的:
它没有关闭
如果我们不禁用事件,从 ThisWorkbook.Close
运行它的行为完全相同。步入,不关闭。
然而,从菜单上看却大不相同:
并且不会关闭。
因此似乎使用 Workbook_BeforeClose
调用 ThisWorkbook.Close
将忽略所有其他 ThisWorkbook.Close
,但是使用菜单关闭文档将尝试运行每个 ThisWorkbook.Close
一次。
在 Excel 前端,手动关闭工作簿。它将按预期通过 ThisWorkbook.Close 语句关闭。
嗯,不完全是:
如果您通过单击右上角的 X
从 UI 关闭,则会发生描述的行为剂量。另一方面,如果您通过转到 File/Close 从 UI 关闭,则行为会反映所描述的直接窗口(不关闭)
取消必需的布尔值
事件发生时为假。如果事件过程将此参数设置为 True,则关闭操作停止并且工作簿保持打开状态。
这解释了观察到的行为。
如果您在 cancel = True
之前设置 ThisWorkbook.Close
,那么它确实关闭。
那么,为什么点击 X
会关闭它?
我相信这是因为该 UI 也在退出 Excel 应用程序。工作簿关闭是应用程序退出的副作用,所有打开工作簿也是如此。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。