Автоматически выполнять макрос Excel при смене ячейки

Как я могу автоматически выполнять макрос Excel каждый раз, когда изменяется значение в определенной ячейке?

Сейчас мой рабочий код:

Private Sub Worksheet_Change(ByVal Target As Range)
    If Not Intersect(Target, Range("H5")) Is Nothing Then Macro
End Sub

где "H5" - это контролируемая ячейка, а Macro - имя макроса.

Есть ли лучший способ?

Ответ 1

Ваш код выглядит неплохо.

Однако будьте осторожны, так как ваш вызов Range("H5") - это команда быстрого доступа к Application.Range("H5"), что эквивалентно Application.ActiveSheet.Range("H5"). Это может быть хорошо, если единственными изменениями являются пользовательские изменения, что является наиболее типичным, но возможно изменение значений ячейки листа, если оно не является активным листом через программные изменения, например, VBA.

Имея это в виду, я бы использовал Target.Worksheet.Range("H5"):

Private Sub Worksheet_Change(ByVal Target As Range)
    If Not Intersect(Target, Target.Worksheet.Range("H5")) Is Nothing Then Macro
End Sub

Или вы можете использовать Me.Range("H5"), если обработчик события находится на кодовой странице для рассматриваемого рабочего листа (обычно это):

Private Sub Worksheet_Change(ByVal Target As Range)
    If Not Intersect(Target, Me.Range("H5")) Is Nothing Then Macro
End Sub

Надеюсь это поможет...

Ответ 2

Обработайте событие Worksheet_Change или событие Workbook_SheetChange.

Обработчики событий принимают аргумент "Target As Range", поэтому вы можете проверить, включает ли диапазон, который меняет интересующую вас ячейку.

Ответ 3

Я предпочитаю этот способ, не используя ячейку, но диапазон

    Dim cell_to_test As Range, cells_changed As Range

    Set cells_changed = Target(1, 1)
    Set cell_to_test = Range( RANGE_OF_CELLS_TO_DETECT )

    If Not Intersect(cells_changed, cell_to_test) Is Nothing Then 
       Macro
    End If

Ответ 4

Я потратил много времени на изучение этого и изучение того, как все это работает, после того, как они действительно запутали триггеры событий. Поскольку было так много разбросанной информации, я решил поделиться тем, что я нашел, чтобы работать все в одном месте, шаг за шагом следующим образом:

1) Откройте редактор VBA, в разделе VBA Project (YourWorkBookName.xlsm) откройте Microsoft Excel Object и выберите Лист, к которому относится событие изменения.

2) Кодирование по умолчанию - "Общее". В раскрывающемся списке в верхней середине выберите "Рабочий лист".

3) Private Sub Worksheet_SelectionChange уже существует, как и должно быть, оставьте его в покое. Скопируйте/вставьте Mike Rosenblum код сверху и измените ссылку.Range на ячейку, для которой вы смотрите изменение (B3, в моем случае). Не помещайте свой Макрос, однако (я удалил слово "Макро" после "Тогда"):

Private Sub Worksheet_Change(ByVal Target As Range)
    If Not Intersect(Target, Me.Range("H5")) Is Nothing Then
End Sub

или из раскрывающегося списка в верхнем левом углу выберите "Изменить" и в промежутке между Private Sub и End Sub, вставьте If Not Intersect(Target, Me.Range("H5")) Is Nothing Then

4) В строке после "Затем" отключите события, чтобы при вызове вашего макроса он не запускал события и не запускал этот рабочий лист_Чтобы снова в бесконечном цикле, который вызывает сбой Excel и/или в противном случае все испортит:

Application.EnableEvents = False

5) Вызовите свой макрос

Call YourMacroName

6) Включите события, чтобы включить следующее изменение (и любые/все другие события):

Application.EnableEvents = True

7) Завершите блок If и Sub:

    End If
End Sub

Весь код:

Private Sub Worksheet_Change(ByVal Target As Range)
    If Not Intersect(Target, Me.Range("B3")) Is Nothing Then
        Application.EnableEvents = False
        Call UpdateAndViewOnly
        Application.EnableEvents = True
    End If
End Sub

Это приводит к включению/отключению событий в модулях, что создает проблемы и просто позволяет запускать изменение, отключает события, запускает ваш макрос и снова включает события.

Ответ 5

У меня есть ячейка, которая связана с онлайн-базой данных и часто обновляется. Я хочу вызвать макрос всякий раз, когда значение ячейки обновляется.

Я считаю, что это похоже на изменение значения ячейки программой или любым внешним обновлением данных, но вышеприведенные примеры как-то не работают для меня. Я думаю, проблема заключается в том, что внутренние события excel не запускаются, но это мое предположение.

Я сделал следующее:

Private Sub Worksheet_Change(ByVal Target As Range) 
  If Not Intersect(Target, Target.Worksheets("Symbols").Range("$C$3")) Is Nothing Then
   'Run Macro
End Sub