如何结束 VBA 中的无限 "change" 循环
How to end infinite "change" loop in VBA
我对 Visual Basic 有疑问。我想制作一个 macro/function ,它将我输入的数字乘以 3 并在同一个单元格中给出结果。我试过这样的事情:
Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$Q" Then
Target.Value = Target.Value * 3
End If
End Sub
但它不起作用 - 我得到了像 "xE25" 这样的结果,因为它不断增加。
我希望它在第一次迭代后停止,或者仅在我按下 "enter" 时才工作,而不是在单元格中进行每次更改。
将结果放在不同的单元格中很容易,但这不是我的重点。
-----编辑:
我将 "If" 行编辑为:
If (Target.Column = 5 Or Target.Column = 11 Or Target.Column = 17 Or Target.Column = 23) And (Target.Row >= 19 And Target.Row <= 24) And Target.Value <> "" Then
所以它适用于我需要的所有细胞。之后,最好的解决方案就是@Chrismas007给出的方式,因为它在尝试一次删除几个单元格中的数据时不会提示错误。
当 Worksheet_Change
事件宏更改值时,您需要将 Application.EnableEvents
设置为 false 否则可能会触发另一个事件并让宏 运行 在其自身之上。
Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$Q" Then
Application.EnableEvents = False
Target.Value = Target.Value * 3
Application.EnableEvents = True
End If
End Sub
虽然我通常会涉及一些错误控制,以便 .EnableEvents
始终重置为 true,但以上应该可以帮助您入门。
您需要禁用事件以防止递归:
Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$Q" Then
application.enableevents = false
Target.Value = Target.Value * 3
application.enableevents = true
End If
End Sub
作为替代方案,您也可以使用自己的变量而不是修改 EnableEvents,尽管这意味着您的代码会响应两次,即使它第二次实际上没有做任何事情:
Dim bSkipEvents as Boolean
Sub Worksheet_Change(ByVal Target As Range)
If bSkipEvents then exit sub
If Target.Address = "$Q" Then
bSkipEvents = True
Target.Value = Target.Value * 3
bSkipEvents = False
End If
End Sub
对于工作表上的 ActiveX 控件,用户窗体和大多数事件也需要这种方法。
通过错误处理确保 .EnableEvents
返回到 True
:
Sub Worksheet_Change(ByVal Target As Range)
On Error GoTo CleanExit
If Target.Address = "$Q" Then
Application.EnableEvents = False
Target.Value = Target.Value * 3
End If
CleanExit:
Application.EnableEvents = True
On Error GoTo 0
End Sub
我对 Visual Basic 有疑问。我想制作一个 macro/function ,它将我输入的数字乘以 3 并在同一个单元格中给出结果。我试过这样的事情:
Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$Q" Then
Target.Value = Target.Value * 3
End If
End Sub
但它不起作用 - 我得到了像 "xE25" 这样的结果,因为它不断增加。
我希望它在第一次迭代后停止,或者仅在我按下 "enter" 时才工作,而不是在单元格中进行每次更改。
将结果放在不同的单元格中很容易,但这不是我的重点。
-----编辑:
我将 "If" 行编辑为:
If (Target.Column = 5 Or Target.Column = 11 Or Target.Column = 17 Or Target.Column = 23) And (Target.Row >= 19 And Target.Row <= 24) And Target.Value <> "" Then
所以它适用于我需要的所有细胞。之后,最好的解决方案就是@Chrismas007给出的方式,因为它在尝试一次删除几个单元格中的数据时不会提示错误。
当 Worksheet_Change
事件宏更改值时,您需要将 Application.EnableEvents
设置为 false 否则可能会触发另一个事件并让宏 运行 在其自身之上。
Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$Q" Then
Application.EnableEvents = False
Target.Value = Target.Value * 3
Application.EnableEvents = True
End If
End Sub
虽然我通常会涉及一些错误控制,以便 .EnableEvents
始终重置为 true,但以上应该可以帮助您入门。
您需要禁用事件以防止递归:
Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$Q" Then
application.enableevents = false
Target.Value = Target.Value * 3
application.enableevents = true
End If
End Sub
作为替代方案,您也可以使用自己的变量而不是修改 EnableEvents,尽管这意味着您的代码会响应两次,即使它第二次实际上没有做任何事情:
Dim bSkipEvents as Boolean
Sub Worksheet_Change(ByVal Target As Range)
If bSkipEvents then exit sub
If Target.Address = "$Q" Then
bSkipEvents = True
Target.Value = Target.Value * 3
bSkipEvents = False
End If
End Sub
对于工作表上的 ActiveX 控件,用户窗体和大多数事件也需要这种方法。
通过错误处理确保 .EnableEvents
返回到 True
:
Sub Worksheet_Change(ByVal Target As Range)
On Error GoTo CleanExit
If Target.Address = "$Q" Then
Application.EnableEvents = False
Target.Value = Target.Value * 3
End If
CleanExit:
Application.EnableEvents = True
On Error GoTo 0
End Sub