Событие Worksheet.SelectionChange, используемое в VBA Excel для запуска процедур при выборе диапазона на рабочем листе, в том числе отдельной ячейки.
Синтаксис события Worksheet.SelectionChange
Синтаксис процедуры, выполнение которой инициируется событием Worksheet.SelectionChange:
1 2 3 |
Private Sub Worksheet_SelectionChange(ByVal Target As Range) 'Операторы процедуры End Sub |
Эта процедура VBA Excel запускается при смене на рабочем листе выделенного диапазона (SelectionChange). Она должна быть размещена в модуле рабочего листа Excel, смена выбранного диапазона ячеек которого будет инициировать ее запуск.
Шаблон процедуры можно скопировать и вставить в модуль рабочего листа, но не обязательно. Если открыть модуль нужного листа, выбрать в левом верхнем поле объект Worksheet
, шаблон процедуры будет добавлен автоматически:
У объекта Worksheet
есть и другие события, которые можно выбрать в правом верхнем поле модуля рабочего листа. Процедура с событием SelectionChange добавляется по умолчанию.
Примеры кода с Worksheet.SelectionChange
Пример разработчика
Замечательный пример дан на сайте разработчика:
1 2 3 4 5 6 |
Private Sub Worksheet_SelectionChange(ByVal Target As Range) With ActiveWindow .ScrollRow = Target.Row .ScrollColumn = Target.Column End With End Sub |
При выборе на листе любого диапазона, в том числе отдельной ячейки, лист автоматически прокручивается по горизонтали и вертикали, пока выделенный диапазон не окажется в верхнем левом углу экрана.
Эта процедура работает и при выборе ячейки через адресную строку (слева над обозначениями столбцов), и при выборе из кода VBA Excel, например:
1 |
Range("F5").Select |
Выбор одной отдельной ячейки
Инициируем выполнение основных операторов процедуры с событием Worksheet.SelectionChange выбором одной отдельной ячейки:
1 2 3 4 5 |
Private Sub Worksheet_SelectionChange(ByVal Target As Range) If Target.Address = "$E$5" Then MsgBox "Выбрана ячейка E5" End If End Sub |
Основной оператор MsgBox "Выбрана ячейка E5"
будет выполнен при выборе ячейки E5.
Примечание:
В условии примера используется свойство Address
переменной Target
, так как в прямом выражении Target = Range("E5")
по умолчанию сравниваются значения диапазонов. В результате этого, при выборе другой ячейки со значением, совпадающим со значением ячейки E5, равенство будет истинным и основные операторы будут выполнены, а при выборе более одной ячейки, будет сгенерирована ошибка.
Выбор диапазона с заданной ячейкой
Выполнение основных операторов процедуры при вхождении заданной ячейки в выбранный диапазон:
1 2 3 4 5 |
Private Sub Worksheet_SelectionChange(ByVal Target As Range) If Not Intersect(Target, Range("B3")) Is Nothing Then MsgBox "Ячейка B3 входит в выбранный диапазон" End If End Sub |
Основной оператор MsgBox "Ячейка B3 входит в выбранный диапазон"
будет выполнен при выделении диапазона, в который входит ячейка B3, в том числе и при выделении одной этой ячейки.
Выбор ячейки в заданной строке
Инициируем выполнение основных операторов процедуры с событием Worksheet.SelectionChange выбором любой отдельной ячейки во второй строке:
1 2 3 4 5 6 |
Private Sub Worksheet_SelectionChange(ByVal Target As Range) If Target.Count > 1 Then Exit Sub If Target.Row = 2 Then MsgBox "Выбрана ячейка во второй строке" End If End Sub |
Дополнительный оператор If Target.Count > 1 Then Exit Sub
необходим для выхода из процедуры при выделении более одной ячейки. Причина: при выделении произвольного диапазона, ограниченного сверху второй строкой, выражение Target.Row = 2
будет возвращать значение True
, и операторы в блоке If ... End If
будут выполнены.
Ввод даты в ячейку первого столбца
Автоматическое добавление текущей даты в выбранную ячейку первого столбца при условии, что предыдущая ячейка сверху не пустая, а ячейка снизу – пустая:
1 2 3 4 5 6 |
Private Sub Worksheet_SelectionChange(ByVal Target As Range) If Target.Count > 1 Or Target.Row = 1 Or Target.Row = ActiveSheet.Rows.Count Then Exit Sub If Target.Column = 1 And Target.Offset(-1, 0) <> "" And Target.Offset(1, 0) = "" Then Target = Format(Now, "DD.MM.YYYY") End If End Sub |
Этот код VBA может быть полезен при ведении реестра, базы данных на листе Excel с записью текущей даты в первой колонке.
Условие If Target.Count > 1 Or Target.Row = 1 Or Target.Row = ActiveSheet.Rows.Count Then Exit Sub
завершает процедуру при выборе более одной ячейки, при выборе ячейки A1 и при выборе последней ячейки первого столбца.
Выбор ячейки A1 приводит к ошибке при проверке условия Target.Offset(-1, 0) <> ""
, так как происходит выход за границы диапазона рабочего листа.
Ошибка выхода за пределы рабочего листа происходит и при проверке условия Target.Offset(1, 0) = ""
, если выбрать последнюю ячейку первой колонки.
Примечание:
Текущая дата будет введена в следующую пустую ячейку первого столбца при переходе к ней от заполненной в том числе нажатием клавиши «Enter».
Пример без отслеживания Target
Если необходимо, чтобы процедура запускалась при любой смене выделенного диапазона, аргумент Target можно не отслеживать:
1 2 3 4 5 6 7 |
Private Sub Worksheet_SelectionChange(ByVal Target As Range) If [B1] > 100 Then [A1].Interior.Color = vbGreen Else [A1].Interior.Color = vbBlue End If End Sub |
После ввода значения в ячейку B1
, можно нажать Enter
или кликнуть по любой другой ячейке рабочего листа, и событие Worksheet.SelectionChange сработает.
Здравствуйте, Евгений.
есть код (не мой),
выполняет вставку таблицы при введении «1» (макрос 1), а при введении «2» (макрос 2) не выводит её. Если A1 является формулой, т.е. ссылается на другие ячейки, то все эти выше указанные коды — не работают. Что делать?
Здравствуйте, Алексей!
Ваш код работает правильно. Вы можете проверить, заменив блок If на:
Здравствуйте, Евгений. Я наверно не правильно сформулировал или объяснил. Ваша проверка работает, всё хорошо. Но если поставить на ячейку А1 код, к примеру:
=ЕСЛИ(L1=1;"1";"2")
то всё не работает.
Если интересно, то вот макросы листа:
Алексей, первый макрос перезаписывает ячейку А1, второй — ее удаляет. Если вы поместили в А1 формулу
=ЕСЛИ(L1=1;"1";"2")
, то для запуска процедуры Worksheet_Change отслеживать надо уже изменение ячейки L1, но это сработает однократно, так как формула будет удалена из А1 запущенным макросом:Здравствуйте!
Выбор диапазона с заданной ячейкой
1. Где д. находиться этот код, на листе, в книге или в Modules?
У меня работает только будучи помещённым на листе, и только когда этот лист активен.
2. Каким кодом экспортированный из Modules *.bas поместить в целевом файле на лист?
Приводит к созданию Modules с Имя.bas в целевом файле и, соответственно, не работает Worksheet.SelectionChange.
Прошу помощи.
Спасибо.
Здравствуйте!
1. Worksheet.SelectionChange — событие рабочего листа, и процедура, связанная с ним, может находиться только в модуле этого листа. Происходит событие SelectionChange, когда лист активен. Когда лист не активен, объект Selection ему не принадлежит.
2. Как вариант, можно лист с кодом скопировать из одной книги в другую. Другого способа программного переноса кода из модуля одного листа в модуль другого листа не знаю.
Обсуждение закрыто.