如何阻止Excel提示重新打开工作簿?

Joe*_*Joe 5 excel vba excel-vba

我有一个包含VBA应用程序的只读Excel工作簿.应用程序保存需要保存在数据库中的所有数据,并且工作簿始终关闭而不保存(通过在BeforeClose中设置ThisWorkbook.Saved = True).

我有以下问题:

  • 用户在Windows资源管理器中双击工作簿,打开工作簿.

  • 用户在Windows资源管理器中双击工作簿上的第二次.

  • Excel提示:"MyWorkbook.xls已经打开.重新打开将导致您所做的任何更改被丢弃.是否要重新打开MyWorkbook.xls?"

  • 如果用户单击"是",则重新打开工作簿,而不执行已打开的实例的BeforeClose事件处理程序.

这是我的应用程序中的一个问题,因为它意味着BeforeClose事件处理程序中的一些重要的清理代码不会被执行.

任何人都可以建议VBA解决方案.可能是:

  • 禁止提示重新打开工作簿.而是默默地使用已经打开的实例.

  • 以某种方式让BeforeClose或其他事件处理程序在原始实例关闭之前运行,因此我可以运行我的清理代码.

更新:

这是Excel 2003.

我可以通过在Workbook_SheetChanged事件处理程序中设置"ThisWorkbook.Saved = True"来消除不需要的提示(VBA应用程序负责保存需要保存在数据库中的任何数据,所以我不关心Excel保存更改).

但是这并没有解决我的问题:如果我这样做,那么双击浏览器中的工作簿会默默地重新打开工作簿,但仍然可以通过"BeforeClose"事件处理程序调用它.

所以重新解释一下这个问题:

  • 无论如何使用VBA来检测和拦截以这种方式重新打开的工作簿?

更新2

接受BKimmel的答案 - 似乎没有VBA方法可以从工作簿中拦截此事件.

我将实现的解决方案是将应用程序代码移动到XLA加载项中,该加载项在加载工作簿时自动加载(如果尚未加载).加载项可以处理Open和BeforeClose事件,并存储执行清理所需的信息.

BKi*_*mel 2

伙计……这看起来很容易,但其实很难。在我 7 年左右的使用 Excel VBA 的经验中,我尝试了所有我能想到的事件和应用程序/工作簿属性,但我根本无法想出任何优雅的东西......我认为简短的答案是对于这个问题,确实没有一个简短而优雅的解决方案(如果有,我真的很想看到它)。这是坏消息。

好消息是,我认为有一些方法可以解决这个问题...... 1 更优雅一点,但需要您重新考虑一些方法,而另一种则很脏,但可能更简单一点。

更优雅的方法将涉及重新思考和重构你的方法......我认为我在工作中从未遇到这个问题的原因是在我的每个方法结束时,工作簿都处于“良好”状态...或者换句话说,如果需要进行“清理”,那么它会在每个方法结束时完成。如果这对性能造成巨大的开销,您可能会考虑设置一个布尔标志并限制它是否在每个其他方法的末尾运行。(即 runCleanup = ReturnTrueIfCleanupIsNeeded() If (runCleanup = true) then CleanupMethod() End If)

更肮脏的方法
将涉及通过1)复制整个(原始)工作簿,将整个工作簿本身变成一种“临时互斥体”在 WorkBookOpen 事件中进入另一个( temp ) WorkBook 并使用temp上的“SaveAs”方法将其放置在单独的位置。
2)存储(原始)路径。
3) 向 WorkBook 打开事件添加代码,检查 ( temp ) 以及 A) 立即关闭并激活temp或 B) 用 ( temp ) 覆盖自身,然后使用 SaveAs
4) 在用户保存 WorkBook 之前捕获该事件并将其保存到原始位置临时位置。5) 在 WorkBookClose 事件中,运行所需的任何清理并将临时文件保存回其原始位置。所有这一切的目的是为了避免当您打开工作簿两次时发生的“冲突” - 本质上是通过创建一个临时文件


当您第一次打开它并将其保存在不同的位置(也许您甚至可以隐藏该文件?)时,您可以确保当用户单击原始工作簿时,它不会与他们已经在其中使用的数据发生冲突应用程序。(当然,这有它自己的问题/疑问,例如“如果我不知道用户可以访问哪些路径来保存临时文件怎么办”或“如果用户打开临时XLS文件怎么办……但这就是为什么我称之为肮脏的方式)”

我知道这很多,特别是如果您不习惯使用 VBA;如果您希望我发布一些代码来帮助您完成这些步骤,请发表评论,我会的。

感谢您提出有趣的问题。