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

74

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

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

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

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

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

Теги:
excel-vba
excel
automation

5 ответов

102
Лучший ответ

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

Однако будьте осторожны, так как ваш вызов 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

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

  • 4
    Что sheet2 если ячейка H5 изменяется с другого листа, скажем sheet2 тогда вышеуказанная функция не работает. Пожалуйста, помогите в этом.
  • 2
    Для любого, кто приходит сюда из поиска в Google, убедитесь, что вы вставили этот код в лист в vba, а не в модуль, как я. посмотрите на stackoverflow.com/questions/15337008/…
Показать ещё 4 комментария
7

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

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

  • 0
    Спасибо, это работает. Я проверяю диапазон, скажем, Target.Address = Range("H5").Address . Есть ли более простой способ?
  • 0
    Альтернатива: Not (Intersect(Target, Range("H5")) Is Nothing) . Это как ты это сделаешь?
Показать ещё 1 комментарий
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
  • 0
    Это так же, как одна клетка. Вы можете установить диапазон как одну ячейку, диапазон непрерывных ячеек или даже разбросанные ячейки (все разделенные запятой).
2

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

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

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

0

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

Я считаю, что это похоже на изменение значения ячейки программой или любым внешним обновлением данных, но вышеприведенные примеры как-то не работают для меня. Я думаю, проблема заключается в том, что внутренние события 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
  • 0
    Я не могу заставить это работать по некоторым причинам. Когда я сообщаю коду для запуска в VBA, он вызывает всплывающее меню и спрашивает меня, хочу ли я запускать макрос вместо автоматического запуска макроса?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню