2017-06-21 91 views
2

我不知道爲什麼,這很奇怪,但我的代碼循環。事實上,在第一片(WS1),我在一個Worksheet_Change事件這樣做:繞過Workbook_SheetChange事件

Application.EnableEvents = False 
ws2.Range(Col_Letter(target.Column) & LastLine & ":" & Col_Letter(target.Column) & LastLine).PasteSpecial Paste:=xlPasteValues 
Application.EnableEvents = True 

而且,我也有,對ThisWorkbook「類」,一個Workbook_SheetChange事件。

在上面的代碼中,我正在修改單元格。 問題是我不知道爲什麼它會調用Workbook_SheetChange事件,因爲我已經禁用了我的第一張工作表上的事件。因爲我的Workbook_SheetChange事件我正在修改Worksheet1。然後,Worksheet1正在修改第二個,....無限循環。

我不知道爲什麼Application.EnableEvents = False不工作(事實上,如果我做的Workbook_SheetChange事件Debug.Print(Application.EnableEvents),它在說「真」,這是無奈之舉。)

謝謝, Clement

+0

難道是ws2的改變嗎?您可以將代碼移動到工作簿中,並使用傳入的sheetname變量來確定是否運行上述操作。像'ws2.cells(lastline,target.column).value = target.value'可能更簡單。 –

+1

你真正寫在這裏的是你對「怪異行爲」的自我診斷。如果您向我們提供了所有相關代碼,例如您在表單1等中的實際操作,我們可能會提供幫助。事件是一個應用程序範圍的參數,所以我不知道你爲什麼說你「在*第一個工作表上禁用了*」?請更清楚一點 – Wolfie

+0

很簡單:我只有一個工作簿。在本工作手冊中,我有34個工作表。首先,我正在執行一些計算,然後,我將這些結果粘貼到其他33張表上。問題是我有一個'Workbook_SheetChange'事件對這個粘貼作出反應。我不知道爲什麼,因爲在粘貼之前,我正在這樣做:'Application.EnableEvents = False'。我不希望啓動'Workbook_SheetChange'事件。如果你知道爲什麼... –

回答

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_ChangeWorkbook_SheetChange)。通過在Sheet1上設置全局標誌(來自DistributeChangeToSheets之內),通過使用If語句,可以禁止在此類處理期間對所有其他工作表進行更改處理。

這可能涉及到您的部分重新編碼,但以有序的方式處理您的事件可以使處理流程更清晰一些。

+0

謝謝。它幫助我很多。 –