我有一个Excel工作簿,其中包含直接放在工作表上的一些ComboBox控件。这些是“表单”工具栏中的标准组合框。
当用户使用“另存为”以使用其他名称保存工作簿时,这将触发所有组合框上的Change事件,包括非活动工作表上的组件。这似乎是不合理的,因为选择并没有真正改变。由于事件处理程序中的代码,这会导致各种不良行为。该事件不是通过简单的“保存”触发的。
Google suggests这是Excel中的一个已知问题。使用命名范围作为组合框的ListFillRange导致rumours,这是我已经完成的,尽管它不是易失性名称。我正在寻找一种方法来防止这种情况发生,只需对代码和电子表格进行最少的更改。有没有人有经证实的解决方案?
答案 0 :(得分:3)
我在一个只有一张工作表Sheet1的新工作簿中执行了以下操作,它似乎在保存之前用于调整事件,然后重新启用它们。它应该通过模仿AfterSave
事件来绕过您看到的问题。这是我在Sheet1上的事件代码(也可能是OLEObject代码)
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
MsgBox Target.Address & ": " & Target.Value
End Sub
这是我的ThisWorkbook代码
Option Explicit
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
' To see the change code work before disabling
' Should show a message box
Sheet1.Range("A1") = "Before After Events Off"
Application.EnableEvents = False
Application.OnTime Now, "ThisWorkbook.Workbook_AfterSave"
' This time it will not show a message box
' You will never see this one . . .
Sheet1.Range("A1") = "After After Events Off"
End Sub
Private Sub Workbook_AfterSave()
Application.EnableEvents = True
End Sub
.OnTime
方法将AfterSave“事件”抛出到执行队列中。它有效!
答案 1 :(得分:2)
您可以在Workbook的BeforeSave事件中设置一个标志,然后在处理每个组合框中的更改事件之前检查该标志。似乎没有AfterSave事件,因此您需要在组合框更改事件中检查后清除该标志。该标志需要不仅仅是一个简单的布尔值,因为在处理完所有组合框更改事件之前无法关闭它。这是一些示例代码:
Public ComboBoxChangeCounter As Integer
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
Const NumOfComboBoxChangeEvents As Integer = 5
ComboBoxChangeCounter = NumOfComboBoxChangeEvents
End Sub
Function JustSaved() As Boolean
If ComboBoxChangeCounter > 0 Then
ComboBoxChangeCounter = ComboBoxChangeCounter - 1
JustSaved = True
End If
End Function
Private Sub Combo1_Change()
If JustSaved Then Exit Sub
'Your existing code '
' ... '
' ... '
' ... '
End Sub
我将组合框更改事件的数量设置为常量,但您可以通过某种方式以编程方式确定该数字。这种解决方法确实需要为每个组合框更改事件添加代码,但它应该很简单,因为您只需要在每个事件开始时复制并粘贴行If JustSaved Then Exit Sub
。
此变通方法假定将在组合框更改事件之前调用Workbook BeforeSave事件。如果是这样的话我不知道。