Запуск макроса (процедуры) из кода VBA Excel при изменении значения ячейки вручную или программным способом, а также при нажатии клавиши Delete.
Запуск макроса при изменении ячейки
Пример кода
Код VBA Excel для запуска макроса (процедуры) при изменении значения ячейки на рабочем листе:
Private Sub Worksheet_Change(ByVal Target As Range) If Not Application.Intersect(Range(«A1:D8»), Range(Target.Address)) Is Nothing Then MsgBox «Значение ячейки « & Target.Address & » изменено.» End If End Sub |
Range("A1:D8")
— это диапазон, при изменении значения любой ячейки которого, произойдет выполнение функции MsgBox. Диапазон может состоять из одной ячейки.
Код размещается в модуле рабочего листа, при изменении значения ячейки на котором следует запустить макрос (процедуру).
Вместо функции MsgBox в приведенном коде следует разместить ссылку на исполняемую процедуру (макрос) VBA Excel.
Примечания
- Макрос будет запущен при изменении значения ячейки вручную или программным способом, а также при нажатии клавиши Delete.
- Вызываемая процедура будет запущена и в том случае, если в ячейку будет записано то же самое значение, которое в ней и было. Например, в ячейке было число 28, и в нее записали вручную или программно число 28; или нажали клавишу Delete на пустой ячейке.
- Макрос не будет запущен при изменении значения ячейки с формулой в результате ее пересчета.
Исключение ложного срабатывания
Если в качестве диапазона указать только одну ячейку, можно исключить срабатывание кода VBA Excel при записи в ячейку того же значения. Для этого необходимо использовать переменную уровня модуля, чтобы с ее помощью контролировать факт изменения или неизменения значения в указанной ячейке.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
Option Explicit Dim x Private Sub Worksheet_Activate() x = Range(«C4») End Sub Private Sub Worksheet_Change(ByVal Target As Range) If Not Application.Intersect(Range(«A1:D8»), Range(Target.Address)) Is Nothing _ And x <> Range(«C4») Then MyMsgBox x = Range(«C4») End If End Sub Private Sub MyMsgBox() MsgBox «Значение ячейки « & «C4» & » изменено на « & Chr(34) & Range(«C4») & Chr(34) End Sub |
В это примере функция MsgBox вынесена в отдельную процедуру, которая вызывается при изменении значения в ячейке C4.
Значение ячейки C4 присваивается переменной x
при активации рабочего листа и, затем, перезаписывается при каждой перезаписи значения в ячейке.
Код этого примера размещен в модуле рабочего листа, но код вызываемой процедуры может быть вынесен из него в другой модуль.
Обычно в Excel мы можем нажать клавишу F5 или кнопку «Выполнить», чтобы выполнить код VBA. Но пробовали ли вы когда-нибудь запустить конкретный код макроса при изменении значения ячейки? В этой статье я расскажу о некоторых быстрых приемах, которые помогут справиться с этой задачей в Excel.
Запуск или вызов макроса при изменении значения определенной ячейки с кодом VBA
Запуск или вызов макроса при изменении любого значения ячейки в диапазоне с кодом VBA
Запуск или вызов макроса при изменении значения определенной ячейки с кодом VBA
Чтобы запустить код макроса, изменив значение ячейки, следующий код VBA может оказать вам услугу, сделайте следующее:
1. Щелкните правой кнопкой мыши вкладку листа, на которой вы хотите выполнить макрос, если значение ячейки изменится, а затем выберите Просмотреть код из контекстного меню, а в открывшемся Microsoft Visual Basic для приложений окна, скопируйте и вставьте следующий код в пустой модуль:
Код VBA: запускать макрос при изменении значения ячейки:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$A$1" Then
Call Mymacro
End If
End Sub
Внимание: В приведенном выше коде A1 это конкретная ячейка, на основе которой вы хотите запустить код, Mymacro это имя макроса, который вы хотите запустить. Пожалуйста, измените их по своему усмотрению.
2. А затем сохраните и закройте окно кода, теперь, когда вы вводите или изменяете значение в ячейке A1, определенный код будет запускаться сразу.
Запуск или вызов макроса при изменении любого значения ячейки в диапазоне с кодом VBA
Если вы хотите запускать или запускать макрос, когда значение какой-либо ячейки изменяется в диапазоне ячеек, следующий код может вам помочь.
1. Щелкните правой кнопкой мыши вкладку листа, на которой вы хотите выполнить макрос, если значение ячейки изменится, а затем выберите Просмотреть код из контекстного меню, а в открывшемся Microsoft Visual Basic для приложений окна, скопируйте и вставьте следующий код в пустой модуль:
Код VBA: запускать макрос при изменении любого значения ячейки в диапазоне:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("A1:B100")) Is Nothing Then
Call Mymacro
End If
End Sub
Внимание: В приведенном выше коде A1: B100 это конкретные ячейки, на основе которых вы хотите запустить код, Mymacro это имя макроса, который вы хотите запустить. Пожалуйста, измените их по своему усмотрению.
2. А затем сохраните и закройте окно кода, теперь, когда вы вводите или изменяете значение в любой ячейке A1: B100, конкретный код будет выполнен сразу.
Статьи по теме:
Как запустить макрос автоматически перед печатью в Excel?
Как запустить макрос на основе значения ячейки в Excel?
Как запустить макрос на основе значения, выбранного из раскрывающегося списка в Excel?
Как запустить макрос, щелкнув гиперссылки в Excel?
Как запустить макрос, когда лист выбран из книги?
Лучшие инструменты для работы в офисе
Kutools for Excel Решит большинство ваших проблем и повысит вашу производительность на 80%
- Снова использовать: Быстро вставить сложные формулы, диаграммы и все, что вы использовали раньше; Зашифровать ячейки с паролем; Создать список рассылки и отправлять электронные письма …
- Бар Супер Формулы (легко редактировать несколько строк текста и формул); Макет для чтения (легко читать и редактировать большое количество ячеек); Вставить в отфильтрованный диапазон…
- Объединить ячейки / строки / столбцы без потери данных; Разделить содержимое ячеек; Объединить повторяющиеся строки / столбцы… Предотвращение дублирования ячеек; Сравнить диапазоны…
- Выберите Дубликат или Уникальный Ряды; Выбрать пустые строки (все ячейки пустые); Супер находка и нечеткая находка во многих рабочих тетрадях; Случайный выбор …
- Точная копия Несколько ячеек без изменения ссылки на формулу; Автоматическое создание ссылок на несколько листов; Вставить пули, Флажки и многое другое …
- Извлечь текст, Добавить текст, Удалить по позиции, Удалить пробел; Создание и печать промежуточных итогов по страницам; Преобразование содержимого ячеек в комментарии…
- Суперфильтр (сохранять и применять схемы фильтров к другим листам); Расширенная сортировка по месяцам / неделям / дням, периодичности и др .; Специальный фильтр жирным, курсивом …
- Комбинируйте книги и рабочие листы; Объединить таблицы на основе ключевых столбцов; Разделить данные на несколько листов; Пакетное преобразование xls, xlsx и PDF…
- Более 300 мощных функций. Поддерживает Office/Excel 2007-2021 и 365. Поддерживает все языки. Простое развертывание на вашем предприятии или в организации. Полнофункциональная 30-дневная бесплатная пробная версия. 60-дневная гарантия возврата денег.
Вкладка Office: интерфейс с вкладками в Office и упрощение работы
- Включение редактирования и чтения с вкладками в Word, Excel, PowerPoint, Издатель, доступ, Visio и проект.
- Открывайте и создавайте несколько документов на новых вкладках одного окна, а не в новых окнах.
- Повышает вашу продуктивность на 50% и сокращает количество щелчков мышью на сотни каждый день!
OSA913 Пользователь Сообщений: 248 |
#1 25.07.2017 08:31:02 Доброе утро! Помогите заставить правильно работать макрос.
Он рабочий, но только любые изменения в любых ячейках на этом листе другими макросами, они(другие макросы) всегда обращаются к этой процедуре, что замедляет работу макроса. Нужно чтобы к этой процедуре было обращение только когда происходит изменение в ячейке указанной в этой процедуре но ни как не в каждой ячейке. Я пытался подставить код как рекомендует Юрий М тут но не известно почему не вышло. Изменено: OSA913 — 25.07.2017 08:34:47 |
|
webley Пользователь Сообщений: 1991 |
#2 25.07.2017 09:21:16 что-то в этом роде:
|
||
Sanja Пользователь Сообщений: 14838 |
#3 25.07.2017 09:47:49
Изменено: Sanja — 25.07.2017 15:55:58 Согласие есть продукт при полном непротивлении сторон. |
||
OSA913 Пользователь Сообщений: 248 |
Спасибо, но пока не работает макрос( |
Sanja Пользователь Сообщений: 14838 |
Покажите файл-пример Согласие есть продукт при полном непротивлении сторон. |
OSA913 Пользователь Сообщений: 248 |
Когда в vba клавишей F8 проверяю ход выполнения макроса «QQ», он заходит в процедуру «Private Sub Worksheet_Change» после изменения значения в каждой ячейке. Нужно чтобы в «Private Sub Worksheet_Change» желтая стрелка не попадала. Изменено: OSA913 — 25.07.2017 11:43:38 |
OSA913 Пользователь Сообщений: 248 |
Вариант webley так же работает как мой. Может так должно быть ..? |
Sanja Пользователь Сообщений: 14838 |
#8 25.07.2017 15:36:20
Правильно. Потому что возникает событие Изменения ячейки Согласие есть продукт при полном непротивлении сторон. |
||
Sanja Пользователь Сообщений: 14838 |
#9 25.07.2017 15:51:42
Что значит не работает? Вы поймите, что Событие изменения ячейки возникает при изменении ЛЮБОЙ ячейки на листе, и обработчик этого события (Private Sub Worksheet_Change) будет выполняться в ЛЮБОМ случае. Другое дело КАК он будет выполняться. Проверьте мой макрос (чуть подкорректировал его в сообщении #3) и сравните время выполнения со своим. У Вас же проблема в том что работа макроса замедляется. Но это именно из-за того, что Ваш код написан не оптимально Согласие есть продукт при полном непротивлении сторон. |
||
OSA913 Пользователь Сообщений: 248 |
Доброе утро! Sanja, сам макрос не работает именно Ваш вариант. Посмотрите пожалуйста в примере. Сверху два варианта за комментированные они работают. |
Александр Пользователь Сообщений: 1147 |
#11 26.07.2017 06:35:03 OSA913, У вас
У Sanja
Разницу улавливаете ?) |
||||
OSA913 Пользователь Сообщений: 248 |
|
OSA913,А я собственно не понимаю, как оно должно работать ?) Так нужно ? |
|
OSA913 Пользователь Сообщений: 248 |
Точно. Спасибо! Действительно оптимальней такой вариант. Только теперь макрос «CopyData1» не всегда срабатывает. Как его поставить в коде чтобы он срабатывал всегда при изменении значения в любой ячейке листа? |
Sanja Пользователь Сообщений: 14838 |
#15 26.07.2017 13:53:27
Перенесите CopyData1 после End If Согласие есть продукт при полном непротивлении сторон. |
||
OSA913 Пользователь Сообщений: 248 |
#16 26.07.2017 18:35:36
Будет непрерывный цикл т.к. CopyData1 меняя значения в ячейках снова возвращается в «Private Sub Worksheet_Change». |
||
Sanja Пользователь Сообщений: 14838 |
#17 26.07.2017 18:43:26 Логично. Тогда отключайте обработку событий сразу после начала процедуры
Согласие есть продукт при полном непротивлении сторон. |
||
Sanja Пользователь Сообщений: 14838 |
#18 26.07.2017 18:46:19
Хотя не совсем. Мы же не знаем что Ваш макрос CopyData1 делает. Может он не изменяет ячейки на текущем листе Согласие есть продукт при полном непротивлении сторон. |
||
OSA913 Пользователь Сообщений: 248 |
Работает! Спасибо друзья! |
OSA913 Пользователь Сообщений: 248 |
#20 05.08.2017 09:08:02 Некоторые макросы слегка притормаживают, проверил, оказалось все из-за процедуры «CopyData», которая выглядит таким образом:
Решил от нее избавиться и перенести ее тело в процедуру события листа «Worksheet_Change» написал код в варианте предложенном Sanja. Макросы стали работать быстрее, но некоторые значения из ячеек не хотят копироваться.
Я думаю что из-за этого например из D3 должно копироваться в M3 и также на др лист в R3. Как раз не копируются значения там где нужно их копировать сразу в два места. Помогите сделать чтобы можно было копировать значение с одной ячейки в два места. Сейчас составлю простой пример и приложу в следующем посте. Изменено: OSA913 — 05.08.2017 09:11:49 |
||
OSA913 Пользователь Сообщений: 248 |
Вот простой пример. Значения не копируются на лист2. |
Sanja Пользователь Сообщений: 14838 |
Напишите пожалуйста обычными словами -ЧТО, КУДА, ПРИ КАКИХ УСЛОВИЯХ должно копироваться. Потому что Ваш код неправилен и из него не понятно что Вы хотите получить на выходе Согласие есть продукт при полном непротивлении сторон. |
OSA913 Пользователь Сообщений: 248 |
Доброе утро) Хочу чтобы при изменении значения в любой из ячеек в A1:A4 в первом листе, значение из ячейки A1 копировалось в B1, A2 в B2, A3 в B3, A4 в B4 и так же из A1 и A2 в первом листе копировалось в A1 и A2 на втором листе. Изменено: OSA913 — 05.08.2017 10:09:52 |
Sanja Пользователь Сообщений: 14838 |
#24 05.08.2017 10:08:27
Согласие есть продукт при полном непротивлении сторон. |
||
OSA913 Пользователь Сообщений: 248 |
Некоторые ячейки не копируют значения в другой лист когда значение в них определяется формулой, копируются только при ручном вводе значения. Сделал такую же ситуацию на своем файле-примере копирует нормально. Не пойму почему так. Проверил код несколько раз-все написал правильно. |
Sanja Пользователь Сообщений: 14838 |
#26 05.08.2017 12:17:45
Потому что
Ручной ввод и изменение значения формулой это разные вещи. ‘Повешайте’ код на событие Private Sub Worksheet_Calculate() Согласие есть продукт при полном непротивлении сторон. |
||||
OSA913 Пользователь Сообщений: 248 |
Не помогло. Но в файле-примере работает. |
OSA913 Пользователь Сообщений: 248 |
Хотя нет. В примере тоже перестало копировать когда в A1 ввел значение вручную. |
Sanja Пользователь Сообщений: 14838 |
#29 05.08.2017 15:33:42 Вы в реальном файле формулу тоже кодом вставляете? Покажите уже пример в РЕАЛЬНОЙ СТРУКТУРЕ и что Вы в нем пытаетесь получить. Я уже просил
Что и Куда Вы объяснили, а вот про условия не хотите. Где данные изменяются вручную? Где формулой? Где формула вставляется кодом? Согласие есть продукт при полном непротивлении сторон. |
||
OSA913 Пользователь Сообщений: 248 |
#30 06.08.2017 15:09:40 В реальном файле проблема точно такая же как и в файле-примере выше. Событием «Worksheet_Change» выполняется перенос значения из ячейки A1(лист1) в ячейку B1(лист1) и в ячейку A1(лист2) когда ввожу значение в A1 в ручную — с этим проблем уже нет. Когда жму на ячейку A5(лист1), макрос задает ячейке A1(лист1) формулу =A2*A3(лист1) — с этим проблем тоже нет. Проблема — когда меняю значение в A2(лист1), в A1 меняется значение (т.к. формула), но оно не копируется в ячейку B1(лист1) и в ячейку A1(лист2). Как это поправить? |
В Excel множество функций, но некоторые возможности не видны на первый взгляд. Неудивительно, ведь неизвестно, что может пригодиться пользователю, поэтому нет смысла выносить все на основную панель. Часто нужно выполнить какое-то действие при определенном условии, решаемое формулой. Но что, если вам необходимо выполнять действие/макрос при изменении ячейки листа Excel. Это тоже можно сделать при помощи макроса VBA. А как запустить макрос при изменении ячейки?
Чтобы запустить макрос (действие) при изменении данных в ячейке, существует несколько возможностей. Мне больше всего нравится эта конструкция:
Содержание
- Макрос, выполняемый при изменении ячейки
- Как запустить макрос при изменении ячейки?
- Похожие статьи
Макрос, выполняемый при изменении ячейки
Private Sub Worksheet_Change(ByVal Target As Range) If Not Intersect(Target, Range("A1")) Is Nothing Then If Target = 0 Then MsgBox "Запустите Ваше действие" End If End If End Sub
Вставьте вместо MsgBox «Запустите Ваше действие» ваш код. Полезные макросы можно посмотреть в этой статье. Для этого макроса если, ячейка А1 становится нулевой, то появляется сообщение (MsgBox) «Запустите Ваше действие».
Как запустить макрос при изменении ячейки?
Сперва включите вкладку Разработчик. Затем пройдите в меню Visual Basic, первый значок слева на картинке (или нажмите Alt+f11):
Важно! Чтобы запустить код типа Worksheet_Change, необходимо записать код не в модуль макроса, а в саму книгу! Подробнее здесь:
Выберите нужную книгу и нужный лист (в примере Лист1), кликнув два раза по листу и в правом окне вставьте код, указанный выше. Если вам нужно, чтобы ваше действие выполнялось, когда ячейка изменяет значение на заполненную, то нужно изменить текст Target = 0 на Target <> 0.
Лично я рекомендую добавить больше условий, при каких действиях будет выполняться ваше действие, чтобы макрос не запускался при любом изменении. Вообще надо быть аккуратным с этой функцией. Бывает и такое — вы забываете, что есть макрос с условиями, а информация изменяется, можно даже не заметить этого
Уважаемые знатоки, подскажите, пожалуйста, возможно ли задать событие рабочей книги — изменение определеной ячейки, например А1 на 1 листе, при изменении значения которой будет выполняться макрос
Не торопись, и все успеешь намного быстрее
Доброго дня!
Можно сделать так:
— само собой, вот этот код разместить следует в модуле листа:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$A$1" Then ' реакция на изменение в ячейке с координатами A1 _
если нужна другая ячейка, поменяйте координату, _
т.е. вместо "$A$1" впишите любую другую (знак "$" _
обязателен!
'запускаем наш макрос
myMacro
End If
End Sub
а вот этот, можно в стандартном Модуле:
Function myMacro()
MsgBox "Привет!", vbInformation + vbOKOnly, ""
End Function
Путей к вершине — множество. Этот один из многих!
Большое спасибо за отклик, да еще с таким дельным решением
Не торопись, и все успеешь намного быстрее
Удачи!
Путей к вершине — множество. Этот один из многих!
Попрошу вновь подсказку: данный способ срабатывает при редактировании ячейки с клавиатуры, а как описать событие вставки в ячейку значения из буфера обмена?
Не торопись, и все успеешь намного быстрее
Именно для А1 проще всего написать так:
Private Sub Worksheet_Change(ByVal Target As Range)
If Left(Target.Address, 4) = "$A$1" Then myMacro
End Sub
а вот если это не А1, а другая ячейка, то такая штука может и не прокатить.
Скажи мне, кудесник, любимец ба’гов…
Яндекс-деньги: 41001632713405
Webmoney: R289877159277; Z102172301748; E177867141995
Огромное спасибо. Теперь все заработало. Как же приятно учиться у таких знающих людей
Не торопись, и все успеешь намного быстрее
Цитата: _Boroda_ от 30.08.2010, 17:51
Именно для А1 проще всего написать так:Private Sub Worksheet_Change(ByVal Target As Range)
If Left(Target.Address, 4) = "$A$1" Then myMacro
End Sub
а вот если это не А1, а другая ячейка, то такая штука может и не прокатить.
согласен, но, если сделать так:
Private Sub Worksheet_Change(ByVal Target As Range)
dim nR as long
dim nC as integer
nR=target.row
nC=target.column
If nR = 4 and nC= 2 and target = "Вася" Then myMacro
End Sub
то myMacro сработает лишь тогда, когда в ячейку B4 активного листа будет введено кодовое слово «Вася».
или же выбор с вариациями:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim nR As Long
Dim nC As Integer
nR = Target.Row
nC = Target.Column
If nR = 4 And nC = 2 Then
Select Case Cells(nR, nC).Text
Case "Вася", "Миша"
myMacro1
Case "Петя"
myMacro2
Case Else
MsgBox "Ничего не буду делать!", vbInformation + vbOKOnly, "Сообщение системы:"
End Select
End If
End Sub
Путей к вершине — множество. Этот один из многих!
Доброго дня, уважаемые знатоки!
У меня родился вопрос в продолжение данной темы. Уважаемый Gwolf предложил отличный вариант написания кода для решения данной задачи. Но у меня немного сложнее задача.
Суть в следующем: у меня есть файл в Листе1 указан некий справочник в котором перечислены Города, Сети (названия сетевых магазинов), Магазины этой сети и еще несколько столбцов. Задача у меня следующая: В Листе2 пользователь должен последовательно выбирать данные в каждом из столбцов (допустим, с помощью «списка вариантов», последовательность столбцов аналогичная), исходя из того какой он выбрал город в столбце Сеть ему должны быть предложены только те варианты которые есть в данном городе и аналогично с магазином (только те магазины, которые есть в данной сети).
Например: пользователь выбрал город Актау в столбце Город, далее ему нужно заполнить столбец Сеть. В данном столбце ему предлагаются сетевые магазины только данного города, а не из всего списка (и без повторений как у меня). Затем в следующем столбце он выбирает магазин, который есть только в данной сети.
Подскажите, пожалуйста, как это реализовать? При этом чтобы была возможность дополнять список магазинов и сетей.
Заранее благодарю!
Путей к вершине — множество. Этот один из многих!
GWOlf, вот файл с примером
Sl131 в интернете поищите «зависимые выпадающие списки» посмотрите для общего развития.
Посмотрите приложенный скриншот. Обвел плюсик который следует нажать
Путей к вершине — множество. Этот один из многих!
Благодарю, Gwolf!
Уже приложил файл двумя постами выше!
Доброго дня, господа знатоки!
Я к Вам все с тем же вопросом и просьбой о помощи.
Есть файл с листом «Магазины» (файл приложил) в котором перечислены города, менеджеры, название сетей магазинов и сами магазины. Так вот, я пытался написать макрос, который бы в столбцах С и D листа «MPV» позволял бы выбирать только те магазины, которые есть в выбранном регионе. Для данных столбцов (С и D) написан макрос облегчающий поиск нужного магазина который вызывается правой клавишей мыши (он ссылается на лист «Справочник» столбцы с I по K).
Но как бы я не извращался моих знаний по программированию не хватает.
Помогите, пожалуйста, исправить этот макрос таким образом, чтобы пользователь в столбцах С и D мог выбирать только те магазины, которые есть в данном регионе.
Буду Вам очень признателен за помощь.
Тема: Выполнение макроса при изменении определенной ячейки
Вопрос: выбирать только те магазины, которые есть в данном регионе
Вы ничего не перепутали? Второй Ваш вопрос здесь тоже не по теме.
Не нужно превращать тему в свалку вопросов только потому, что они связаны Вашей задачей.
Давайте не запутывать тех, кто пользуется поиском. Создайте новую тему с назвнием, отражающим суть проблемы.
Добрый вечер Всем.
Пользовался вот этим вариантом запуска макроса(от Boroda),за что ему большое спасибо.
Private Sub Worksheet_Change(ByVal Target As Range)
If Left(Target.Address, 4) = "$A$1" Then Макрос1
End Sub
Но если в ячейке А1 стоит формула,то запуск макроса не происходит.
Как это можно исправить?
Спасибо.
Здравствуйте
Трудно что-то ответить на ваш вопрос.
Скорее всего вы перепутали понятия «пересчет значения ячейки» и «изменение значения ячейки»
Рекомендую создать отдельный топик, приложить файл, как того требуют правила, и тогда можно будет вам чем-то помочь