Как закончить бесконечный цикл" изменения " в VBA

у меня проблема с visual basic. Я хочу сделать макрос / функцию, которая умножит число, которое я введу на 3, и даст результат в той же ячейке. Я попробовал что-то вроде этого:

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

но это не работает - я получаю результаты, такие как" xE25", потому что он продолжает умножаться.

Я бы хотел, чтобы он остановился после первой итерации или работал только тогда, когда я нажимаю "enter" не с каждым изменением в ячейке.
Довольно легко поместить результат в другую ячейку, но это не мой точка.


-----Edit:
Я отредактировал строку " 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, потому что он не вызывает ошибки при попытке удалить данные сразу в нескольких ячейках.

3 ответов


с обработкой ошибок для обеспечения .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

когда Worksheet_Change макрос события изменяет значение, вам нужно установить Application.EnableEvents to 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 всегда сбрасывался на правда выше должно вам начать работу.


вам нужно отключить события, чтобы предотвратить рекурсию:

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

Это также тот подход, который вам нужен с userforms и большинством событий для элементов управления activex на листах.