Worksheet_Change事件中的目标范围不正确
我是一个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
事件处理程序创build的“Target”对象只包含已更改的单元格/单元,因此我的代码只会更改已修改并触发事件的单元格的值。
我试图通过使用Debug.Print
输出对象的地址来帮助自己。 它打印出的值小于零的表格中的每个单元格的地址,所以我假设处理程序跑了好几次。
实际上,我发现问题本身的一个解决方法,但我的问题是这样的:我怎么在使用Worksheet_Change事件失败,我可以做什么在未来没有这样的问题?
编辑1:更新的代码与错误修复build议在评论中
编辑2:更新error handling代码来处理数组公式
回答你的问题
[1]我如何在使用Worksheet_Change事件失败,以及[2]我今后可以做什么没有这样的问题?
- 从技术上讲,你没有
- 这种types的问题没有什么,尽pipe下面的规则总体上有帮助
你对Target
对象的理解是正确的。 您的代码失败,因为SpecialCells
不喜欢单个单元格操作。 给它一个,它扩大到整个表! 给别的,它工作得很好。
Debug.Print
显示所有单元格的原因是,每当您的代码更改单元格时,都会触发另一个更改事件。 幸运的是,第二个find一个零,所以它不会触发另一个 。 下面的一般规则应该有助于避免很多问题,而不是这个问题:
- 始终围绕事件处理程序中的任何代码,用
Application.EnableEvents
更改工作簿的任何部分 。
要解决你的代码,所以它的工作,只需删除SpecialCells
方法调用。 由于您使用的是Cell.Value
而不是强烈推荐的Cell.Value2
(请参见此处 ),VBA隐式types可将数字格式化为实际数字。 因此,代码可以同时处理数字和文本值。
码:
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来处理input数组公式。 它可以允许在列6中input数组公式,而在列6中input负数,或者完全停止input。
这工作( 更新 )
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
!