2015-11-06 88 views
1

我正在使用VBA來檢查特定列中的單元格何時發生更改,因此我可以調用不同的宏對它們進行排序。這很奇妙,除了它會在我插入新行時觸發。因此,使用IsEmpty我添加了一個檢查,看看有問題的單元格是否爲空。但我顯然做錯了,因爲我插入一行時仍然會調用宏。我究竟做錯了什麼?插入行時也會觸發宏「觸發單元更改」

的VBA是對細胞變化觸發:

Private Sub Worksheet_Change(ByVal Target As Range) 
    Dim KeyCells As Range 

    Set KeyCells = Range("A:A") 

    If Not Application.Intersect(KeyCells, Range(Target.Address)) _ 
      Is Nothing Then 

     If Not IsEmpty(KeyCells) Then 
      Call SortByDate 
     End If 

    End If 
End Sub 
+0

您無法使用「IsEmpty」檢查數組。你需要遍歷'Intersect(KeyCells,Target)'中的單元格,因爲可以一次插入多行。 – Rory

+0

①你可能用'if target.count> = columns.count過濾出行插入,然後退出子'②如果你正在更改該工作表上的任何東西,在開始更改任何內容之前使用'application.enableevents = false'並且應用程序.enableevents = true「,然後離開子。 – Jeeped

回答

2

你可能會通過檢查收到的改變細胞的數量濾除行插入。在行插入的情況下,這大於或等於工作表的columns.count。如果您正在更改該工作表上的任何內容,請在開始更改任何內容前使用application.enableevents = false,並在離開子文件夾之前使用application.enableevents = true

Private Sub Worksheet_Change(ByVal Target As Range) 
    ' exit immediately on row insertion 
    If Target.CountLarge >= Columns.Count Then Exit Sub 

    If Not Intersect(Target, Columns(1)) Is Nothing Then 
     'escape route 
     On Error GoTo bm_Safe_Exit 

     'don't declare or Set anything until you know you will need it 
     '(this isn't really terribly necessary) 
     Dim KeyCells As Range 
     Set KeyCells = Range("A:A") 

     If Application.CountA(KeyCells) Then 'is there ANYTHING in A:A? 
      Application.EnableEvents = False 
      Call SortByDate 
     End If 

    End If 
bm_Safe_Exit: 
    Application.EnableEvents = True 
End Sub 

未能禁用事件處理,並隨後在工作表上的任何更改將觸發另一個變化事件和Worksheet_Change事件宏將嘗試在自身上運行。

+0

只是要清楚 - 你似乎相信** Target **是插入一行時的單個單元格。不是這樣。目標是包含插入的整個行的一系列單元格。在XLSX工作表的情況下,插入單行時爲16,384個單元格。 – Jeeped

+1

爲防萬一用戶做了一些改變大於'Long'的單元格數量(2,147,483,647;這可能在更新版本的Excel中可能,但可能是一個壞主意),但使用'Target.CountLarge '在初步檢查中。 – eirikdaude

+0

他們將不得不插入或刪除超過2000個整列,但您的觀點非常有效並且很有效。我會編輯以適應上面。 – Jeeped