我不知道为什么,这很奇怪,但我的代码是循环的。实际上,在第一张(ws1)中,我在Worksheet_Change
事件中执行此操作:
Application.EnableEvents = False
ws2.Range(Col_Letter(target.Column) & LastLine & ":" & Col_Letter(target.Column) & LastLine ).PasteSpecial Paste:=xlPasteValues
Application.EnableEvents = True
此外,我在ThisWorkbook
"班级",Workbook_SheetChange
事件。
在上面的代码中,我修改了一个Cell。 问题我不知道它为什么要调用Workbook_SheetChange
事件,因为我已经在我的第一张工作表上禁用了这些事件。
因此,它会循环播放,因为在我的Workbook_SheetChange
事件中我修改了工作表1。然后,Worksheet1正在修改第二个,....无限循环。
我不知道为什么Application.EnableEvents = False
不起作用(事实上,如果我在Workbook_SheetChange
上执行Debug.Print(Application.EnableEvents)事件,它说"真的"这是非常不安。)
谢谢, 克莱门特
答案 0 :(得分:1)
如果您使用全局标记来指示正在进行何种处理,则可以解决此问题而无需禁用事件。
您的设计说明中并不完全清楚为什么您需要同时处理Worksheet_Change
个事件和Workbook_SheetChange
个事件。但是对每个事件何时开火的充分理解肯定有帮助。在您的情况下,如果您更改Sheet1上的单元格,您将获得Sheet1的Worksheet_Change
事件,然后获得Workbook_SheetChange
事件。只要您更改任何工作表,就会发生这种情况。
下面的示例说明了如何处理处理以保持一切正常,而不是踩到您通过VBA进行的更改以及手动进行的更改。这个例子有多个部分,所以请在家里跟着......
首先,我们需要建立两个Public
事物:一个工作簿 - 全局标志和一个工作簿 - 全局子例程来执行您的处理。所以在VBA代码模块(Module1
)中,我们有以下代码:
'------ Module1 --------
Option Explicit
Public MyCustomMacroInProgress As Boolean
Public Sub DistributeChangeToSheets()
Debug.Print "Entering DistributeChangeToSheets... "
MyCustomMacroInProgress = True
Debug.Print "=== setting MyCustomMacroInProgress = " & MyCustomMacroInProgress
'--- loop to fire change events in the other worksheets for testing
Dim ws As Variant
For Each ws In ThisWorkbook.Sheets
If ws.Name <> "Sheet1" Then
ws.Range("A1") = 1
End If
Next ws
MyCustomMacroInProgress = False
Debug.Print "=== setting MyCustomMacroInProgress = " & MyCustomMacroInProgress
Debug.Print "Leaving DistributeChangeToSheets"
End Sub
(请注意,在任何地方使用Option Explicit
可以极大地帮助您的代码。)
通过创建公共全局标志(MyCustomMacroInProgress
),您现在可以在任何模块以及任何类和任何工作表中检查此标志。通过在模块中创建Sub DistributeChangeToSheets
并将其公开,您基本上可以从您可能想要的任何原始工作表中应用此类处理。我的示例仅应用Sheet1的更改。
所以现在主要改变捕手 - Sheet1。在Sheet1的代码中,我有
Option Explicit
'--- in Sheet1
Private Sub Worksheet_Change(ByVal Target As Range)
Debug.Print "In " & Target.Parent.Name;
Debug.Print ": Worksheet_Change event fired ";
Debug.Print " - changed cell " & Target.Address
DistributeChangeToSheets
End Sub
我在任何地方都打印Debug
语句,因此在处理过程中更容易理解。您可以在Sheet1中看到,我们正在打印我们所在的位置,然后将子调用DistributeChangesToSheets
(来自Module1)。
我的示例只有三个工作表,因此其他工作表模块中的代码很简单:
Option Explicit
'--- in Sheet2
Private Sub Worksheet_Change(ByVal Target As Range)
Debug.Print "In " & Target.Parent.Name;
Debug.Print ": Worksheet_Change event fired ";
If Not MyCustomMacroInProgress Then
Debug.Print " - process change event normally"
Else
Debug.Print " - skip normal change event processing"
End If
End Sub
和
Option Explicit
'--- in Sheet3
Private Sub Worksheet_Change(ByVal Target As Range)
Debug.Print "In " & Target.Parent.Name;
Debug.Print ": Worksheet_Change event fired ";
If Not MyCustomMacroInProgress Then
Debug.Print " - process change event normally"
Else
Debug.Print " - skip normal change event processing"
End If
End Sub
现在在示例中将所有内容放在一起,在Sheet1上的任何单元格中键入一个值。立即窗口现在显示以下输出:
In Sheet1: Worksheet_Change event fired - changed cell $B$2 Entering DistributeChangeToSheets... === setting MyCustomMacroInProgress = True In Sheet2: Worksheet_Change event fired - skip normal change event processing In Sheet2: Workbook_SheetChange event fired - skip normal change event processing In Sheet3: Worksheet_Change event fired - skip normal change event processing In Sheet3: Workbook_SheetChange event fired - skip normal change event processing === setting MyCustomMacroInProgress = False Leaving DistributeChangeToSheets In Sheet1: Workbook_SheetChange event fired - process change event normally
从输出中,您可以看到工作表和工作簿事件都遵循事件模式 - 因此在更改工作表(Worksheet_Change
和Workbook_SheetChange
)时会收到两个事件。通过在Sheet1上设置全局标志(从DistributeChangeToSheets
内部),通过使用If
语句,您可以在此类处理期间禁止对所有其他工作表进行更改处理。
可能需要对您进行一些重新编码,但是以有序的方式处理您的事件可以使处理流程更加清晰。