【发布时间】:2017-09-14 09:07:06
【问题描述】:
我遇到了一个有点奇怪的小问题。
所以我有一个宏工作簿(为简化起见,我们称之为“Main”),除了这个小问题之外,它的所有代码几乎都能完美运行。 “主要”通常始终处于打开状态,因为它是我们当天的余额。
当我或其他用户在打开此工作簿的同时打开任何其他工作簿时,一切都很好,但是当我们关闭没有代码的工作簿时,“Main”会在关闭代码之前运行它。
所以这是我在“Main”上的关闭代码:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Dim Tsweep As Integer
Dim sTime As Date
If ThisWorkbook.Sheets("Coordenador").Range("O2") <> "" Then
For Tsweep = 2 To Range("Coordenador!O1048000").End(xlUp).Row
Application.OnTime EarliestTime:=Range("Coordenador!O" & Tsweep).Value,
Procedure:="CloseC", Schedule:=False
Next Tsweep
End If
CloseC
sTime = ThisWorkbook.Sheets("Coordenador").Range("P15") +
TimeValue("00:30:00")
Application.OnTime EarliestTime:=sTime, Procedure:="SaveWb", Schedule:=False
ThisWorkbook.Save
End Sub[/CODE]
这是“CloseC”上的代码:
Sub CloseC()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Coordenador")
With ws
.Unprotect Password:=pass
.Range("O:O").ClearContents
End With
For Each Worksheet In ThisWorkbook.Worksheets
Worksheet.Protect Password:=pass
Next
ThisWorkbook.Sheets("Coordenador").Visible = xlSheetVeryHidden
ThisWorkbook.Sheets("LookupList").Visible = xlSheetVeryHidden
End Sub
还有 SaveWb 上的代码:
Sub SaveWb()
Dim vTime As Date
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Coordenador")
ThisWorkbook.Save
vTime = Now
With ws
.Unprotect Password:=pass
.Range("P15") = vTime
.Protect Password:=pass
End With
Application.OnTime vTime + TimeValue("00:30:00"), "SaveWb"
End Sub
为了解释这个代码会停止系统可能仍然存在的所有 OnTime 运行。它清除了一些单元格,保护了一些床单并保存了。当用户关闭“Main”并且excel尝试运行“SaveWb”时出现错误。
我想知道是否有办法避免这种情况,因为理论上 excel 会自行运行每个实例,即使我和/或用户使用关闭按钮顶部关闭这些其他工作簿,我们也不会关闭“主”并且该工作簿保持打开状态。另一个想法是检查工作簿在 5 秒后是否仍然打开,以及是否要运行“SaveWb”,但我还没有找到编码的方法。
提前感谢您的帮助!
【问题讨论】:
-
您是否考虑过在 BeforeClose 子的开头检查工作簿的名称?另外,ThisWorkbook 是什么?是你的 ActiveWorkbook 的别名吗?
-
@MaciejLipinski
ThisWorkbook是一个内置对象,引用包含宏的工作簿。 -
@YowE3K 谢谢,我不知道 - 我一直使用 ActiveWorkbook 或通过文件名引用代码工作簿
-
Maciej 给了我一个想法。如果 ThisWorkbook 是 ActiveWorkbook,我只能运行代码,但这会提示我另一个问题,在用户单击关闭按钮后,活动工作簿是先更改还是先运行 beforeclose? (这是来自不同工作簿的代码,我希望我很清楚..)
-
如果 Workbook_BeforeClose 事件过程响应一个应用程序事件,它应该在任何工作簿关闭时运行。阻止它采取行动的唯一方法是将其适用性限制在专门命名的(在代码中)工作簿。另一方面,如果关闭的工作簿包含代码,它们的代码似乎可能会调用“Main's”VBA 项目中的过程。您可以通过将
Option Private Module放在您不希望其他项目可见的代码模块的顶部来防止这种情况发生。