Ale*_*der 5 excel events vba worksheet excel-vba
我是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
Run Code Online (Sandbox Code Playgroud)
现在发生的是当我更改第6列中任何单元格的值时,包含小于零的数字的工作表中的每个单元格也会更改为零.
我认为为Worksheet_Change事件处理程序创建的"目标"对象只包含已更改的单元格/单元格,因此我的代码只会更改已修改并首先触发事件的单元格的值.
我试图通过使用Debug.Print输出对象的地址来帮助自己.它打印出工作表中每个单元格的地址,其值小于零,因此我假设处理程序运行了几次.
我实际上找到了问题本身的解决方法,但我的问题是:我如何使用Worksheet_Change事件失败,以及我将来可以做些什么来解决这些问题呢?
编辑 1:使用评论中建议的错误修复更新了代码
编辑 2:更新了错误处理代码以处理数组公式
回答你的问题
[1]我为什么无法使用 Worksheet_Change 事件?[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
Run Code Online (Sandbox Code Playgroud)
笔记:
- 更新 1:代码现在可以正确处理多单元格更改。
- 更新 2:代码现在捕获错误 1004 来处理输入数组公式。它可以允许输入数组公式,从而在第 6 列中产生负值,也可以完全停止输入。