如何在VBA中结束无限的“更改”循环

我有一个视觉基本问题。 我想做一个macros/函数,将乘以我input的数字3,并给出一个结果在同一个单元格。 我尝试了这样的事情:

Sub Worksheet_Change(ByVal Target As Range) If Target.Address = "$Q$21" Then Target.Value = Target.Value * 3 End If End Sub 

但它不起作用 – 我得到的结果像“xE25”,因为它不断倍增。

我希望在第一次迭代之后停止工作,或者只在按下“enter”键而不是在单元格中进行任何更改时才工作。
把结果放在不同的单元格中是很容易的,但这不是我的观点。

– – -编辑:
我编辑了“如果”行来:
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给出的方式,因为当试图一次删除less数几个单元格的数据时不会提示错误。

通过error handling来确保.EnableEvents回到True

 Sub Worksheet_Change(ByVal Target As Range) On Error GoTo CleanExit If Target.Address = "$Q$21" Then Application.EnableEvents = False Target.Value = Target.Value * 3 End If CleanExit: Application.EnableEvents = True On Error GoTo 0 End Sub 

当一个Worksheet_Change事件macros更改一个值时,您需要将Application.EnableEvents设置为false或触发另一个事件,并使macros运行在其本身之上。

 Sub Worksheet_Change(ByVal Target As Range) If Target.Address = "$Q$21" Then Application.EnableEvents = False Target.Value = Target.Value * 3 Application.EnableEvents = True End If End Sub 

虽然我通常会涉及一些错误控制,以便.EnableEvents总是重置为true ,上面应该让你开始。

您需要禁用事件以防止recursion:

 Sub Worksheet_Change(ByVal Target As Range) If Target.Address = "$Q$21" Then application.enableevents = false Target.Value = Target.Value * 3 application.enableevents = true End If End Sub 

作为替代scheme,您也可以使用自己的variables,而不是修改EnableEvents,但这意味着即使代码第二次没有做任何事情,它也会响应两次:

 Dim bSkipEvents as Boolean Sub Worksheet_Change(ByVal Target As Range) If bSkipEvents then exit sub If Target.Address = "$Q$21" Then bSkipEvents = True Target.Value = Target.Value * 3 bSkipEvents = False End If End Sub 

这也是您在工作表上使用用户表单和大多数事件进行ActiveX控件所需的方法。