微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如果以编程方式触发关闭,为什么 VBA Workbook.Close 语句在 Workbook_BeforeClose 内失败?

如何解决如果以编程方式触发关闭,为什么 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,这将无限期地向“开始”消息框发送垃圾邮件。

合上书通常会给你两个“开始”和一个“结束”

  • 所以它第一次回到 BeforeCloseThisWorkbook.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 关闭时是如何执行的:
enter image description here 它没有关闭

然后从菜单:
enter image description here 关门了

如果我们不禁用事件,从 ThisWorkbook.Close 运行它的行为完全相同。步入,不关闭。
然而,从菜单上看却大不相同:
enter image description here 并且不会关闭。

因此似乎使用 Workbook_BeforeClose 调用 ThisWorkbook.Close 将忽略所有其他 ThisWorkbook.Close,但是使用菜单关闭文档将尝试运行每个 ThisWorkbook.Close 一次

,

在 Excel 前端,手动关闭工作簿。它将按预期通过 ThisWorkbook.Close 语句关闭。

嗯,不完全是:

如果您通过单击右上角的 X 从 UI 关闭,则会发生描述的行为剂量。另一方面,如果您通过转到 File/Close 从 UI 关闭,则行为会反映所描述的直接窗口(不关闭)

来自documentation

取消必需的布尔值

事件发生时为假。如果事件过程将此参数设置为 True,则关闭操作停止并且工作簿保持打开状态。

这解释了观察到的行为。

如果您在 cancel = True 之前设置 ThisWorkbook.Close,那么它确实关闭。

那么,为什么点击 X 会关闭它?

我相信这是因为该 UI 也在退出 Excel 应用程序。工作簿关闭是应用程序退出的副作用,所有打开工作簿也是如此。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。