簡體   English   中英

Worksheet_Change事件中的目標范圍不正確

[英]Incorrect target range in Worksheet_Change event

我是Excel-VBA的新手,我正在嘗試編寫一小段代碼,這些代碼是由某人更改工作表中單元格的值而觸發的。 如果更改的單元格的值小於零,則應將其設置為零。 代碼如下所示:

Private Sub Worksheet_Change(ByVal Target As Range)
'Debug.Print Target.Address
 If Target.Column = 6 Then
  For Each Cell In Target.SpecialCells(xlCellTypeConstants, 3)
     If Cell.Value < 0 Then
        Cell.Value = 0
     End If
  Next
 End If
End Sub

現在發生的是當我更改第6列中任何單元格的值時,包含小於零的數字的工作表中的每個單元格也會更改為零。

我認為為Worksheet_Change事件處理程序創建的“目標”對象只包含已更改的單元格/單元格,因此我的代碼只會更改已修改並首先觸發事件的單元格的值。

我試圖通過使用Debug.Print輸出對象的地址來幫助自己。 它打印出工作表中每個單元格的地址,其值小於零,因此我假設處理程序運行了幾次。

我實際上找到了問題本身的解決方法,但我的問題是:我如何使用Worksheet_Change事件失敗,以及我將來可以做些什么來解決這些問題呢?

這工作( 更新

Private Sub Worksheet_Change(ByVal Target As Range)
    Dim c As Range
    For Each c In Target
        If c.Column = 6 Then If IsNumeric(c) Then If c < 0 Then c = 0
    Next c
End Sub

請學習並使用OPTION EXPLICIT

編輯1:更新了代碼,並在評論中提供了錯誤修復

編輯2:更新了具有錯誤處理的代碼以處理數組公式

回答你的問題

[1]我是如何使用Worksheet_Change事件失敗的,以及[2]我將來怎么辦才能沒有這樣的問題?

  1. 從技術上講,你沒有
  2. 這類問題沒什么,盡管以下規則有助於解決這個問題

您對Target對象的理解是正確的。 您的代碼失敗,因為SpecialCells不喜歡單個單元格進行操作。 給它一個,它將它擴展到整個工作表! 給它任何其他東西,它工作得很好。

Debug.Print顯示所有單元格的原因是每次代碼更改單元格時,都會觸發另一個更改事件。 幸運的是,第二個找到零,所以它不會觸發另一個 以下一般規則應該有助於避免很多問題,而不是這個問題:

  • 始終包圍事件處理程序中的任何代碼,該處理程序使用Application.EnableEvents更改工作簿的任何部分

要修復代碼以使其正常工作,只需刪除SpecialCells方法調用即可。 由於您使用的是Cell.Value而不是強烈推薦的Cell.Value2 (請參見此處 ),因此VBA隱式類型會將格式化為文本的數字轉換為實際數字。 因此,代碼適用於數值和文本值。

碼:

Private Sub Worksheet_Change(ByVal Target As Range)
  'Debug.Print Target.Address;
  Application.EnableEvents = False
    For Each Cell In Target '.SpecialCells(xlCellTypeConstants, 3)
      If Cell.Column = 6 And Cell.Value < 0 Then
        On Error GoTo Error:
        Cell.Value = 0
        On Error GoTo 0
      End If
    Next
GoTo ExitSub:
Error:
  If Err.Number = 1004 Then ' 1004 -> "You cannot change part of an array."
    'Application.Undo ' Uncomment to disallow array entering a negative value formula into/across column 6
    MsgBox "A cell could not be zeroed as" & vbCr & "it is part of an array formula.", vbExclamation, "Microsoft Office Excel"
    On Error GoTo 0
  Else
    On Error GoTo 0
    Resume
  End If
ExitSub:
  Application.EnableEvents = True
End Sub

筆記:

- 更新1:代碼現在正確處理多單元格更改。

- 更新2:代碼現在捕獲錯誤1004以處理輸入數組公式。 它可以允許輸入數組公式,從而在第6列中產生負值,或者完全停止輸入。

我來到這里尋找一種方法來阻止我的工作表“閃爍”,因為它運行代碼來格式化列和行,因為用戶在工作表中的任何位置更改數據,包括過濾器和排序。

除此之外,從官方答案OP的問題,如果你試圖控制Worksheet_Change()根本上(仍然會閃光,但你可以繞過它)發射,在你希望用戶更改例如數據的情況下事件,但不是數據周圍的區域,例如作為VBA系統一部分的字段或標簽,我使用Target.Row元素來確定我的限制。 結合Target.Column ,您可以磨練用戶可以自由控制的特定單元格。

Dim myTopLimit AS Integer
myTopLimit = 6
etc..etc
if Target.Row < myTopLimit and Target.Row > myBottomLimit and Target.Column < myLeftLimit and Target.Column > myRightLimit then
.... code to allow WorkSheet_Change() to do somthing
else
.... code to force WorkSheet_Change() to drop through or no code
End If

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM