Excel макрос по событию

На чтение 31 мин. Просмотров 19.4k.

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

Несколько способов запуска макроса включают использование диалогового окна макроса, назначение макроса кнопке, использование ярлыка и т.д.

Помимо этих запускаемых пользователем макросов, вы также можете использовать события VBA для запуска макроса.

Содержание

  1. События Excel VBA — Введение
  2. Различные типы событий Excel VBA
  3. Где поставить код, связанный с событием
  4. Понимание последовательности событий
  5. Понимание роли аргументов в событиях VBA
  6. События на уровне рабочей книги (поясняются примерами)
  7. События уровня рабочего листа (объясненные с примерами)
  8. Событие Excel VBA OnTime
  9. Событие Excel VBA OnKey
  10. Отключение событий в VBA
  11. Влияние событий Undo Stack

Позвольте мне сначала объяснить, что такое событие в VBA.

Событие — это действие, которое может инициировать выполнение указанного макроса.

Например, когда вы открываете новую книгу, это событие. Когда вы вставляете новый лист, это событие. Если дважды щелкнуть ячейку, это событие.

В VBA есть много таких событий, и вы можете создавать коды для этих событий. Это означает, что как только происходит событие, и если вы указали код для этого события, этот код будет немедленно выполнен.

Excel автоматически сделает это, как только заметит, что событие произошло. Таким образом, вам нужно только написать код и поместить его в правильную подпрограмму события (это будет описано далее в этой статье).

Например, если вы вставляете новый лист и хотите, чтобы он имел префикс года, вы можете написать для него код.

Теперь, когда кто-нибудь вставляет новый лист, этот код будет автоматически выполняться и добавлять префикс года к имени листа.

Другой пример: вы хотите изменить цвет ячейки, когда кто-то дважды щелкает по ней. Вы можете использовать событие двойного щелчка для этого.

Точно так же вы можете создавать коды VBA для многих таких событий (рассмотрим позже в этой статье).

Ниже приведена краткая картинка, показывающая событие двойного щелчка в действии. Как только я дважды щелкну по ячейке A1. Excel мгновенно открывает окно сообщения, в котором отображается адрес ячейки.

Двойной щелчок — это событие, а отображение окна сообщения — это то, что я указал в коде, когда происходит событие двойного щелчка.

Excel VBA Events Demo Double Click

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

Различные типы событий Excel VBA

В Excel есть разные объекты — например, сам Excel (к которому мы часто обращаемся как приложение), рабочие книги, рабочие таблицы, диаграммы и т.д.

Каждый из этих объектов может иметь различные события, связанные с ним. Например:

  • Если вы создаете новую книгу, это событие уровня приложения.
  • Если вы добавляете новый лист, это событие уровня книги.
  • Если вы измените значение в ячейке на листе, это событие уровня рабочего листа.

Ниже приведены различные типы событий, которые существуют в Excel:

  1. События уровня рабочего листа. Это типы событий, которые запускаются на основе действий, выполненных в рабочем листе. Примеры этих событий включают изменение ячейки на рабочем листе, изменение выделения, двойной щелчок по ячейке, щелчок правой кнопкой мыши по ячейке и т.д.
  2. События на уровне рабочей книги. Эти события будут инициироваться на основе действий на уровне рабочей книги. Примеры таких событий включают добавление новой рабочей таблицы, сохранение рабочей книги, открытие рабочей книги, печать части или всей рабочей книги и т.д.
  3. События уровня приложения: это события, которые происходят в приложении Excel. Примером этого может быть закрытие любой из открытых рабочих книг или открытие новой рабочей книги.
  4. События уровня пользовательской формы: эти события будут инициироваться на основе действий в пользовательской форме. Примеры этого включают инициализацию пользовательской формы или нажатие кнопки в пользовательской форме.
  5. События диаграммы: это события, относящиеся к листу диаграммы. Лист диаграммы отличается от рабочего листа. Примеры таких событий могут включать изменение серии диаграммы или изменение размера диаграммы.
  6. События OnTime и OnKey. Это два события, которые не соответствуют ни одной из перечисленных выше категорий. Поэтому я перечислил их отдельно. Событие «OnTime» позволяет вам выполнить код в определенное время или по истечении определенного времени. Событие «OnKey» позволяет выполнить код, когда используется определенное нажатие клавиши (или комбинация нажатий клавиш).

Где поставить код, связанный с событием

В приведенном выше разделе я рассмотрел различные типы событий.

В зависимости от типа события вам необходимо поместить код в соответствующий объект.

Например, если это событие, связанное с рабочим листом, оно должно идти в окне кода объекта рабочего листа. Если она связана с книгой, она должна идти в окне кода для объекта книги.

В VBA разные объекты — такие как Worksheets, Workbooks, Chart Sheets, UserForms и т.д. Имеют собственные окна кода. Вам необходимо поместить код события в окно кода соответствующего объекта. Например, если это событие уровня рабочей книги, вам нужно иметь код события в окне кода рабочей книги.

Следующие разделы охватывают места, где вы можете поместить код события:

В окне кода Worksheet

Когда вы откроете VB Editor (используя сочетание клавиш ALT + F11), вы заметите объект рабочих таблиц в Project Explorer. Для каждого листа в книге вы увидите один объект.

Excel VBA Events - Worksheets Objects

Если дважды щелкнуть объект листа, в который вы хотите поместить код, откроется окно кода для этого листа.

Хотя вы можете начать писать код с нуля, гораздо лучше выбрать событие из списка параметров и позволить VBA автоматически вставить соответствующий код для выбранного события.

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

Excel VBA Events - Selecting Worksheet Object from the drop down

После выбора рабочего листа из выпадающего списка вы получите список всех событий, связанных с рабочим листом. Вы можете выбрать тот, который вы хотите использовать, из выпадающего списка в правом верхнем углу окна кода.

List of Worksheet Events in VBA

Как только вы выберете событие, оно автоматически введет первую и последнюю строку кода для выбранного события. Теперь вы можете добавить свой код между двумя строками.

Your Code Goes Here is the Worksheet Events

Примечание. Как только вы выберете «Worksheet» в раскрывающемся списке, вы увидите две строки кода в окне кода. После того, как вы выбрали событие, для которого вы хотите код, вы можете удалить строки, которые появились по умолчанию.

Обратите внимание, что каждый лист имеет собственное окно кода. Когда вы вводите код для Лист1, он будет работать только в том случае, если событие происходит в Лист1.

В окне кода ThisWorkBook

Точно так же как рабочие листы, если у вас есть код события уровня книги, вы можете поместить его в окно кода ThisWorkbook.

Excel VBA Events - Workbook Objects

Когда вы дважды щелкните на ThisWorkbook, он откроет окно кода для него.

Вам нужно выбрать Workbook из выпадающего списка в верхнем левом углу окна кода.

Select Workbook Object from the drop down

После выбора Workbook из выпадающего списка вы получите список всех событий, связанных с Workbook. Вы можете выбрать тот, который вы хотите использовать, из выпадающего списка в правом верхнем углу окна кода.

List of Workbook Events in VBA

Как только вы выберете событие, оно автоматически введет первую и последнюю строку кода для выбранного события. Теперь вы можете добавить свой код между двумя строками.

Примечание. Как только вы выберете Workbook из выпадающего списка, вы увидите две строки кода в окне кода. После того, как вы выбрали событие, для которого вы хотите код, вы можете удалить строки, которые появились по умолчанию.

В окне кода Userform

Когда вы создаете пользовательские формы в Excel, вы также можете использовать события пользовательской формы для выполнения кодов на основе определенных действий. Например, вы можете указать код, который будет выполняться при нажатии кнопки.

Хотя объекты Sheet и ThisWorkbook уже доступны при открытии редактора VB, пользовательская форма — это то, что вам нужно создать в первую очередь.

Чтобы создать пользовательскую форму, щелкните правой кнопкой мыши любой из объектов, перейдите на вкладку «Вставка» и выберите «UserForm».

Inserting a Userform in Excel

Это вставит объект UserForm в книгу.

Userform inserted in Excel in the VB Editor

Если дважды щелкнуть пользовательскую форму (или любой объект, который вы добавляете в пользовательскую форму), откроется окно кода для пользовательской формы.

Теперь, так же как рабочие листы или ThisWorkbook, вы можете выбрать событие, и оно вставит первую и последнюю строку для этого события. И тогда вы можете добавить код в середине этого.

В окне кода Chart

В Excel вы также можете вставлять листы диаграмм (которые отличаются от листов). Лист диаграмм должен содержать только диаграммы.

Вставив лист диаграммы, вы сможете увидеть объект листа диаграммы в редакторе VB.

Вы можете добавить код события в окно кода листа диаграммы, как мы это делали на листе.

Дважды щелкните объект листа Chart в Project Explorer. Это откроет окно кода для листа диаграммы.

Обработка событий

Теперь вам нужно выбрать Chart из выпадающего списка в верхнем левом углу окна кода.

Excel VBA Events - Select Chart from the drop down

После выбора Chart из выпадающего списка вы получите список всех событий, связанных с листом Chart. Вы можете выбрать тот, который вы хотите использовать, из выпадающего списка в правом верхнем углу окна кода.

List of Chart Sheet Events in VBA

Примечание. Как только вы выберете Chart из выпадающего списка, вы заметите две строки кода в окне кода. После того, как вы выбрали событие, для которого вы хотите код, вы можете удалить строки, которые появились по умолчанию.

В Class Module

Class Module должны быть вставлены так же, как пользовательские формы.

Inserting a Class Module in Excel

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

Я расскажу о модуле класса в качестве отдельного учебного пособия в ближайшие недели.

Обратите внимание, что кроме событий OnTime и OnKey, ни одно из перечисленных выше событий не может быть сохранено в обычном модуле VBA.

Понимание последовательности событий

Когда вы запускаете событие, оно не происходит изолированно. Это также может привести к последовательности нескольких триггеров.

Например, когда вы вставляете новый лист, происходит следующее:

  1. Добавлен новый рабочий лист
  2. Предыдущая рабочая таблица деактивируется
  3. Новый лист активируется

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

Понимание роли аргументов в событиях VBA

Прежде чем мы перейдем к примерам событий и удивительным вещам, которые вы можете с ним сделать, я должен рассмотреть одну важную концепцию.

В событиях VBA было бы два типа кодов:

  • Без каких-либо аргументов
  • С аргументами

И в этом разделе я хочу быстро осветить роль аргументов.

Ниже приведен код без аргументов (круглые скобки пусты):

Private Sub Workbook_Open()
MsgBox "Не забудьте заполнить расписание"
End Sub

С помощью приведенного выше кода, когда вы открываете рабочую книгу, она просто показывает окно сообщения с сообщением — «Не забудьте заполнить расписание».

Теперь давайте посмотрим на код, который имеет аргумент.

Private Sub Workbook_NewSheet(ByVal Sh As Object)
Sh.Range("A1") = Sh.Name
End Sub

Приведенный выше код использует аргумент Sh, который определен как тип объекта. Аргумент Sh может быть рабочим листом или листом диаграммы, так как указанное выше событие вызывается при добавлении нового листа.

Присвоив новый лист, который добавляется к книге, объектной переменной Sh, VBA позволил нам использовать его в коде. Поэтому, чтобы обратиться к новому названию листа, я могу использовать Sh.Name.

Концепция аргументов будет полезна при ознакомлении с примерами событий VBA в следующих разделах.

События на уровне рабочей книги (поясняются примерами)

Ниже приведены наиболее часто используемые события в книге.

Событие Что запускает событие
Activate Когда книга активирована
AfterSave Когда книга установлена как надстройка
BeforeSave Когда рабочая книга сохранена
BeforeClose Когда рабочая книга закрыта
BeforePrint Когда печатается книга
Deactivate Когда книга деактивирована
NewSheet Когда добавляется новый лист
Open Когда рабочая книга открыта
SheetActivate Когда любой лист в книге
активирован
SheetBeforeDelete При удалении любого листа
SheetBeforeDoubleClick При двойном щелчке по любому листу
SheetBeforeRightClick При щелчке правой кнопкой
мыши по любому листу
SheetCalculate Когда любой лист
рассчитывается или
пересчитывается
SheetDeactivate Когда рабочая книга
деактивирован
SheetPivotTableUpdate При обновлении книги
SheetSelectionChange При изменении рабочей книги
WindowActivate Когда книга активирована
WindowDeactivate Когда книга деактивирована

Обратите внимание, что это не полный список.

Помните, что код для события Workbook хранится в окне кода объектов ThisWorkbook.

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

Событие Workbook Open

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

Вы можете использовать приведенный ниже код, чтобы сделать это:

Private Sub Workbook_Open()
MsgBox "Не забудьте заполнить расписание"
End Sub

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

Workbook Event code example - show reminder

При работе с этим кодом (или с кодами событий рабочей книги в целом) необходимо знать несколько вещей:

  • Если в книге есть макрос, и вы хотите сохранить его, вам нужно сохранить его в формате .XLSM. В противном случае код макроса будет потерян.
  • В приведенном выше примере код события будет выполняться только при включенных макросах. Может появиться желтая полоса, запрашивающая разрешение на включение макросов. Пока это не включено, код события не выполняется.
  • Код события Workbook помещается в окно кода объекта ThisWorkbook.

Вы можете дополнительно уточнить этот код и показать сообщение только пятницы.

Код ниже сделает это:

Private Sub Workbook_Open()
wkday = Weekday(Date)
If wkday = 6 Then MsgBox "Не забудьте заполнить расписание"
End Sub

Обратите внимание, что в функции «Weekday» воскресенье присваивается значение 1, понедельник — 2 и т. Д.

Поэтому на пятницу я использовал 6.

Событие Open Workbook может быть полезно во многих ситуациях, таких как:

  • Когда вы хотите показать приветственное сообщение человеку, когда книга открыта.
  • Когда вы хотите отобразить напоминание, когда рабочая книга открыта.
  • Если вы хотите всегда активировать один конкретный лист в книге, когда она открыта.
  • Когда вы хотите открыть связанные файлы вместе с книгой.
  • Если вы хотите фиксировать дату и время каждый раз, когда открывается рабочая книга.

Событие Workbook NewSheet

Событие NewSheet запускается при вставке нового листа в рабочую книгу.

Допустим, вы хотите ввести значение даты и времени в ячейку A1 вновь вставленного листа. Вы можете использовать приведенный ниже код, чтобы сделать это:

Private Sub Workbook_NewSheet(ByVal Sh As Object)
On Error Resume Next
Sh.Range("A1") = Format(Now, "dd-mmm-yyyy hh:mm:ss")
End Sub

Приведенный выше код использует «On Error Resume Next» для обработки случаев, когда кто-то вставляет лист диаграммы, а не лист. Поскольку на листе диаграммы нет ячейки A1, будет отображаться ошибка, если «On Error Resume Next» не используется.

Другой пример может быть, когда вы хотите применить некоторые базовые настройки или форматирование к новому листу, как только он будет добавлен. Например, если вы хотите добавить новый лист и хотите, чтобы он автоматически получал серийный номер (до 100), то вы можете использовать код ниже.

Private Sub Workbook_NewSheet(ByVal Sh As Object)
On Error Resume Next
With Sh.Range("A1")
.Value = "S. No."
.Interior.Color = vbBlue
.Font.Color = vbWhite
End With
For i = 1 To 100
Sh.Range("A1").Offset(i, 0).Value = i
Next i
Sh.Range("A1", Range("A1").End(xlDown)).Borders.LineStyle = xlContinuous
End Sub

Приведенный выше код также немного форматирует. Это дает ячейке заголовка синий цвет и делает шрифт белым. Это также применяет границу ко всем заполненным ячейкам.

Приведенный выше код является примером того, как короткий код VBA может помочь вам украсть несколько секунд каждый раз, когда вы вставляете новый лист (на случай, если вам придется каждый раз это делать).

Событие Workbook BeforeSave

Событие «BeforeSave» запускается при сохранении книги. Обратите внимание, что событие инициируется сначала, а затем рабочая книга сохраняется.

При сохранении книги Excel возможны два сценария:

  1. Вы сохраняете его в первый раз, и он покажет диалоговое окно Сохранить как.
  2. Вы уже сохранили его ранее, и он просто сохранит и перезапишет изменения в уже сохраненной версии.

Теперь давайте рассмотрим несколько примеров, где вы можете использовать событие BeforeSave.

Предположим, у вас есть новая книга, которую вы сохраняете впервые, и вы хотите напомнить пользователю о необходимости сохранить ее на диске K, затем вы можете использовать следующий код:

Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
If SaveAsUI Then MsgBox "Сохраните этот файл на диске K"
End Sub

В приведенном выше коде, если файл никогда не был сохранен, SaveAsUI имеет значение True и вызывает диалоговое окно Save As. Приведенный выше код будет отображать сообщение до появления диалогового окна «Save As».

Другим примером может быть обновление даты и времени, когда файл сохраняется в определенной ячейке.

Приведенный ниже код вставляет отметку даты и времени в ячейку A1 листа She1 при каждом сохранении файла.

Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
Worksheets("Лист1").Range("A1") = Format(Now, "dd-mmm-yyyy hh:mm:ss")
End Sub

Обратите внимание, что этот код выполняется, как только пользователь сохраняет рабочую книгу. Если книга сохраняется в первый раз, в ней отобразится диалоговое окно «Save As». Но код уже выполняется к тому времени, когда вы видите диалоговое окно Save As. На этом этапе, если вы решите отменить и не сохранить книгу, дата и время уже будут введены в ячейку.

Событие Workbook BeforeClose

Событие «BeforeClose» происходит непосредственно перед закрытием книги.

Приведенный ниже код защищает все рабочие листы до их закрытия.

Private Sub Workbook_BeforeClose(Cancel As Boolean)
Dim sh As Worksheet
For Each sh In ThisWorkbook.Worksheets
sh.Protect
Next sh
End Sub

Помните, что код события срабатывает, как только вы закрываете книгу.

Об этом событии важно знать, что не имеет значения, закрыта ли рабочая книга или нет.

В случае, если рабочая книга не была сохранена, и вы увидите приглашение с вопросом о том, сохранять рабочую книгу или нет, и вы нажмете Отмена, она не сохранит вашу рабочую книгу. Однако код события уже был бы выполнен к тому времени.

Событие Workbook BeforePrint

Когда вы даете команду печати (или команду предварительного просмотра), запускается событие «BeforePrint».

Приведенный ниже код будет пересчитывать все рабочие листы до их печати.

Private Sub Workbook_BeforePrint(Cancel As Boolean)
 For Each ws in Worksheets
 ws.Calculate
 Next ws
 End Sub

Когда пользователь печатает книгу, событие вызывается независимо от того, печатает ли он всю книгу или только ее часть.

Другой пример, приведенный ниже, — это код, который добавляет дату и время в нижний колонтитул при печати рабочей книги.

Private Sub Workbook_BeforePrint(Cancel As Boolean)
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
ws.PageSetup.LeftFooter = "Напечатано - " & Format(Now, "dd-mmm-yyyy hh:mm")
Next ws
End Sub

События уровня рабочего листа (объясненные с примерами)

События рабочего листа происходят на основе триггеров в рабочем листе.

Ниже приведены наиболее часто используемые события на листе.

Событие Что запускает событие
Activate Когда лист активирован
BeforeDelete Перед удалением листа
BeforeDoubleClick Перед двойным щелчком на
листе
BeforeRightClick Перед щелчком правой кнопкой мыши по рабочему листу
Calculate До того, как рабочий лист будет рассчитан или пересчитан
Change При изменении ячеек на листе
Deactivate Когда лист деактивирован
PivotTableUpdate При обновлении сводной
таблицы на листе
SelectionChange Когда выбор на рабочем листе
изменяется

Обратите внимание, что это не полный список. Вы можете найти полный список здесь.

Помните, что код события Worksheet хранится в окне кода объекта рабочего листа (в том, в котором вы хотите, чтобы событие было запущено). В одной книге может быть несколько рабочих листов, и ваш код будет запущен только тогда, когда событие происходит в рабочей таблице, в которой оно размещено.

Теперь давайте посмотрим на некоторые полезные события на листе и посмотрим, как их можно использовать в вашей повседневной работе.

Событие Worksheet Activate

Это событие вызывается при активации рабочего листа.

Приведенный ниже код снимает защиту листа, как только он активирован.

Private Sub Worksheet_Activate()
ActiveSheet.Unprotect
End Sub

Вы также можете использовать это событие, чтобы убедиться, что конкретная ячейка или диапазон ячеек (или именованный диапазон) выбран, как только вы активируете рабочую таблицу. Приведенный ниже код выберет ячейку D1, как только вы активируете лист.

Private Sub Worksheet_Activate()
ActiveSheet.Range("D1").Select
End Sub

Событие Worksheet Change

Событие изменения запускается всякий раз, когда вы вносите изменения в лист.

Ну .. не всегда.

Есть некоторые изменения, которые вызывают событие, а некоторые нет. Вот список некоторых изменений, которые не вызовут событие:

  • При изменении форматирования ячейки (размер шрифта, цвет, рамка и т.д.).
  • Когда вы объединяете клетки. Это удивительно, так как иногда объединение ячеек также удаляет содержимое из всех ячеек, кроме верхнего левого.
  • Когда вы добавляете, удаляете или редактируете комментарий к ячейке.
  • Когда вы сортируете диапазон ячеек.
  • Когда вы используете поиск цели.

Следующие изменения могут вызвать событие (даже если вы думаете, что не должно):

  • Копирование и вставка форматирования вызовут событие.
  • Очистка форматирования вызовет событие.
  • Запуск проверки орфографии вызовет событие.

Ниже код будет отображать окно сообщения с адресом ячейки, которая была изменена.

Private Sub Worksheet_Change(ByVal Target As Range)
MsgBox "Вы только что изменились " & Target.Address
End Sub

Хотя это бесполезный макрос, он показывает, как использовать аргумент Target, чтобы узнать, какие ячейки были изменены.

Теперь давайте посмотрим пару более полезных примеров.

Предположим, у вас есть диапазон ячеек (скажем, A1: D10), и вы хотите показать подсказку и спросить пользователя, действительно ли он хочет изменить ячейку в этом диапазоне, вы можете использовать приведенный ниже код.

Отображается подсказка с двумя кнопками — «Да» и «Нет». Если пользователь выбирает «Да», изменение выполняется, в противном случае оно отменяется.

Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Row <= 10 And Target.Column <= 4 Then
Ans = MsgBox("Вы вносите изменения в ячейки в A1: D10. Вы уверены, что хотите это?", vbYesNo)
End If
If Ans = vbNo Then
Application.EnableEvents = False
Application.Undo
Application.EnableEvents = True
End If
End Sub

В приведенном выше коде мы проверяем, находится ли целевая ячейка в первых 4 столбцах и первых 10 строках. Если это так, появится окно сообщения. Кроме того, если пользователь выбрал «Нет» в окне сообщения, изменение отменяется (с помощью команды Application.Undo).

Обратите внимание, что я использовал Application.EnableEvents = False перед строкой Application.Undo. И затем я изменил его, используя Application.EnableEvent = True в следующей строке.

Это необходимо, поскольку, когда происходит отмена, это также вызывает событие изменения. Если я не установлю для параметра EnableEvent значение False, он продолжит вызывать событие изменения.

Вы также можете отслеживать изменения в именованном диапазоне, используя событие изменения. Например, если у вас есть именованный диапазон с именем «DataRange», и вы хотите показать подсказку на случай, если пользователь внесет изменение в этот именованный диапазон, вы можете использовать код ниже:

Private Sub Worksheet_Change(ByVal Target As Range)
Dim DRange As Range
Set DRange = Range("DataRange")
If Not Intersect(Target, DRange) Is Nothing Then
MsgBox "Вы только что внесли изменения в диапазон данных"
End If
End Sub

Приведенный выше код проверяет, имеет ли ячейка / диапазон, в котором вы внесли изменения, какие-либо ячейки, общие для диапазона данных. Если это так, он показывает окно сообщения.

Событие SelectionChange Workbook

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

Приведенный ниже код будет пересчитывать лист, как только вы измените выбор.

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Application.Calculate
End Sub

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

Что-то, как показано ниже:

Excel VBA Events - Selection change event

Следующий код может сделать это:

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Cells.Interior.ColorIndex = xlNone
With ActiveCell
.EntireRow.Interior.Color = RGB(248, 203, 173)
.EntireColumn.Interior.Color = RGB(180, 198, 231)
End With
End Sub

Код сначала удаляет цвет фона из всех ячеек, а затем применяет цвет, упомянутый в коде, к активной строке и столбцу.

И это проблема с этим кодом. Что он удаляет цвет со всех клеток.

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

Событие Workbook DoubleClick

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

Это событие срабатывает при двойном щелчке по ячейке.

Позвольте мне показать вам, как это круто.

С помощью приведенного ниже кода вы можете дважды щелкнуть ячейку, и она применит цвет фона, изменит цвет шрифта и сделает текст в ячейке жирным;

Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
Cancel = True
With Target
.Interior.Color = vbBlue
.Font.Color = vbWhite
.Font.Bold = True
End With
End Sub

Это может быть полезно, когда вы просматриваете список ячеек и хотите выделить несколько выбранных. Хотя вы можете использовать клавишу F4, чтобы повторить последний шаг, он сможет применить только один вид форматирования. С этим событием двойного щелчка вы можете применить все три с помощью двойного щелчка.

Обратите внимание, что в приведенном выше коде я сделал значение Cancel = True.

Это сделано для того, чтобы действие двойного щелчка по умолчанию было отключено — то есть войти в режим редактирования. Если Cancel = True, Excel не переведет вас в режим редактирования, если дважды щелкнуть ячейку.

Вот еще один пример.

Если у вас есть список дел в Excel, вы можете использовать событие двойного щелчка, чтобы применить формат перечеркивания, чтобы пометить задачу как выполненную.

Как показано ниже:

Excel VBA Event - Double Click Event

Вот код, который сделает это:

Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
Cancel = True
CurrFormat = Target.Font.Strikethrough
If CurrFormat Then
Target.Font.Strikethrough = False
Else
Target.Font.Strikethrough = True
End If
End Sub

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

Событие Excel VBA OnTime

События, которые мы видели до сих пор в этой статье, были связаны с одним из объектов Excel, будь то рабочая книга, рабочий лист, лист диаграммы или пользовательские формы и т.д.

Событие OnTime отличается от других событий, поскольку оно может быть сохранено в обычном модуле VBA (тогда как другие должны были быть помещены в окно кода объектов, таких как ThisWorkbook или Worksheets или UserForms).

В обычном модуле VBA он используется как метод объекта приложения.

Причина, по которой это считается событием, заключается в том, что оно может быть запущено в зависимости от указанного вами времени. Например, если я хочу, чтобы лист пересчитывался каждые 5 минут, я могу использовать для него событие OnTime.

Или, если я хочу показать сообщение / напоминание в определенное время дня, я могу использовать событие OnTime.

Ниже приведен код, который будет показывать сообщение в 2 часа дня каждый день.

Sub MessageTime()
Application.OnTime TimeValue("14:00:00"), "ShowMessage"
End Sub

Sub ShowMessage()
MsgBox "Время обеда"
End Sub

Помните, что вам нужно поместить этот код в обычный модуль VBA,

Кроме того, хотя событие OnTime будет запускаться в указанное время, макрос необходимо запускать вручную в любое время. После запуска макроса он будет ждать до 14:00, а затем вызовет макрос «ShowMessage».

Макрос ShowMessage будет отображать сообщение.

Событие OnTime принимает четыре аргумента:

Application.OnTime (Самое раннее время, Процедура, Последнее время, Расписание)

  • EarliestTime: время, когда вы хотите запустить процедуру.
  • Procedure: имя процедуры, которая должна быть запущена.
  • LatestTime (Необязательно): Если другой код выполняется и указанный код не может быть запущен в указанное время, вы можете указать LatestTime, которого он должен ждать. Например, это может быть EarliestTime + 45 (что означает, что он будет ждать 45 секунд, пока другая процедура завершится). Если даже через 45 секунд процедура не может быть запущена, она прекращается. Если вы не укажете это, Excel подождет, пока код может быть запущен, а затем запустит его.
  • Schedule (необязательно): если установлено значение «ИСТИНА», оно планирует новую процедуру времени. Если ЛОЖЬ, то это отменяет ранее установленную процедуру. По умолчанию это ИСТИНА

В приведенном выше примере мы использовали только первые два аргумента.

Давайте посмотрим на другой пример.

Приведенный ниже код будет обновлять лист каждые 5 минут.

Dim NextRefresh as Date

Sub RefreshSheet()
ThisWorkbook.Worksheets("Лист1").Calculate
NextRefresh = Now + TimeValue("00:05:00")
Application.OnTime NextRefresh, "RefreshSheet"
End Sub

Sub StopRefresh()
On Error Resume Next
Application.OnTime NextRefresh, "RefreshSheet", , False
End Sub

Приведенный выше код обновляет лист каждые 5 минут.

Он использует функцию «Now», чтобы определить текущее время, а затем добавляет 5 минут к текущему времени.

Событие OnTime будет продолжаться до тех пор, пока вы его не остановите. Если вы закроете книгу, а приложение Excel все еще будет запущено (другие книги открыты), книга, в которой запущено событие OnTime, снова откроется.

Это лучше сделать, если специально остановить событие OnTime.

В приведенном выше коде у меня есть код StopRefresh, но вам нужно выполнить его, чтобы остановить событие OnTime. Вы можете сделать это вручную, назначить ее кнопке и сделать это, нажав кнопку или вызвав ее из события закрытия рабочей книги.

Private Sub Workbook_BeforeClose(Cancel As Boolean)
Call StopRefresh
End Sub

Вышеупомянутый код события «BeforeClose» находится в окне кода ThisWorkbook.

Событие Excel VBA OnKey

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

С помощью события OnKey вы можете указать нажатие клавиши (или комбинацию нажатий клавиш) и код, который должен выполняться при использовании этого нажатия клавиши. При нажатии этих клавиш выполняется код для него.

Точно так же, как событие OnTime, у вас должен быть способ отменить событие OnKey. Кроме того, когда вы устанавливаете событие OnKey для определенного нажатия клавиши, оно становится доступным во всех открытых книгах.

Прежде чем я покажу вам пример использования события OnKey, позвольте мне сначала поделиться кодами клавиш, которые вам доступны в VBA.

Ключ Код
Backspace {BACKSPACE} or {BS}
Break {BREAK}
Caps Lock {CAPSLOCK}
Delete {DELETE} or {DEL}
Down Arrow {DOWN}
End {END}
Enter ~
Enter (on the nueric keypad) {ENTER}
Escape {ESCAPE} or {ESC}
Home {HOME}
Ins {INSERT}
Left Arrow {LEFT}
NumLock {NUMLOCK}
PageDown {PGDN}
PageUp {PGUP}
RightArrow {RIGHT}
Scroll Lock {SCROLLOCK}
Tab {TAB}
Up Arrow {UP}
F1 through F15 {F1} through {F15}

Когда вам нужно использовать любое событие onkey, вам нужно использовать код для него.

В приведенной выше таблице приведены коды для однократных нажатий.

Вы также можете комбинировать их со следующими кодами:

Shift: + (знак плюс)
Контроль: ^ (Карет)
Alt:% (в процентах)
Например, для Alt F4 вам нужно использовать код: «% {F4}» — где% для клавиши ALT, а {F4} для клавиши F4.

Теперь давайте посмотрим на примере (помните, код для событий OnKey находится в обычном модуле VBA).

Когда вы нажимаете клавишу PageUp или PageDown, она переходит на 29 строк выше / ниже активной ячейки (по крайней мере, это то, что она делает на моем ноутбуке).

Если вы хотите, чтобы он перескакивал только на 5 строк одновременно, вы можете использовать следующий код:

Sub PageUpDOwnKeys()
Application.OnKey "{PgUp}", "PageUpMod"
Application.OnKey "{PgDn}", "PageDownMod"
End Sub

Sub PageUpMod()
On Error Resume Next
ActiveCell.Offset(-5, 0).Activate
End Sub

Sub PageDownMod()
On Error Resume Next
ActiveCell.Offset(5, 0).Activate
End Sub

Когда вы запускаете первую часть кода, он запускает события OnKey. Как только это будет выполнено, использование PageUp и клавиши PageDown заставит курсор перескакивать только на 5 строк за раз.

Обратите внимание, что мы использовали «On Error Resume Next», чтобы убедиться, что ошибки игнорируются. Эти ошибки могут возникать, когда вы нажимаете клавишу PageUp, даже если вы находитесь в верхней части листа. Поскольку больше нет строк для перехода, код покажет ошибку. Но так как мы использовали «On Error Resume Next», он будет проигнорирован.

Чтобы убедиться, что эти события OnKey доступны, вам нужно запустить первую часть кода. Если вы хотите, чтобы это было доступно, как только вы откроете рабочую книгу, вы можете поместить ее в окно кода ThisWorkbook.

Private Sub Workbook_Open()
Application.OnKey "{PgUp}", "PageUpMod"
Application.OnKey "{PgDn}", "PageDownMod"
End Sub

Приведенный ниже код вернет ключи к их нормальной работе.

Sub Cancel_PageUpDownKeysMod()
Application.OnKey "{PgUp}"
Application.OnKey "{PgDn}"
End Sub

Если вы не укажете второй аргумент в методе OnKey, он вернет нажатие клавиши к своей обычной функциональности.

В случае, если вы хотите отменить функциональность нажатия клавиши, чтобы Excel ничего не делал при использовании этого нажатия клавиши, вам нужно использовать пустую строку в качестве второго аргумента.

В приведенном ниже коде Excel ничего не будет делать, когда мы используем ключи PageUp или PageDown.

Sub Ignore_PageUpDownKeys()
Application.OnKey "{PgUp}", ""
Application.OnKey "{PgDn}", ""
End Sub

Отключение событий в VBA

Иногда вам может потребоваться отключить события, чтобы ваш код работал правильно.

Например, предположим, что у меня есть диапазон (A1: D10), и я хочу показать сообщение всякий раз, когда ячейка изменяется в этом диапазоне. Поэтому я показываю окно сообщения и спрашиваю пользователя, уверены ли они, что хотят внести изменения. Если ответ «Да», изменение внесено, и если ответ «Нет», VBA отменит его.

Вы можете использовать следующий код:

Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Row <= 10 And Target.Column <= 4 Then
Ans = MsgBox("Вы вносите изменения в ячейки в A1: D10. Вы уверены, что хотите это?", vbYesNo)
End If
If Ans = vbNo Then
Application.Undo
End If
End Sub

Проблема с этим кодом заключается в том, что когда пользователь выбирает «Нет» в окне сообщения, действие отменяется (как я использовал Application.Undo).

Когда происходит отмена, и значение возвращается к исходному, событие изменения VBA снова инициируется, и пользователю снова отображается то же самое окно сообщения.

Это означает, что вы можете продолжать нажимать НЕТ в окне сообщения, и оно будет отображаться. Это происходит, когда вы застряли в бесконечном цикле в этом случае.

Чтобы избежать таких случаев, вам нужно отключить события, чтобы событие изменения (или любое другое событие) не срабатывало.

Следующий код будет хорошо работать в этом случае:

Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Row <= 10 And Target.Column <= 4 Then
Ans = MsgBox("Вы вносите изменения в ячейки в A1: D10. Вы уверены, что хотите это?", vbYesNo)
End If
If Ans = vbNo Then
Application.EnableEvents = False
Application.Undo
Application.EnableEvents = True
End If
End Sub

В приведенном выше коде, прямо над строкой Application.Undo, мы использовали — Application.EnableEvents = False.

Если для параметра EnableEvents установлено значение False, это не приведет к возникновению какого-либо события (в текущей или любой открытой рабочей книге).

После того, как мы завершили операцию отмены, мы можем переключить свойство EnableEvents на True.

Имейте в виду, что отключение событий влияет на все книги, которые в данный момент открыты (или открыты, когда для параметра EnableEvents установлено значение False). Например, как часть кода, если вы откроете новую книгу, событие Workbook Open не будет работать.

Влияние событий Undo Stack

Позвольте мне сначала рассказать вам, что такое Undo Stack.

Когда вы работаете в Excel, он продолжает следить за вашими действиями. Когда вы делаете ошибку, вы всегда можете использовать Control + Z, чтобы вернуться к предыдущему шагу (то есть отменить ваше текущее действие).

Если вы дважды нажмете Control + Z, это вернет вас назад на два шага. Эти шаги, которые вы выполнили, сохраняются как часть Undo Stack.

Любое событие, которое изменяет рабочий лист, уничтожает этот стек отмены. Это означает, что если я выполнил 5 действий до запуска события, я не смогу использовать Control + Z, чтобы вернуться к этим предыдущим шагам. Запуск события уничтожил этот стек для меня.

В приведенном ниже коде я использую VBA для ввода метки времени в ячейку A1 при каждом изменении в листе.

Private Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = False
Range("A1").Value = Format(Now, "dd-mmm-yyyy hh:mm:ss")
Application.EnableEvents = True
End Sub

Поскольку я делаю изменения в листе, это уничтожит Undo Stack.

Также обратите внимание, что это не ограничивается только событиями.

Если у вас есть код, который хранится в обычном модуле VBA, и вы вносите изменения в рабочую таблицу, это также уничтожит Undo Stack в Excel.

Например, приведенный ниже код просто вводит текст «Hello» в ячейку A1, но даже выполнение этого приведет к разрушению
Undo Stack.

Sub TypeHello()
Range("A1").Value = "Привет"
End Sub
 

Микки

Пользователь

Сообщений: 3280
Регистрация: 24.12.2012

Добрый день данные макрос запускаются по событиям в определенных ячейках:
Private Sub Worksheet_Change(ByVal Target As Range)
If Intersect(Target, [m1:ar10000]) Is Nothing Then Exit Sub
With Target
If .Cells.Count > 1 Then Exit Sub
Select Case .Column
Case 13: Call MyMail(.Row, 13)
Case 16: Call MyMail(.Row, 16)
Case 26: Call MyMail1(.Row, 26)
Case 29: Call MyMail1(.Row, 29)

End Select
End With

End Sub

А можно сделать так , чтою они запускались по вводу числа (даты) , например при очитке ячейки мне макрос не нужен.
Спасибо

 

Igor67

Пользователь

Сообщений: 3726
Регистрация: 21.12.2012

Добавить проверку на наличие данных в ячейке?
With Target
If .Cells.Count > 1 Then Exit Sub
if .value > 0 then
Select Case .Column
Case 13: Call MyMail(.Row, 13)
Case 16: Call MyMail(.Row, 16)
Case 26: Call MyMail1(.Row, 26)
Case 29: Call MyMail1(.Row, 29)
End Select
end if
End With

 

V

Пользователь

Сообщений: 5018
Регистрация: 22.12.2012

#3

15.04.2013 11:51:33

проверка именно даты.

Код
If IsDate(Target) = False Then Exit Sub
 

Микки

Пользователь

Сообщений: 3280
Регистрация: 24.12.2012

Спасибо.

Я так понимаю это надо после  With Target воткнуть ?
А если число или дата можно?

 

V

Пользователь

Сообщений: 5018
Регистрация: 22.12.2012

#5

15.04.2013 12:27:49

мои знания поверхностные, ну раз спецы молчат предложу вариант

Код
.....
If IsNumeric(Target) = True Or IsDate(Target) = True Then
With Target
....
End With
Else: Exit Sub
End If
End Sub
 

Юрий М

Модератор

Сообщений: 60570
Регистрация: 14.09.2012

Контакты см. в профиле

#6

15.04.2013 12:33:28

Нагляднее так:

Код
If Not IsDate(Target) Then ...

Миша, уточни задачу — всё перепуталось ))

 

Микки

Пользователь

Сообщений: 3280
Регистрация: 24.12.2012

Уточняю если ввели число ИЛИ дату посылаем …если текст ,очистили ячейку ввели пробел ИЛИ «0» то не посылаем ничего .

 

Юрий М

Модератор

Сообщений: 60570
Регистрация: 14.09.2012

Контакты см. в профиле

Если текст ,очистили ячейку ввели пробел ИЛИ «0» — это нормальная ситуация . Так?

 

RAN

Пользователь

Сообщений: 7091
Регистрация: 21.12.2012

#9

15.04.2013 13:06:55

Код
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    On Error Resume Next
    If Target.Value > 0 Then
        MsgBox IsDate(CDate(Target.Value)) & vbLf & Target.Value
    End If
End Sub
 

Микки

Пользователь

Сообщений: 3280
Регистрация: 24.12.2012

Да ситуация нормальная особо очистка …но макрос не запускаем Юр, запускаем только в случае введения числа отличного от 0 или Даты

 

Юрий М

Модератор

Сообщений: 60570
Регистрация: 14.09.2012

Контакты см. в профиле

 

Микки

Пользователь

Сообщений: 3280
Регистрация: 24.12.2012

Спасибо Юра и Ran…. мне бы еще понять как всю эту бодягу встроить в работающий макрос с

Select Case .Column
Case 13: Call MyMail(.Row, 13)
Case 16: Call MyMail(.Row, 16)
Case 26: Call MyMail1(.Row, 26)
Case 29: Call MyMail1(.Row, 29)
End Select

см. пост1 в этой теме.

 

Юрий М

Модератор

Сообщений: 60570
Регистрация: 14.09.2012

Контакты см. в профиле

А в чём проблема? В моём коде меняй диапазон, вместо MsgBox пишем Exit Sub. А затем уже твои Select Case .Column

 

RAN

Пользователь

Сообщений: 7091
Регистрация: 21.12.2012

#14

15.04.2013 13:51:30

Код
Private Sub Worksheet_Change(ByVal Target As Range)
    With Target
        If .Count > 1 Then Exit Sub
        If .Value > 0 Then
            On Error Resume Next
            If CDate(.Value) Then
                Select Case .Column
                Case 13, 16, 26, 29
                    Call MyMail(.Row, .Column)
                End Select
            End If
        End If
    End With
End Sub
 

Микки

Пользователь

Сообщений: 3280
Регистрация: 24.12.2012

#15

15.04.2013 14:02:26

Цитата
Юрий М пишет:
А в чём проблема? В моём коде меняй диапазон, вместо MsgBox пишем Exit Sub. А затем уже твои Select Case .Column

Юра ты прекрасно знаешь что для меня и это проблема там еще какие-то With Target…Вот диапазон поменять смогу))))

 

Микки

Пользователь

Сообщений: 3280
Регистрация: 24.12.2012

 

Микки

Пользователь

Сообщений: 3280
Регистрация: 24.12.2012

#17

15.04.2013 15:46:34

Цитата
RAN пишет:
If Intersect(Target, [m1:ar10000]) Is Nothing Then Exit Sub
With Target

Цитата
RAN пишет:

Код
 Private Sub Worksheet_Change(ByVal Target As Range)
    With Target
        If .Count > 1 Then Exit Sub
        If .Value > 0 Then
            On Error Resume Next
            If CDate(.Value) Then
                Select Case .Column
                Case 13, 16, 26, 29
                    Call MyMail(.Row, .Column)
                End Select
            End If
        End If
    End With
End Sub 

А у меня еще конструкция была…

If Intersect(Target, [m1:ar10000]) Is Nothing Then Exit Sub
With Target

ее то куда Ran
Спасибо

 

V

Пользователь

Сообщений: 5018
Регистрация: 22.12.2012

Микки там же и оставьте где и была (перед With Target)

 

RAN

Пользователь

Сообщений: 7091
Регистрация: 21.12.2012

#19

15.04.2013 16:04:32

Цитата
Микки пишет:
А у меня еще конструкция была…
….
ее то куда Ran

A зачем она вам? Дорога как память?  :)

 

Микки

Пользователь

Сообщений: 3280
Регистрация: 24.12.2012

Я настолько слаб в макросах ..что боюсь отпилить что-либо  нужное ..хотя насколько я понял Ваш ..оно там лишнее?

 

RAN

Пользователь

Сообщений: 7091
Регистрация: 21.12.2012

#21

15.04.2013 16:20:31

Прозевал, однако.
Так надо

Код
    Select Case .Column
    Case 13, 16
        Call MyMail(.Row, .Column)
    Case 26, 29
        Call MyMail1(.Row, .Column)
    End Select
 

Микки

Пользователь

Сообщений: 3280
Регистрация: 24.12.2012

Ну до этого я бы и сам додумался..все равно огромное спасибо

 

V

Пользователь

Сообщений: 5018
Регистрация: 22.12.2012

на сколько я понимаю данная строчка отвечает за то чтоб макрос срабатывал только в диапазоне m1:ar10000, а у вас RAN по моему макрос будет срабатывать в любой ячейке листа (даты и числа не касаюсь) или я не правильно понимаю? Если я прав то вопрос к Микки нужно ли это ограничение?
хотя пока не знаю за что отвечает процедура Case, может из за неё и ни нужна данная строка.  :(

Изменено: V15.04.2013 16:39:06

 

RAN

Пользователь

Сообщений: 7091
Регистрация: 21.12.2012

#24

15.04.2013 16:44:44

Не совсем так.
Макрос в любом случае срабатывает в любой ячейке листа.
Если есть конструкция

Код
If Intersect(Target, [m1:ar10000]) Is Nothing Then Exit Sub 

то в зависимости от выполнения условия макрос либо продолжает, либо завершает работу.

Если этой конструкции нет, то при условии ввода числа/даты в столбцы 13, 16, 26 или 29 запускается процедура отправки письма.

В остальных случаях никаких действий не выполняется, точнее, выполняются 2 лишних проверки.

 

V

Пользователь

Сообщений: 5018
Регистрация: 22.12.2012

 

Микки

Пользователь

Сообщений: 3280
Регистрация: 24.12.2012

#26

16.04.2013 13:23:59

Спасибо всем огромное тема закрыта работает как надо .

Запуск макроса (процедуры) из кода 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 VBA — Введение
  • Различные типы событий Excel VBA
  • Где разместить код, связанный с событием
  • Понимание последовательности событий
  • Понимание роли аргументов в событиях VBA
  • События на уровне книги (с примерами)
  • События уровня рабочего листа (объяснение с примерами)
  • Событие onTime Excel VBA
  • Событие Excel VBA OnKey
  • Отключение событий в VBA
  • Влияние стека отмены событий

Когда вы создаете или записываете макрос в Excel, вам необходимо запустить макрос для выполнения шагов в коде.

Несколько способов запуска макроса включают использование диалогового окна макроса, назначение макроса кнопке, использование ярлыка и т. Д.

Помимо этих запускаемых пользователем макросов, вы также можете использовать события VBA для запуска макроса.

Позвольте мне сначала объяснить, что такое событие в VBA.

Событие — это действие, которое может инициировать выполнение указанного макроса.

Например, когда вы открываете новую книгу, это событие. Когда вы вставляете новый лист, это событие. Если дважды щелкнуть ячейку, это событие.

В VBA много таких событий, и вы можете создавать коды для этих событий. Это означает, что как только происходит событие, и если вы указали код для этого события, этот код будет немедленно выполнен.

Excel автоматически делает это, как только замечает, что произошло событие. Таким образом, вам нужно только написать код и поместить его в нужную подпрограмму обработки событий (это будет рассмотрено далее в этой статье).

Например, если вы вставляете новый лист и хотите, чтобы на нем был префикс года, вы можете написать для него код.

Теперь, когда кто-либо вставляет новый лист, этот код будет автоматически выполняться и добавлять префикс года к имени листа.

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

Точно так же вы можете создавать коды VBA для многих таких событий (как мы увидим позже в этой статье).

Ниже приведено короткое изображение, показывающее действие двойного щелчка. Как только я дважды щелкаю по ячейке A1. Excel мгновенно открывает окно сообщения, в котором отображается адрес ячейки.

Двойной щелчок — это событие, а отображение окна сообщения — это то, что я указал в коде всякий раз, когда происходит событие двойного щелчка.

Хотя приведенный выше пример является бесполезным событием, я надеюсь, что он поможет вам понять, что это за события на самом деле.

Различные типы событий Excel VBA

В Excel есть разные объекты, такие как сам Excel (который мы часто называем приложением), книги, рабочие листы, диаграммы и т. Д.

С каждым из этих объектов могут быть связаны различные события. Например:

  • Если вы создаете новую книгу, это событие уровня приложения.
  • Если вы добавляете новый лист, это событие уровня книги.
  • Если вы измените значение в ячейке на листе, это произойдет на уровне рабочего листа.

Ниже приведены различные типы событий, которые существуют в Excel:

  1. События уровня рабочего листа: Это типы событий, которые будут запускаться в зависимости от действий, предпринятых на листе. Примеры этих событий включают изменение ячейки на листе, изменение выделения, двойной щелчок по ячейке, щелчок правой кнопкой мыши по ячейке и т. Д.
  2. События уровня книги: Эти события будут запускаться на основе действий на уровне книги. Примеры этих событий включают добавление нового листа, сохранение книги, открытие книги, печать части или всей книги и т. Д.
  3. События уровня приложения: Это события, которые происходят в приложении Excel. Примером этого может быть закрытие любой из открытых книг или открытие новой книги.
  4. События уровня UserForm: Эти события будут запускаться на основе действий в «UserForm». Примеры этого включают инициализацию UserForm или нажатие кнопки в UserForm.
  5. График событий: Это события, связанные с листом диаграммы. Лист диаграммы отличается от рабочего листа (с которым большинство из нас привыкло работать в Excel). Назначение листов диаграммы — держать диаграмму. Примеры таких событий могут включать изменение серии диаграммы или изменение размера диаграммы.
  6. События OnTime и OnKey: Это два события, которые не попадают ни в одну из вышеперечисленных категорий. Поэтому я перечислил их отдельно. Событие OnTime позволяет выполнить код в определенное время или по истечении определенного времени. Событие OnKey позволяет выполнять код при использовании определенного нажатия клавиши (или комбинации нажатий клавиш).

Где разместить код, связанный с событием

В приведенном выше разделе я рассмотрел различные типы событий.

Исходя из типа события, вам нужно поместить код в соответствующий объект.

Например, если это событие, связанное с листом, оно должно находиться в окне кода объекта листа. Если это связано с книгой, он должен войти в окно кода для объекта книги.

В VBA разные объекты, такие как рабочие листы, рабочие книги, таблицы диаграмм, пользовательские формы и т. Д., Имеют свои собственные окна кода. Вам необходимо поместить код события в окно кода соответствующего объекта. Например, если это событие уровня книги, вам необходимо иметь код события в окне кода книги.

В следующих разделах описаны места, где можно разместить код события:

В окне кода рабочего листа

Когда вы открываете редактор VB (используя сочетание клавиш ALT + F11), вы можете заметить объект рабочих листов в проводнике проекта. Для каждого листа в книге вы увидите один объект.

Если дважды щелкнуть объект листа, в который нужно поместить код, откроется окно кода для этого листа.

Хотя вы можете начать писать код с нуля, гораздо лучше выбрать событие из списка параметров и позволить VBA автоматически вставить соответствующий код для выбранного события.

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

После выбора рабочего листа в раскрывающемся списке вы получите список всех событий, связанных с рабочим листом. Вы можете выбрать тот, который хотите использовать, из раскрывающегося списка в правом верхнем углу окна кода.

Как только вы выберете событие, оно автоматически введет первую и последнюю строку кода для выбранного события. Теперь вы можете добавить свой код между двумя строками.

Примечание. Как только вы выберете «Рабочий лист» в раскрывающемся списке, вы заметите, что в окне кода появятся две строки кода. После того, как вы выбрали событие, для которого вы хотите код, вы можете удалить строки, которые появляются по умолчанию.

Обратите внимание, что на каждом листе есть собственное окно кода. Когда вы помещаете код для Sheet1, он будет работать, только если событие произойдет в Sheet1.

В окне кода ThisWorkbook

Как и в случае с рабочими листами, если у вас есть код события на уровне книги, вы можете поместить его в окно кода ThisWorkbook.

Если дважды щелкнуть ThisWorkbook, откроется окно кода для него.

Вам нужно выбрать Workbook из раскрывающегося списка в верхнем левом углу окна кода.

После выбора Workbook в раскрывающемся списке вы получите список всех событий, связанных с Workbook. Вы можете выбрать тот, который хотите использовать, из раскрывающегося списка в правом верхнем углу окна кода.

Как только вы выберете событие, оно автоматически введет первую и последнюю строку кода для выбранного события. Теперь вы можете добавить свой код между двумя строками.

Примечание. Как только вы выберете «Рабочая книга» в раскрывающемся списке, вы заметите, что в окне кода появятся две строки кода. После того, как вы выбрали событие, для которого вы хотите код, вы можете удалить строки, которые появляются по умолчанию.

В окне кода пользовательской формы

Когда вы создаете пользовательские формы в Excel, вы также можете использовать события UserForm для выполнения кода на основе определенных действий. Например, вы можете указать код, который будет выполняться при нажатии кнопки.

Хотя объекты Sheet и ThisWorkbook уже доступны при открытии редактора VB, UserForm — это то, что вам нужно создать в первую очередь.

Чтобы создать пользовательскую форму, щелкните правой кнопкой мыши любой из объектов, выберите «Вставить» и нажмите «Пользовательская форма».

Это вставит объект UserForm в книгу.

Если дважды щелкнуть UserForm (или любой объект, который вы добавляете в UserForm), откроется окно кода для UserForm.

Теперь, как и в рабочих таблицах или ThisWorkbook, вы можете выбрать событие, и оно вставит первую и последнюю строки для этого события. А затем вы можете добавить код в его середину.

В окне кода диаграммы

В Excel вы также можете вставлять листы диаграмм (которые отличаются от листов). Лист диаграммы предназначен только для содержания диаграмм.

Когда вы вставили лист диаграммы, вы сможете увидеть объект листа диаграммы в редакторе VB.

Вы можете добавить код события в окно кода листа диаграммы так же, как мы это делали на листе.

Дважды щелкните объект листа диаграммы в проводнике проекта. Это откроет окно кода для листа диаграммы.

Теперь вам нужно выбрать Диаграмму из раскрывающегося списка в верхнем левом углу окна кода.

После выбора «Диаграмма» в раскрывающемся списке вы получите список всех событий, связанных с листом «Диаграмма». Вы можете выбрать тот, который хотите использовать, из раскрывающегося списка в правом верхнем углу окна кода.

Примечание. Как только вы выберете «Диаграмма» в раскрывающемся списке, вы заметите, что в окне кода появляются две строки кода. После того, как вы выбрали событие, для которого вы хотите код, вы можете удалить строки, которые появляются по умолчанию.

В модуле класса

Модули классов нужно вставлять так же, как и UserForms.

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

В ближайшие недели я расскажу о модуле класса как отдельное руководство.

Обратите внимание, что кроме событий OnTime и OnKey, ни одно из указанных выше событий не может быть сохранено в обычном модуле VBA.

Понимание последовательности событий

Когда вы запускаете событие, оно не происходит изолированно. Это также может привести к последовательности нескольких триггеров.

Например, когда вы вставляете новый лист, происходит следующее:

  1. Добавлен новый рабочий лист
  2. Предыдущий рабочий лист деактивируется
  3. Новый рабочий лист активируется

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

Понимание роли аргументов в событиях VBA

Прежде чем мы перейдем к примерам событий и удивительным вещам, которые вы можете с ними сделать, есть одна важная концепция, которую мне нужно осветить.

В событиях VBA будет два типа кодов:

  • Без всяких аргументов
  • С аргументами

В этом разделе я хочу быстро осветить роль аргументов.

Ниже приведен код, в котором нет аргументов (круглые скобки пусты):

Private Sub Workbook_Open () MsgBox "Не забудьте заполнить расписание" End Sub

С помощью приведенного выше кода, когда вы открываете книгу, она просто показывает окно сообщения с сообщением — «Не забудьте заполнить расписание».

Теперь давайте посмотрим на код, в котором есть аргумент.

Private Sub Workbook_NewSheet (ByVal Sh как объект) Sh.Range ("A1") = Sh.Name End Sub

В приведенном выше коде используется аргумент Sh, который определяется как тип объекта. Аргументом Sh может быть рабочий лист или лист диаграммы, поскольку указанное выше событие запускается при добавлении нового листа.

Назначив новый лист, добавляемый в книгу, объектной переменной Sh, VBA позволил нам использовать его в коде. Поэтому для обозначения нового имени листа я могу использовать Sh.Name.

Концепция аргументов будет полезна при рассмотрении примеров событий VBA в следующих разделах.

События на уровне книги (с примерами)

Ниже приведены наиболее часто используемые события в книге.

НАЗВАНИЕ СОБЫТИЯ ЧТО ВЫЗЫВАЕТ СОБЫТИЕ
Активировать Когда книга активирована
После сохранения Когда книга установлена ​​как надстройка
ПередСохранить Когда книга сохранена
ДоЗакрыть Когда книга закрыта
Перед печатью Когда напечатана рабочая тетрадь
Деактивировать Когда книга деактивирована
NewSheet Когда добавляется новый лист
Открыть Когда книга открыта
SheetActivate Когда активирован какой-либо лист в книге
SheetBeforeDelete Когда какой-либо лист удален
SheetBeforeDoubleClick При двойном щелчке по любому листу
SheetBeforeRightClick При щелчке правой кнопкой мыши по любому листу
SheetCalculate Когда любой лист рассчитывается или пересчитывается
SheetDeactivate Когда книга деактивирована
SheetPivotTableUpdate Когда книга обновляется
SheetSelectionChange Когда рабочая книга изменена
WindowActivate Когда книга активирована
WindowDeactivate Когда книга деактивирована

Обратите внимание, что это не полный список. Вы можете найти полный список здесь.

Помните, что код для события Workbook хранится в окне кода объектов ThisWorkbook.

Теперь давайте взглянем на некоторые полезные события из рабочей тетради и посмотрим, как их можно использовать в повседневной работе.

Событие открытия книги

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

Для этого вы можете использовать приведенный ниже код:

Private Sub Workbook_Open () MsgBox "Не забудьте заполнить расписание" End Sub

Теперь, как только вы откроете книгу с этим кодом, она покажет вам окно сообщения с указанным сообщением.

При работе с этим кодом (или кодами событий рабочей книги в целом) необходимо знать несколько вещей:

  • Если в книге есть макрос, и вы хотите его сохранить, вам необходимо сохранить его в формате .XLSM. В противном случае код макроса будет потерян.
  • В приведенном выше примере код события будет выполняться только тогда, когда макросы включены. Вы можете увидеть желтую полосу с запросом разрешения на включение макросов. Пока это не будет включено, код события не выполняется.
  • Код события Workbook помещается в окно кода объекта ThisWorkbook.

Вы можете дополнительно уточнить этот код и показать сообщение только пятницы.

Следующий код сделает это:

Private Sub Workbook_Open () wkday = Weekday (Date) Если wkday = 6, то MsgBox «Не забудьте заполнить расписание» End Sub

Обратите внимание, что в функции «День недели» воскресенье имеет значение 1, понедельник — 2 и т. Д.

Поэтому для пятницы я использовал 6.

Событие Workbook Open может быть полезно во многих ситуациях, например:

  • Когда вы хотите показать человеку приветственное сообщение при открытии книги.
  • Если вы хотите отображать напоминание при открытии книги.
  • Если вы хотите всегда активировать один конкретный рабочий лист в книге, когда она открыта.
  • Если вы хотите открыть связанные файлы вместе с книгой.
  • Если вы хотите фиксировать дату и время при каждом открытии книги.

Событие NewSheet в книге

Событие NewSheet запускается, когда вы вставляете новый лист в книгу.

Допустим, вы хотите ввести значение даты и времени в ячейку A1 только что вставленного листа. Для этого вы можете использовать приведенный ниже код:

Private Sub Workbook_NewSheet (ByVal Sh As Object) При ошибке Возобновить Далее Sh.Range ("A1") = Format (Теперь, "dd-mmm-yyyy hh: mm: ss") End Sub

В приведенном выше коде используется «Возобновить при ошибке» для обработки случаев, когда кто-то вставляет лист диаграммы, а не лист. Поскольку на листе диаграммы нет ячейки A1, будет отображаться сообщение об ошибке, если не использовать «On Error Resume Next».

Другим примером может быть случай, когда вы хотите применить некоторые базовые настройки или форматирование к новому листу сразу после его добавления. Например, если вы хотите добавить новый лист и хотите, чтобы он автоматически получал серийный номер (до 100), вы можете использовать приведенный ниже код.

Private Sub Workbook_NewSheet (ByVal Sh As Object) При ошибке Возобновить следующий с Sh.Range ("A1") .Value = "S. No." .Interior.Color = vbBlue .Font.Color = vbWhite End With For i = от 1 до 100 Sh.Range ("A1"). Offset (i, 0) .Value = i Next i Sh.Range ("A1", Range ("A1"). End (xlDown)). Borders.LineStyle = xlContinuous End Sub

Приведенный выше код также выполняет небольшое форматирование. Он придает ячейке заголовка синий цвет, а шрифт — белый. Он также применяет границу ко всем заполненным ячейкам.

Приведенный выше код является примером того, как короткий код VBA может помочь вам украсть несколько секунд каждый раз, когда вы вставляете новый рабочий лист (в случае, если это то, что вам нужно делать каждый раз).

Рабочая книга перед событием сохранения

Перед сохранением событие запускается при сохранении книги. Обратите внимание, что сначала запускается событие, а затем книга сохраняется.

При сохранении книги Excel может быть два возможных сценария:

  1. Вы сохраняете его впервые, и появится диалоговое окно «Сохранить как».
  2. Вы уже сохранили его ранее, и он просто сохранит и перезапишет изменения в уже сохраненной версии.

Теперь давайте рассмотрим несколько примеров, в которых вы можете использовать событие BeforeSave.

Предположим, у вас есть новая книга, которую вы сохраняете впервые, и вы хотите напомнить пользователю о необходимости сохранить ее на диске K, тогда вы можете использовать следующий код:

Private Sub Workbook_BeforeSave (ByVal SaveAsUI As Boolean, Cancel As Boolean) Если SaveAsUI Then MsgBox «Сохранить этот файл на K-диске» End Sub

В приведенном выше коде, если файл никогда не сохранялся, SaveAsUI имеет значение True и вызывает диалоговое окно «Сохранить как». Приведенный выше код отобразит сообщение до появления диалогового окна «Сохранить как».

Другим примером может быть обновление даты и времени, когда файл сохраняется в определенной ячейке.

Приведенный ниже код будет вставлять метку даты и времени в ячейку A1 листа Sheet1 при сохранении файла.

Private Sub Workbook_BeforeSave (ByVal SaveAsUI As Boolean, Cancel As Boolean) Worksheets ("Sheet1"). Range ("A1") = Format (Now, "dd-mmm-yyyy hh: mm: ss") End Sub

Обратите внимание, что этот код выполняется, как только пользователь сохраняет книгу. Если книга сохраняется в первый раз, отобразится диалоговое окно «Сохранить как». Но код уже выполняется к тому моменту, когда вы видите диалоговое окно «Сохранить как». На этом этапе, если вы решите отменить и не сохранять книгу, дата и время уже будут введены в ячейку.

Рабочая книга перед событием закрытия

Событие Before Close происходит непосредственно перед закрытием книги.

Приведенный ниже код защищает все рабочие листы до закрытия книги.

Private Sub Workbook_BeforeClose (Отменить как логическое) Dim sh As Worksheet для каждого sh в ThisWorkbook.Worksheets sh.Protect Next sh End Sub

Помните, что код события запускается, как только вы закрываете книгу.

Об этом событии важно знать, что его не волнует, закрыта книга на самом деле или нет.

Если книга не была сохранена, и вам отображается запрос с вопросом, сохранять книгу или нет, и вы нажимаете «Отмена», книга не будет сохранена.Однако к тому времени код события уже был бы выполнен.

Workbook BeforePrint Event

Когда вы даете команду печати (или команду предварительного просмотра), запускается событие Перед печатью.

Приведенный ниже код пересчитает все рабочие листы перед печатью вашей книги.

Private Sub Workbook_BeforePrint (Cancel As Boolean) для каждого ws в листах ws.Calculate Next ws End Sub

Когда пользователь печатает книгу, событие запускается независимо от того, печатает ли он всю книгу или только ее часть.

Другой пример ниже — это код, который добавит дату и время в нижний колонтитул при печати книги.

Private Sub Workbook_BeforePrint (Cancel As Boolean) Dim ws As Worksheet For Each ws In ThisWorkbook.Worksheets ws.PageSetup.LeftFooter = "Напечатано -" & Format (Теперь, "dd-mmm-yyyy hh: mm") Next ws End Sub

События уровня рабочего листа (объяснение с примерами)

События рабочего листа происходят на основе триггеров на листе.

Ниже приведены наиболее часто используемые события на листе.

Название события Что вызывает событие
Активировать Когда рабочий лист активирован
Перед Удалить Перед удалением рабочего листа
Перед DoubleClick Перед двойным щелчком по листу
BeforeRightClick Перед щелчком правой кнопкой мыши по листу
Рассчитать Перед расчетом или перерасчетом рабочего листа
Изменять Когда ячейки на листе изменены
Деактивировать Когда рабочий лист деактивирован
PivotTableUpdate Когда сводная таблица на листе обновляется
SelectionChange Когда выбор на листе изменен

Обратите внимание, что это не полный список. Вы можете найти полный список здесь.

Помните, что код для события рабочего листа хранится в окне кода объекта рабочего листа (в том, в котором вы хотите, чтобы событие запускалось). В книге может быть несколько листов, и ваш код будет запускаться только тогда, когда событие происходит на листе, в который он помещен.

Теперь давайте взглянем на некоторые полезные события на листе и посмотрим, как их можно использовать в повседневной работе.

Рабочий лист активировать событие

Это событие запускается, когда вы активируете лист.

Приведенный ниже код снимает защиту с листа, как только он активируется.

Private Sub Worksheet_Activate () ActiveSheet.Unprotect End Sub

Вы также можете использовать это событие, чтобы убедиться, что определенная ячейка или диапазон ячеек (или именованный диапазон) выбраны, как только вы активируете рабочий лист. Приведенный ниже код выберет ячейку D1, как только вы активируете лист.

Private Sub Worksheet_Activate () ActiveSheet.Range ("D1"). Выберите End Sub

Событие изменения рабочего листа

Событие изменения запускается всякий раз, когда вы вносите изменения в рабочий лист.

Ну… не всегда.

Некоторые изменения запускают событие, а некоторые нет. Вот список некоторых изменений, которые не активируют событие:

  • При изменении форматирования ячейки (размер шрифта, цвет, граница и т. Д.).
  • Когда вы объединяете ячейки. Это удивительно, поскольку иногда при слиянии ячеек также удаляется содержимое всех ячеек, кроме верхней левой.
  • Когда вы добавляете, удаляете или редактируете комментарий к ячейке.
  • Когда вы сортируете диапазон ячеек.
  • Когда вы используете Goal Seek.

Следующие изменения вызовут событие (даже если вы думаете, что это не должно происходить):

  • Копирование и вставка форматирования вызовут событие.
  • Очистка форматирования вызовет событие.
  • Запуск проверки орфографии вызовет событие.

Ниже приведен код, отображающий окно сообщения с адресом измененной ячейки.

Private Sub Worksheet_Change (ByVal Target As Range) MsgBox «Вы только что изменили» и Target.Address End Sub

Хотя это бесполезный макрос, он показывает, как использовать аргумент Target, чтобы узнать, какие ячейки были изменены.

А теперь давайте посмотрим еще пару полезных примеров.

Предположим, у вас есть диапазон ячеек (скажем, A1: D10), и вы хотите показать подсказку и спросить пользователя, действительно ли он хочет изменить ячейку в этом диапазоне или нет, вы можете использовать приведенный ниже код.

Он показывает подсказку с двумя кнопками — Да и Нет. Если пользователь выбирает «Да», изменение выполняется, в противном случае оно отменяется.

Private Sub Worksheet_Change (ByVal Target As Range) Если Target.Row <= 10 And Target.Column <= 4 Then Ans = MsgBox («Вы вносите изменение в ячейки в A1: D10. Вы уверены, что хотите?», vbYesNo) End If If Ans = vbNo Then Application.EnableEvents = False Application.Undo Application.EnableEvents = True End If End Sub

В приведенном выше коде мы проверяем, находится ли целевая ячейка в первых 4 столбцах и первых 10 строках. В этом случае отображается окно сообщения. Кроме того, если пользователь выбрал Нет в окне сообщения, изменение отменяется (командой Application.Undo).

Обратите внимание, что я использовал Application.EnableEvents = False перед строкой Application.Undo. И затем я изменил это, используя Application.EnableEvent = True в следующей строке.

Это необходимо, поскольку, когда происходит отмена, она также запускает событие изменения. Если я не установлю для EnableEvent значение False, оно продолжит запускать событие изменения.

Вы также можете отслеживать изменения именованного диапазона с помощью события изменения. Например, если у вас есть именованный диапазон под названием «DataRange», и вы хотите показать подсказку в случае, если пользователь внесет изменения в этот именованный диапазон, вы можете использовать приведенный ниже код:

Private Sub Worksheet_Change (ByVal Target As Range) Dim DRange As Range Set DRange = Range ("DataRange") Если не Intersect (Target, DRange) Is Nothing Then MsgBox "Вы только что внесли изменение в диапазон данных" End If End Sub

Приведенный выше код проверяет, есть ли в ячейке / диапазоне, в котором вы внесли изменения, какие-либо ячейки, общие для диапазона данных. Если это так, отображается окно сообщения.

Событие выбора книги

Событие изменения выбора запускается всякий раз, когда на листе происходит изменение выбора.

Приведенный ниже код пересчитает лист, как только вы измените выбор.

Private Sub Worksheet_SelectionChange (ByVal Target As Range) Application.Calculate End Sub

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

Что-то вроде того, что показано ниже:

Следующий код может это сделать:

Private Sub Worksheet_SelectionChange (ByVal Target As Range) Cells.Interior.ColorIndex = xlNone With ActiveCell .EntireRow.Interior.Color = RGB (248, 203, 173) .EntireColumn.Interior.Color = RGB (180, 198, 231) Заканчивается на Конец подписки

Код сначала удаляет цвет фона из всех ячеек, а затем применяет цвет, упомянутый в коде, к активной строке и столбцу.

И в этом проблема этого кода. Что убирает цвет со всех ячеек.

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

Рабочая книга DoubleClick Event

Это одно из моих любимых событий рабочего листа, и вы увидите множество руководств, в которых я его использовал (например, этот или этот).

Это событие запускается при двойном щелчке по ячейке.

Позвольте мне показать вам, насколько это круто.

С помощью приведенного ниже кода вы можете дважды щелкнуть ячейку, и она применит цвет фона, изменит цвет шрифта и сделает текст в ячейке жирным;

Private Sub Worksheet_BeforeDoubleClick (ByVal Target As Range, Cancel As Boolean) Cancel = True With Target .Interior.Color = vbBlue .Font.Color = vbWhite .Font.Bold = True End With End Sub

Это может быть полезно, когда вы просматриваете список ячеек и хотите выделить несколько выбранных. Хотя вы можете использовать клавишу F4 для повторения последнего шага, можно будет применить только один вид форматирования. С помощью этого события двойного щелчка вы можете применить все три одним двойным щелчком.

Обратите внимание, что в приведенном выше коде я установил значение Cancel = True.

Это сделано для того, чтобы действие двойного щелчка по умолчанию было отключено, то есть переход в режим редактирования. Если Отмена = True, Excel не переведет вас в режим редактирования при двойном щелчке по ячейке.

Другой пример.

Если у вас есть список дел в Excel, вы можете использовать событие двойного щелчка, чтобы применить зачеркнутый формат, чтобы пометить задачу как выполненную.

Что-то вроде того, что показано ниже:

Вот код, который это сделает:

Private Sub Worksheet_BeforeDoubleClick (ByVal Target As Range, Cancel As Boolean) Cancel = True CurrFormat = Target.Font.Strikethrough If CurrFormat Then Target.Font.Strikethrough = False Else Target.Font.Strikethrough = True End If End Sub

Обратите внимание, что в этом коде я сделал двойной щелчок как событие переключения. Когда вы дважды щелкаете ячейку, она проверяет, применялся ли уже зачеркнутый формат. Если это так, двойной щелчок удаляет зачеркнутый формат, а если нет, применяется зачеркнутый формат.

Событие onTime Excel VBA

События, которые мы видели до сих пор в этой статье, были связаны с одним из объектов Excel, будь то книга, рабочий лист, лист диаграммы или пользовательские формы и т. Д.

Событие OnTime отличается от других событий, поскольку оно может храниться в обычном модуле VBA (в то время как остальные должны были быть помещены в окно кода таких объектов, как ThisWorkbook, Worksheets или UserForms).

В обычном модуле VBA он используется как метод объекта приложения.

Причина, по которой это считается событием, заключается в том, что оно может быть инициировано в указанное вами время. Например, если я хочу, чтобы лист пересчитывался каждые 5 минут, я могу использовать для этого событие OnTime.

Или, если я хочу показать сообщение / напоминание в определенное время дня, я могу использовать событие OnTime.

Ниже приведен код, который будет показывать сообщение в 14:00 каждый день.

Sub MessageTime () Application.OnTime TimeValue ("14:00:00"), "ShowMessage" End Sub Sub ShowMessage () MsgBox "It's Lunch Time" End Sub

Помните, что вам нужно поместить этот код в обычный модуль VBA,

Кроме того, хотя событие OnTime будет запускаться в указанное время, вам необходимо запустить макрос вручную в любое время. Как только вы запустите макрос, он дождется 14:00, а затем вызовет макрос ShowMessage.

После этого макрос ShowMessage отобразит сообщение.

Событие OnTime принимает четыре аргумента:

Application.OnTime (EarlyTime, Процедура, LatestTime, График)

  • Самое раннее время: Время, когда вы хотите запустить процедуру.
  • Процедура: Имя процедуры, которую нужно запустить.
  • LatestTime (необязательно): В случае, если выполняется другой код, а указанный код не может быть запущен в указанное время, вы можете указать LatestTime, в течение которого он должен ждать. Например, это может быть EarliestTime + 45 (что означает, что он будет ждать завершения другой процедуры в течение 45 секунд). Если даже через 45 секунд процедура не может быть запущена, она прерывается. Если вы не укажете это, Excel подождет, пока код будет запущен, а затем запустит его.
  • Расписание (необязательно): Если установлено значение True, он планирует новую временную процедуру. Если False, то отменяет ранее установленную процедуру. По умолчанию это True.

В приведенном выше примере мы использовали только первые два аргумента.

Давайте посмотрим на другой пример.

Приведенный ниже код будет обновлять рабочий лист каждые 5 минут.

Dim NextRefresh as Date Sub RefreshSheet () ThisWorkbook.Worksheets ("Sheet1"). Calculate NextRefresh = Now + TimeValue ("00:05:00") Application.OnTime NextRefresh, "RefreshSheet" End Sub Sub StopRefresh () При ошибке Возобновить Далее Application.OnTime NextRefresh, «RefreshSheet»,, False End Sub

Приведенный выше код будет обновлять лист каждые 5 минут.

Он использует функцию «Сейчас» для определения текущего времени, а затем добавляет 5 минут к текущему времени.

Событие OnTime будет продолжать выполняться, пока вы его не остановите. Если вы закроете книгу, а приложение Excel все еще работает (другие книги открыты), книга, в которой запущено событие OnTime, откроется снова.

С этим лучше справиться, специально остановив событие OnTime.

В приведенном выше коде у меня есть код StopRefresh, но вам нужно выполнить его, чтобы остановить событие OnTime. Вы можете сделать это вручную, назначить его кнопке и сделать это, нажав кнопку или вызвав его из события закрытия книги.

Private Sub Workbook_BeforeClose (Отменить как логическое) Вызов StopRefresh End Sub

Приведенный выше код события «BeforeClose» появляется в окне кода ThisWorkbook.

Событие Excel VBA OnKey

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

С помощью события OnKey вы можете указать нажатие клавиши (или комбинацию нажатий клавиш) и код, который должен выполняться при использовании этого нажатия клавиши. Когда эти нажатия клавиш нажаты, он выполнит код для этого.

Как и в случае с событием OnTime, у вас должен быть способ отменить событие OnKey. Кроме того, когда вы устанавливаете событие OnKey для определенного нажатия клавиши, оно становится доступным во всех открытых книгах.

Прежде чем я покажу вам пример использования события OnKey, позвольте мне сначала поделиться кодами клавиш, которые доступны вам в VBA.

КЛЮЧ КОД
Backspace {BACKSPACE} или {BS}
Сломать {СЛОМАТЬ}
Caps Lock {CAPSLOCK}
Удалить {УДАЛИТЬ} или {УДАЛИТЬ}
Стрелка вниз {ВНИЗ}
Конец {КОНЕЦ}
Войти ~
Enter (на цифровой клавиатуре) {ВОЙТИ}
Побег {ESCAPE} или {ESC}
Дом {ДОМ}
Ins {ВСТАВЛЯТЬ}
Стрелка влево {ЛЕВЫЙ}
NumLock {NUMLOCK}
Листать вниз {PGDN}
PageUp {PGUP}
Правая стрелка {ВЕРНО}
Scroll Lock {SCROLLOCK}
Вкладка {TAB}
Стрелка вверх {ВВЕРХ}
С F1 по F15 С {F1} по {F15}

Когда вам нужно использовать какое-либо событие onkey, вам нужно использовать для него код.

В приведенной выше таблице есть коды для одиночных нажатий клавиш.

Вы также можете комбинировать их со следующими кодами:

  • Сдвиг: + (Знак плюс)
  • Контроль: ^ (Карет)
  • Alt: % (В процентах)

Например, для Alt F4 вам нужно использовать код: «% {F4}”- где% для клавиши ALT, а {F4} для клавиши F4.

Теперь давайте посмотрим на пример (помните, что код для событий OnKey помещается в обычный модуль VBA).

Когда вы нажимаете клавишу PageUp или PageDown, он перескакивает на 29 строк выше / ниже активной ячейки (по крайней мере, это то, что он делает на моем ноутбуке).

Если вы хотите, чтобы он перескакивал только 5 строк за раз, вы можете использовать следующий код:

Sub PageUpDOwnKeys () Application.OnKey "{PgUp}", "PageUpMod" Application.OnKey "{PgDn}", "PageDownMod" Конец Sub Sub PageUpMod () При ошибке Возобновить След. ActiveCell.Offset (-5, 0). Активировать Конец Sub Sub PageDownMod () При ошибке Возобновить Далее ActiveCell.Offset (5, 0) .Activate End Sub

Когда вы запускаете первую часть кода, она запускает события OnKey. Как только это будет выполнено, использование PageUp и клавиши PageDown заставит курсор перемещаться только на 5 строк за раз.

Обратите внимание, что мы использовали «Возобновить после ошибки», чтобы убедиться, что ошибки игнорируются. Эти ошибки могут возникать при нажатии клавиши PageUp, даже если вы находитесь в верхней части листа. Поскольку строк для перехода больше нет, код покажет ошибку. Но поскольку мы использовали «При ошибке возобновить следующий», он будет проигнорирован.

Чтобы убедиться, что эти события OnKey доступны, необходимо запустить первую часть кода. Если вы хотите, чтобы это было доступно, как только вы откроете книгу, вы можете поместить это в окно кода ThisWorkbook.

Частная подписка Workbook_Open () Application.OnKey "{PgUp}", "PageUpMod" Application.OnKey "{PgDn}", "PageDownMod" End Sub

Приведенный ниже код вернет ключи к их нормальному функционированию.

Sub Cancel_PageUpDownKeysMod () Application.OnKey "{PgUp}" Application.OnKey "{PgDn}" End Sub

Если вы не укажете второй аргумент в методе OnKey, он вернет нажатие клавиши в обычном режиме.

Если вы хотите отменить функциональность нажатия клавиши, чтобы Excel ничего не делал при использовании этого нажатия клавиши, вам нужно использовать пустую строку в качестве второго аргумента.

В приведенном ниже коде Excel ничего не сделает, когда мы будем использовать ключи PageUp или PageDown.

Sub Ignore_PageUpDownKeys () Application.OnKey "{PgUp}", "" Application.OnKey "{PgDn}", "" End Sub

Отключение событий в VBA

Иногда вам может потребоваться отключить события, чтобы ваш код работал правильно.

Например, предположим, что у меня есть диапазон (A1: D10), и я хочу отображать сообщение всякий раз, когда ячейка изменяется в этом диапазоне. Поэтому я показываю окно сообщения и спрашиваю пользователя, уверены ли они, что хотят внести изменения. Если ответ «Да», изменение внесено, а если ответ «Нет», VBA отменит его.

Вы можете использовать приведенный ниже код:

Private Sub Worksheet_Change (ByVal Target As Range) Если Target.Row <= 10 And Target.Column <= 4 Then Ans = MsgBox («Вы вносите изменение в ячейки в A1: D10. Вы уверены, что хотите?», vbYesNo) End If If Ans = vbNo Then Application.Undo End If End Sub

Проблема с этим кодом заключается в том, что, когда пользователь выбирает «Нет» в окне сообщения, действие отменяется (как я использовал Application.Undo).

Когда происходит отмена и значение изменяется обратно на исходное, снова запускается событие изменения VBA, и пользователю снова отображается то же окно сообщения.

Это означает, что вы можете продолжать нажимать НЕТ в окне сообщения, и оно будет отображаться. Это происходит из-за того, что в этом случае вы застряли в бесконечном цикле.

Чтобы избежать таких случаев, вам необходимо отключить события, чтобы событие изменения (или любое другое событие) не запускалось.

В этом случае подойдет следующий код:

Private Sub Worksheet_Change (ByVal Target As Range) Если Target.Row <= 10 And Target.Column <= 4 Then Ans = MsgBox («Вы вносите изменение в ячейки в A1: D10. Вы уверены, что хотите?», vbYesNo) End If If Ans = vbNo Then Application.EnableEvents = False Application.Undo Application.EnableEvents = True End If End Sub

В приведенном выше коде прямо над строкой Application.Undo мы использовали — Application.EnableEvents = False.

Установка для EnableEvents значения False не вызовет никаких событий (в текущей или любых открытых книгах).

После того, как мы завершили операцию отмены, мы можем снова переключить свойство EnableEvents на True.

Имейте в виду, что отключение событий влияет на все книги, открытые в данный момент (или открытые, если для EnableEvents установлено значение False). Например, как часть кода, если вы откроете новую книгу, событие Workbook Open не сработает.

Влияние стека отмены событий

Позвольте мне сначала рассказать вам, что такое стек отмены.

Когда вы работаете в Excel, он постоянно отслеживает ваши действия. Если вы допустили ошибку, вы всегда можете использовать Control + Z, чтобы вернуться к предыдущему шагу (т. Е. Отменить текущее действие).

Если вы дважды нажмете Control + Z, вы вернетесь на два шага назад. Эти выполненные вами шаги сохраняются как часть стека отмены.

Любое событие, которое изменяет рабочий лист, уничтожает этот стек отмены.Это означает, что если я сделал 5 действий до запуска события, я не смогу использовать Control + Z, чтобы вернуться к этим предыдущим шагам. Запуск события уничтожил этот стек для меня.

В приведенном ниже коде я использую VBA для ввода метки времени в ячейку A1 всякий раз, когда на листе происходит изменение.

Private Sub Worksheet_Change (ByVal Target As Range) Application.EnableEvents = False Range («A1»). Value = Format (Теперь, «дд-ммм-гггг чч: мм: сс») Application.EnableEvents = True End Sub

Поскольку я вношу изменение в лист, это уничтожит стек отмены.

Также обратите внимание, что это не ограничивается только событиями.

Если у вас есть код, который хранится в обычном модуле VBA, и вы вносите изменения в рабочий лист, это также уничтожит стек отмены в Excel.

Например, в приведенном ниже коде просто введите текст «Hello» в ячейку A1, но даже запуск этого приведет к разрушению стека отмены.

Sub TypeHello () Range ("A1"). Value = "Hello" End Sub

Вам также могут понравиться следующие руководства по Excel VBA:

  • Работа с ячейками и диапазонами в Excel VBA.
  • Работа с листами в Excel VBA.
  • Работа с книгами в Excel VBA.
  • Циклы Excel VBA — полное руководство.
  • Использование IF Then Else Statment в Excel VBA.
  • Для следующего цикла в Excel.
  • Создание пользовательских функций в Excel VBA.
  • Как создавать и использовать надстройки в Excel.
  • Создавайте и повторно используйте макросы, сохраняя их в личной книге макросов.

Это глава из книги Билла Джелена Гуру Excel расширяют горизонты: делайте невозможное с Microsoft Excel.

Задача: в предыдущей заметке мы рассмотрели создание обычного макроса, который располагается в модуле VBA. Вместе с тем существуют специальные макросы, называемые обработчиками событий, которые запускаются автоматически в ответ на событие, происходящее в Excel.

Рис. 1. Для доступа к коду объекта ThisWorkbook кликните на ней правой кнопкой мыши и выберите View Code

Рис. 1. Для доступа к коду объекта ThisWorkbook кликните на ней правой кнопкой мыши и выберите View Code

Скачать заметку в формате Word или pdf, примеры в формате Excel (с кодом VBA)

Справочная информация: вот некоторые из часто используемых обработчиков событий:

  • Workbook_open – этот макрос запускается при открытии книги.
  • Workbook_BeforeClose – этот макрос запускается после того, как кто-то пытается закрыть книгу, но прежде чем появляется окно с вопросом, нужно ли сохранить изменения.
  • Workbook_BeforePrint – этот макрос запускается, когда кто-то выдает команду печати, но перед отправкой задания на принтер. Макрос позволяет добавить настройки в печатную форму, например, путь к файлу или имя пользователя в колонтитуле листа.
  • Worksheet_change – этот удивительный макрос запускается каждый раз, когда пользователь вводит значение в любую ячейку листа.
  • Worksheet_Activate – этот макрос подобен Workbook_open, но запускается при переходе на лист. Может быть, вы хотите, чтобы появлялись определенные пункты меню, когда кто-то переходит на конкретный лист.
  • Worksheet_SelectionChange – этот макрос запускается каждый раз при переходе в новую ячейку на листе.

Обработчики события являются мощными инструментами, но они работают корректно, только если должным образом введены в редакторе VBA. Код VBA следует ввести не в традиционный модуль, а в область кода листа или книги Excel.

Решение: допустим, вы нашли какой-то код, который хотите выполнить для события BeforePrint. Это событие соответствует уровню книги, так что код нужно поместить в соответствующую область. Выполните следующие действия.

Откройте книгу Excel. Переключитесь в редактор VBA, нажав сочетание клавиш Alt+F11. Если окно проектов (VBAProject) отсутствует, выведете его на экран, нажав Ctrl+R. Найти книгу в списке проектов. Щелкните на знак + слева от имени книги, а затем на знак + слева от Microsoft Excel Objects и Modules. Это развернет представление книг и рабочих листов вплоть до имен листов и названия модулей. Вы также увидите строки ThisWorkbook (ЭтаКнига). Именно в этих объектах следует хранить код для событий уровня книги. Дважды щелкните на строку ThisWorkbook. Также можно кликнуть на ней правой кнопкой мыши и выбрать опцию View Code (рис. 1).

Если вы копируете макрос из Интернета, самое время вставить его в окно кода. Если вы набираете макрос, самостоятельно выполните следующие два шага (рис. 2):

  • В верхней части окна кода из левого раскрывающегося списка выберите Workbook. По умолчанию Excel в окне кода выводит начало процедуры Workbook_Open. Вы можете удалить этот фрагмент кода позже.
  • В правом раскрывающемся списке представлены все события уровня книги (в алфавитном порядке). Выберите BeforePrint. Теперь в окне кода заготовка процедуры начинается с Workbook_BeforePrint.

Рис. 2. Заготовка кода для объекта книга (Workbook) и события BeforePrint

Рис. 2. Заготовка кода для объекта книга (Workbook) и события BeforePrint

Процесс аналогичен, если вы хотите создать код обработчика событий на уровне листа Excel. В этом случае в окне проектов, вы должны выбрать не ThisWorkbook, а какой-либо лист, например, Sheet3 (Cash Flow), дважды кликнуть на нем, и выбрать в качестве объекта Worksheet, а в качестве события, например, SelectionChange. Excel автоматически создает заготовку процедуры, начинающуюся с Worksheet_ SelectionChange.

Резюме: создание макроса обработчика событий начните с выбора объекта (книги или листа), а затем введите код не в модуль, а в соответствующий объект – ThisWorkbook или лист Excel.

Rewq

1

26.11.2008, 09:36. Показов 5821. Ответов 2


Студворк — интернет-сервис помощи студентам

Подскажите пожста, как запустить макрос по событию в Excele?, например изменение ячейки, или изменение условий автофильтра.
Заранее благодарен за ответ.

3 / 3 / 0

Регистрация: 03.12.2008

Сообщений: 17

08.12.2008, 10:00

2

Если не мудрствовать лукаво, то есть простая возможность создать обработчик (читай макрос) по обработке событий связанных с рабочим листом или рабочей книгой в целом как объектов. Наиболее близко к вашей задаче — это обработка изменения на листе (в любой ячейке). Для этого откройте редактор VBA. Выполните двойной щелчок в проводнике проекта на нужном вам листе. Далее в редакторе кода в области действия (вверху слева) выберите из списка Worksheet. появится заготовка обработчика Worksheet_SelectionChange (изменение выбора (активной ячейки)). Это Вам не нужно — удалите. В правом списке выберите обработчик Change. В редакторе появится заготовка обработчика Worksheet_Change. Не трогая параметров обработчика пишите в него что Вам нужно. Теперь любое изменение содержания любой ячейки этого листа заставит выполнится Ваш макрос.



0



3 / 3 / 0

Регистрация: 03.12.2008

Сообщений: 17

09.12.2008, 07:11

3

Кстати, если необходимо чтобы действия выполнялись при изменении только определенных ячеек, то можно определить измененную ячейку используя параметр Target обработчика и дальше принимать решение выполнять действие (и какое) или нет.

Target.Column — номер столбца измененной ячейки
Target.Row — номер строки (ряда) измененной ячейки

Можно еще определить ячейку через свойство Range, но это уже на любителя.



0



Событие листа

Worksheet_SelectionChange

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

Заходим в окно VB, нажимая Alt+F11. Слева мы видим названия наших листов. Щёлкаем двойным щелчком по желаемому листу. Вверху имеется два окошка в которых по умолчанию написано General и Declarations.

Выбираем в левом окне Worksheets, а в правом SelectionChange.

После этого появится следующая запись кода:

      Private Sub Worksheet_SelectionChange(ByVal Target As Range)

      End Sub

Такая запись нам и будет говорить о том, что необходимо выполнять макрос, когда на листе произойдёт выделение некоторого диапазона.
И если в этот макрос добавить следующий код:

      Private Sub Worksheet_SelectionChange(ByVal Target As Range)

          Selection.Interior.ColorIndex = 5

      End Sub

то какой бы мы диапазон не выделили на этом листе, он окрасится в синий цвет.

Хочу обратить внимание, что макрос работает только на том листе, который Вы выбрали слева в списке листов.

Рассмотрим ещё один пример, в котором будет выделяться всегда только одна ячейка на листе — активная ячейка (в видеоролике показано как это работает).

      Private Sub Worksheet_SelectionChange(ByVal Target As Range)

          ActiveCell.Select

      End Sub

Необходимо только запомнить одно, — что вы можете вставить на лист только один макрос с таким именем, т.е. макрос создающий событие при выделении ячейки. Если вы хотите чтобы происходило несколько разных событий в зависимости от условий на листе, то это необходимо описывать всё в этом же макросе. Ниже приведён пример как макрос выдаёт различные информационные сообщения в зависимости от положения курсора на листе.

      Private Sub Worksheet_SelectionChange(ByVal Target As Range)

          a = ActiveCell.Column

      If a < 10 Then

          MsgBox «Курсор находится на столбце №» & a & » — это меньше 10.», _

          vbInformation, «Пример»

      Else

          MsgBox «Курсор находится за пределами моего понимания!», _

          vbInformation, «Пример»

      End If

      End Sub

Существует очень много событиев на листе, которые можно интересно использовать. Все я рассматривать подробно не буду, но основные самые интересные поясню

Worksheet_Change

Рассмотрим событие, которое возникает при редактировании ячейки. Т.е. мы внесли какие-то данные в ячейку, вышли из режима редактирования и при этом у нас сразу сработал какой-то макрос.
Делается это следующим образом. Заходим в окно VB, щёлкаем слева по листу, событие которого хотим отслеживать. Открывается окно. В левом верхнем окошке выбираем пункт Worksheet и правом окошке Change.

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

      Private Sub Worksheet_Change(ByVal Target As Range)

      End Sub

Для того чтобы определить какая ячейка у нас притерпела изменение можно воспользоваться следующей записью — для определения столбца и ячейки. Наверное это надо было поместить в этот урок.

      Stolbec = Target.Column

      Stroka = Target.Row

Ну вот, зная координаты теперь мы точно знаем какая ячейка у нас будет обрабатываться. Теперь можно написать макрос, который нам будет сообщать о том, в какой ячейке произошли изменения. Выглядеть это будет, например, так:

      Private Sub Worksheet_Change(ByVal Target As Range)

      Stolbec = Target.Column

      Stroka = Target.Row

      MsgBox «Отредактирована ячейка Cells(» & Stroka & «,» & Stolbec & «)», _

              vbInformation, «Пример»

      End Sub

Рассмотрим такой пример когда, после редактирования ячейки, её текст автоматически закрашивается в синий цвет, а ячейка окрашивается в жёлтый цвет.

      Private Sub Worksheet_Change(ByVal Target As Range)

          Target.Font.ColorIndex = 5 ‘синий

          Target.Interior.ColorIndex = 6 ‘жёлтый

      End Sub

И всё бы ничего, отредактировали ячейку, потом выпполнился какой-то макрос. Но вот беда если записать такой макрос, то мы загрустим:

      Private Sub Worksheet_Change(ByVal Target As Range)

          Target.Cells = «Привет»

      End Sub

А загрустим потому, что мы будем заносить в изменённую ячейку какие-то данные. То-есть мы опять её редактируем. Следовательно, как только макрос заносит данные в ячейку, он снова запускает сам себя. И у нас получается зацикливание. Для того чтобы этого не происходило мы используем дополнительную запись, которая блокирует запуск события в момент выполнения текущего.

      Private Sub Worksheet_Change(ByVal Target As Range)

          Application.EnableEvents = False

              Target.Cells = «Привет»

          Application.EnableEvents = True

      End Sub

Получается, что при выполнении макроса мы отключаем запуск события, затем прописываем в изменённую ячейку данные, затем снова включаем запуск сторонних событий. Вот при такой записи зацикливания не произойдёт. Попробуйте выполнить два выше указанных макроса через F8, и вы поймёте в чём разница этих двух записей, и когда именно неоходимо применять Application.EnableEvents.

Двойной щелчок мыши. BeforeDoubleClick

Иногда охото сделать программу, которая приближается к настоящей, где всякие события происходят от нажатия двойного щелчка мыши. В этом занятии я расскажу, как сделать макрос, который будет реагировать на двойной щелчок ЛКМ.

Что можно сделать при помощи такого макроса? Таблицы, в которых данные можно заносить при помощи двойного щелчка мыши. Например, устанавливать галочки напротив выбранных наименований.

Делается это следующим образом. Заходим в окно VB, щёлкаем слева по необходимому листу. Открывается окно. В левом верхнем окошке выбираем пункт Worksheet, а правом окошке BeforeDoubleClick.

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

      Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)

      End Sub

Если в этот код поместить какое-нибудь информационное сообщение, то при двойном щелчке по ячейке, будет появляться это сообщение.

      Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)

          MsgBox «Вы совершили двойной клик!», vbInformation, «Пример»

      End Sub

Но при такой записи есть один нюанс. После совершения двойного нажатия вы входите в режим редактирования ячейки, что очень неудобно. Для того чтобы этого не происходило необходимо написать команду, кооторая будет запрещать вход в режим редактирования. Макрос будет выглядеть так:

      Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)

      Cancel = True

          MsgBox «Вы совершили двойной клик!», vbInformation, «Пример»

      End Sub

Cancel = True может принимать только два значения True или False и об этом указано в наименовании макроса Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean).

Но такая запись активизирует двойной щелчёк на всём листе, и это конечно хорошо, но иногда возникает потребность задействовать только часть листа, например только столбец А. На этом этапе мы уже начинаем придумывать какие-то условия. И это можно осуществить всё при помощи того же If … End If или Select Case … End Select.

      Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)

          If ActiveCell.Column = 1 Then

              Cancel = True

              MsgBox «Вы совершили двойной клик!», vbInformation, «Пример»

          End If

      End Sub

При такой записи сообщение будет появляться только в том случае, если мы щёлкаем мышкой по столбцу А.

Усложним пример. Сделаем так, как показано в начале урока на левом рисунке. Попробуем Установить галочки, причём не во всём столбце, а в некотором диапазоне, например В2:В8. Ниже приведён макрос, который может это осуществить.

      Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)

      If Not Intersect(Target, Range(«B2:B8»)) Is Nothing Then ‘ищем пересечение в данном диапазоне

      Target.Font.Name = «Marlett» ‘Задаем текст при двойном шелчке и шрифт текста, в котором символ А и есть галочка

      Cancel = True

          If Target = «a» Then ‘Искомый текст

              Target.Interior.ColorIndex = 23 ‘цвет синий

              Target = «»

          Else

              Target = «a»

              Target.Interior.ColorIndex = 6

          End If

      End If

End Sub

Теперь самое время пояснить его составляющие.

If Not … Is Nothing Then — если производится действие в указанном диапазоне, то выполняем условие. Другими словами, если ячейка, по которой произвели двойной щелчок, попадает в диапазон В2:В8, то выполняем макрос дальше после слова Then;

Intersect(Target, Range(«B2:B8»)) — это указывает переменную, которая должна принимать участие в диапазоне В2:В8, т.е. пересекаться в этом диапазоне, в данном случае это изменяемая ячейка;

Target.Font.Name = «Marlett» — устанавливаем имя шрифта в ячейке, который и отвечает за галочку;

If Target = «a» Then … — если в редактируемой ячейке стоит галочка, то убираем её и закрашиваем ячейку в синий цвет. В противном случае устанавливаем галочку и закрашиваем ячейку в жёлтый цвет.

Ту же самую функцию можно осуществить через другую запись:

      Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)

      St = Target.Column

      Sk = Target.Row

      If St = 2 And Sk > 1 And Sk < 9 Then

      Target.Font.Name = «Marlett»

      Cancel = True

          If Target = «a» Then

              Target.Interior.ColorIndex = 23

              Target = «»

          Else

              Target = «a»

              Target.Interior.ColorIndex = 6

          End If

      End If

      End Sub

Тут диапазон задаётся при помощи координат столбца и строки, а также обычных логических операторов.

Вторая табличка, которая показана в начале страницы справа, выполняется по тем же принципам, только можно не указывать стиль шрифта и вместо а, писать Вкл и Выкл.

В видеоматериале показаны примеры работ приведённых макросов, а также продемонстрирована полная запись их написания.

Правая кнопка мыши. BeforeRightClick

Рассмотрим событие, которое возникает при нажатии на правую кнопку мыши. Иногда просто необходимо сделать так, чтобы заблокировалось меню появляющееся при нажатии на правую кнопку мыши. Или охото сделать своё меню. Именно это мы сегодня и изучим.

Делается это следующим образом. Заходим в окно VB, щёлкаем слева по листу, событие которого хотим отслеживать. Открывается окно. В левом верхнем окошке выбираем пункт Worksheet и правом окошке BeforeRightClick.

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

      Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As Boolean)

      End Sub

И если в этот макрос вставить какое-нибудь информационное сообщение, то при нажатии на правую кнопку мыши на заданном листе, нам отобразится оно.

      Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As Boolean)

          MsgBox «Вы нажали на ПКМ», vbInformation, «Пример»

      End Sub

Но при такой записи, после выполнения макроса нам появляется меню. И для того чтобы этого не происходило необходимо добавить следующую запись, которая отвечает за появление меню.

      Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As Boolean)

          Cancel = True

          MsgBox «Вы нажали на ПКМ», vbInformation, «Пример»

      End Sub

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

      Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As Boolean)

          Cancel = True

          a = ActiveCell.Column

          Select Case a

          Case 1

          ActiveCell.Interior.ColorIndex = 3

          Case 2

          ActiveCell.Interior.ColorIndex = 4

          Case 3

          ActiveCell.Interior.ColorIndex = 5

          Case 4

          ActiveCell.Interior.ColorIndex = 6

          Case 5

          ActiveCell.Interior.ColorIndex = 7

          Case Else

          ActiveCell.Interior.ColorIndex = xlNone

          End Select

      End Sub

В данном примере показано, что в зависимости от того куда Вы поставите курсор и нажмёте на правую кнопку мыши, ячейка примет окрас в зависимости от номера столбца. Тут рассмотрены только первые 5 столбцов листа. Всё что дальше 5 столбца, при нажатии на ПКМ будет обесцвечиваться.

Если выполнить вот такую запись:

      Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As Boolean)

          Cancel = True

      End Sub

то правая кнопка мыши просто напросто не будет «работать», то-есть меню не будет появляться.

Добавление своего раздела в меню правой кнопки мыши

В следующем примере показано как добавить свои два раздела в меню (Окрасить ячейку и Обесцветить ячейку). При нажатии на правую кнопку мыши в меню появляется две новых команды.

    Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As Boolean)

        Dim a As Object

        For Each a In Application.CommandBars(«cell»).Controls

            If a.Tag = «brccm» Then a.Delete

        Next a

            With Application.CommandBars(«cell»).Controls.Add(Type:=msoControlButton, _

            before:=1, temporary:=True)

               .Caption = «Окрасить ячейку»

               .OnAction = «cvet1»

               .Tag = «brccm»

            End With

            With Application.CommandBars(«cell»).Controls.Add(Type:=msoControlButton, _

            before:=2, temporary:=True)

               .Caption = «Обесцветить ячейку»

               .OnAction = «cvet0»

               .Tag = «brccm»

            End With

    End Sub

При выборе «Окрасить ячейку», выделенный диапазон заливается синим цветом. При нажатии на «Обесцветить ячейку», выделенный диапазон ячеек обесцвечивается.
Работу данного кода можно посмотреть на «Листе 3» в примере. На видеоролике так же можно посмотреть его работу.

Событие листа
Worksheet_SelectionChange

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

Заходим в окно VB, нажимая Alt+F11. Слева мы видим названия наших листов. Щёлкаем двойным щелчком по желаемому листу. Вверху имеется два окошка в которых по умолчанию написано General иDeclarations.

Выбираем в левом окне Worksheets, а в правом SelectionChange.

После этого появится следующая запись кода:

Private Sub Worksheet_SelectionChange(ByVal Target As Range)

End Sub

Такая запись нам и будет говорить о том, что необходимо выполнять макрос, когда на листе произойдёт выделение некоторого диапазона.
И если в этот макрос добавить следующий код:

Private Sub Worksheet_SelectionChange(ByVal Target As Range)

Selection.Interior.ColorIndex = 5

End Sub

то какой бы мы диапазон не выделили на этом листе, он окрасится в синий цвет.

Хочу обратить внимание, что макрос работает только на том листе, который Вы выбрали слева в списке листов.

Рассмотрим ещё один пример, в котором будет выделяться всегда только одна ячейка на листе — активная ячейка (в видеоролике показано как это работает).

Private Sub Worksheet_SelectionChange(ByVal Target As Range)

ActiveCell.Select

End Sub

Необходимо только запомнить одно, — что вы можете вставить на лист только один макрос с таким именем, т.е. макрос создающий событие при выделении ячейки. Если вы хотите чтобы происходило несколько разных событий в зависимости от условий на листе, то это необходимо описывать всё в этом же макросе. Ниже приведён пример как макрос выдаёт различные информационные сообщения в зависимости от положения курсора на листе.

Private Sub Worksheet_SelectionChange(ByVal Target As Range)

a = ActiveCell.Column

If a

MsgBox «Курсор находится на столбце №» & a & » — это меньше 10.», _

vbInformation, «Пример»

Else

MsgBox «Курсор находится за пределами моего понимания!», _

vbInformation, «Пример»

End If

End Sub

Существует очень много событиев на листе, которые можно интересно использовать. Все я рассматривать подробно не буду, но основные самые интересные поясню.

Событие листа
Worksheet_SelectionChange

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

Заходим в окно VB, нажимая Alt+F11. Слева мы видим названия наших листов. Щёлкаем двойным щелчком по желаемому листу. Вверху имеется два окошка в которых по умолчанию написано General иDeclarations.

Выбираем в левом окне Worksheets, а в правом SelectionChange.

После этого появится следующая запись кода:

Private Sub Worksheet_SelectionChange(ByVal Target As Range)

End Sub

Такая запись нам и будет говорить о том, что необходимо выполнять макрос, когда на листе произойдёт выделение некоторого диапазона.
И если в этот макрос добавить следующий код:

Private Sub Worksheet_SelectionChange(ByVal Target As Range)

Selection.Interior.ColorIndex = 5

End Sub

то какой бы мы диапазон не выделили на этом листе, он окрасится в синий цвет.

Хочу обратить внимание, что макрос работает только на том листе, который Вы выбрали слева в списке листов.

Рассмотрим ещё один пример, в котором будет выделяться всегда только одна ячейка на листе — активная ячейка (в видеоролике показано как это работает).

Private Sub Worksheet_SelectionChange(ByVal Target As Range)

ActiveCell.Select

End Sub

Необходимо только запомнить одно, — что вы можете вставить на лист только один макрос с таким именем, т.е. макрос создающий событие при выделении ячейки. Если вы хотите чтобы происходило несколько разных событий в зависимости от условий на листе, то это необходимо описывать всё в этом же макросе. Ниже приведён пример как макрос выдаёт различные информационные сообщения в зависимости от положения курсора на листе.

Private Sub Worksheet_SelectionChange(ByVal Target As Range)

a = ActiveCell.Column

If a

MsgBox «Курсор находится на столбце №» & a & » — это меньше 10.», _

vbInformation, «Пример»

Else

MsgBox «Курсор находится за пределами моего понимания!», _

vbInformation, «Пример»

End If

End Sub

Существует очень много событиев на листе, которые можно интересно использовать. Все я рассматривать подробно не буду, но основные самые интересные поясню.

Событие листа
Worksheet_Change

Рассмотрим событие, которое возникает при редактировании ячейки. Т.е. мы внесли какие-то данные в ячейку, вышли из режима редактирования и при этом у нас сразу сработал какой-то макрос.
Делается это следующим образом. Заходим в окно VB, щёлкаем слева по листу, событие которого хотим отслеживать. Открывается окно. В левом верхнем окошке выбираем пункт Worksheet и правом окошкеChange.

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

Private Sub Worksheet_Change(ByVal Target As Range)

End Sub

Для того чтобы определить какая ячейка у нас притерпела изменение можно воспользоваться следующей записью — для определения столбца и ячейки. Наверное это надо было поместить в этот урок.

Stolbec = Target.Column

Stroka = Target.Row

Ну вот, зная координаты теперь мы точно знаем какая ячейка у нас будет обрабатываться. Теперь можно написать макрос, который нам будет сообщать о том, в какой ячейке произошли изменения. Выглядеть это будет, например, так:

Private Sub Worksheet_Change(ByVal Target As Range)

Stolbec = Target.Column

Stroka = Target.Row

MsgBox «Отредактирована ячейка Cells(» & Stroka & «,» & Stolbec & «)», _

vbInformation, «Пример»

End Sub

Рассмотрим такой пример когда, после редактирования ячейки, её текст автоматически закрашивается в синий цвет, а ячейка окрашивается в жёлтый цвет.

Private Sub Worksheet_Change(ByVal Target As Range)

Target.Font.ColorIndex = 5 ‘синий

Target.Interior.ColorIndex = 6 ‘жёлтый

End Sub

И всё бы ничего, отредактировали ячейку, потом выпполнился какой-то макрос. Но вот беда если записать такой макрос, то мы загрустим:

Private Sub Worksheet_Change(ByVal Target As Range)

Target.Cells = «Привет»

End Sub

А загрустим потому, что мы будем заносить в изменённую ячейку какие-то данные. То-есть мы опять её редактируем. Следовательно, как только макрос заносит данные в ячейку, он снова запускает сам себя. И у нас получается зацикливание. Для того чтобы этого не происходило используют дополнительную запись, которая блокирует запуск события в момент выполнения текущего.

Private Sub Worksheet_Change(ByVal Target As Range)

Application.EnableEvents = False

Target.Cells = «Привет»

Application.EnableEvents = True

End Sub

Получается, что при выполнении макроса мы отключаем запуск события, затем прописываем в изменённую ячейку данные, затем снова включаем запуск сторонних событий. Вот при такой записи зацикливания не произойдёт. Попробуйте выполнить два выше указанных макроса через F8 и вы поймёте в чём разница этих двух записей, и когда именно неоходимо применять Application.EnableEvents.

Событие листа. Двойной щелчок мыши.
BeforeDoubleClick

Иногда охото сделать программу, которая приближается к настоящей, где всякие события происходят от нажатия двойного щелчка мыши. В этом занятии я расскажу как сделать макрос, который будет реагировать на двойной щелчок ЛКМ.

Что можно сделать при помощи такого макроса? Таблицы, в которых данные можно заносить при помощи двойного щелчка мыши. Например устанавливать галочки напротив выбранных наименований.

 

Делается это следующим образом. Заходим в окно VB, щёлкаем слева по необходимому листу. Открывается окно. В левом верхнем окошке выбираем пункт Worksheet, а правом окошке BeforeDoubleClick.

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

Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)

End Sub

Если в этот код поместить какое-нибудь информационное сообщение, то при двойном щелчке по ячейке, будет появляться это сообщение.

Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)

MsgBox «Вы совершили двойной клик!», vbInformation, «Пример»

End Sub

Но при такой записи есть один нюанс. После совершения двойного нажатия вы входите в режим редактирования ячейки, что очень неудобно. Для того чтобы этого не происходило необходимо написать команду, кооторая будет запрещать вход в режим редактирования. Макрос будет выглядеть так:

Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)

Cancel = True

MsgBox «Вы совершили двойной клик!», vbInformation, «Пример»

End Sub

Cancel = True может принимать только два значения True или False и об этом указано в наименовании макроса Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean).

Но такая запись активизирует двойной щелчёк на всём листе, и это конечно хорошо, но иногда возникает потребность задействовать только часть листа, например только столбец А. На этом этапе мы уже начинаем придумывать какие-то условия. И это можно осуществить всё при помощи того же If … End If или Select Case … End Select.

Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)

If ActiveCell.Column = 1 Then

Cancel = True

MsgBox «Вы совершили двойной клик!», vbInformation, «Пример»

End If

End Sub

При такой записи сообщение будет появляться только в том случае, если мы щёлкаем мышкой по столбцу А.

Усложним пример. Сделаем так, как показано в начале урока на левом рисунке. Попробуем Установить галочки, причём не во всём столбце, а в некотором диапазоне, например В2:В8. Ниже приведён макрос, который может это осуществить.

Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)

If Not Intersect(Target, Range(«B2:B8»)) Is Nothing Then

Target.Font.Name = «Marlett»

Cancel = True

If Target = «a» Then

Target.Interior.ColorIndex = 23

Target = «»

Else

Target = «a»

Target.Interior.ColorIndex = 6

End If

End If

End Sub

Теперь самое время пояснить его составляющие.

If Not … Is Nothing Then — если производится действие в указанном диапазоне, то выполняем условие. Другими словами, если ячейка, по которой произвели двойной щелчок, попадает в диапазон В2:В8, то выполняем макрос дальше после слова Then;

Intersect(Target, Range(«B2:B8»)) — это указывает переменную, которая должна принимать участие в диапазоне В2:В8, т.е. пересекаться в этом диапазоне, в данном случае это изменяемая ячейка;

Target.Font.Name = «Marlett» — устанавливаем имя шрифта в ячейке, который и отвечает за галочку;

If Target = «a» Then … — если в редактируемой ячейке стоит галочка, то убираем её и закрашиваем ячейку в синий цвет. В противном случае устанавливаем галочку и закрашиваем ячейку в жёлтый цвет.

Ту же самую функцию можно осуществить через другую запись:

Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)

St = Target.Column

Sk = Target.Row

If St = 2 And Sk 1 And Sk

Target.Font.Name = «Marlett»

Cancel = True

If Target = «a» Then

Target.Interior.ColorIndex = 23

Target = «»

Else

Target = «a»

Target.Interior.ColorIndex = 6

End If

End If

End Sub

Тут диапазон задаётся при помощи координат столбца и строки, а также обычных логических операторов.

Вторая табличка, которая показана в начале страницы справа, выполняется по тем же принципам, только можно не указывать стиль шрифта и вместо а, писать Вкл и Выкл.

В видеоматериале показаны примеры работ приведённых макросов, а также продемонстрирована полная запись их написания.

Правая кнопка мыши.
BeforeRightClick

Рассмотрим событие, которое возникает при нажатии на правую кнопку мыши. Иногда просто необходимо сделать так, чтобы заблокировалось меню появляющееся при нажатии на правую кнопку мыши. Или охото сделать своё меню. Именно это мы сегодня и изучим.

Делается это следующим образом. Заходим в окно VB, щёлкаем слева по листу, событие которого хотим отслеживать. Открывается окно. В левом верхнем окошке выбираем пункт Worksheet и правом окошкеBeforeRightClick.

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

Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As Boolean)

End Sub

И если в этот макрос вставить какое-нибудь информационное сообщение, то при нажатии на правую кнопку мыши на заданном листе, нам отобразится оно.

Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As Boolean)

MsgBox «Вы нажали на ПКМ», vbInformation, «Пример»

End Sub

Но при такой записи, после выполнения макроса нам появляется меню. И для того чтобы этого не происходило необходимо добавить следующую запись, которая отвечает за появление меню.

Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As Boolean)

Cancel = True

MsgBox «Вы нажали на ПКМ», vbInformation, «Пример»

End Sub

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

Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As Boolean)

Cancel = True

a = ActiveCell.Column

Select Case a

Case 1

ActiveCell.Interior.ColorIndex = 3

Case 2

ActiveCell.Interior.ColorIndex = 4

Case 3

ActiveCell.Interior.ColorIndex = 5

Case 4

ActiveCell.Interior.ColorIndex = 6

Case 5

ActiveCell.Interior.ColorIndex = 7

Case Else

ActiveCell.Interior.ColorIndex = xlNone

End Select

End Sub

В данном примере показано, что в зависимости от того куда Вы поставите курсор и нажмёте на правую кнопку мыши, ячейка примет окрас в зависимости от номера столбца. Тут рассмотрены только первые 5 столбцов листа. Всё что дальше 5 столбца, при нажатии на ПКМ будет обесцвечиваться.

Если выполнить вот такую запись:

Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As Boolean)

Cancel = True

End Sub

то правая кнопка мыши просто напросто не будет «работать», то-есть меню не будет появляться.

Добавление своего раздела в меню правой кнопки мыши

В следующем примере показано как добавить свои два раздела в меню (Окрасить ячейку и Обесцветить ячейку). При нажатии на правую кнопку мыши в меню появляется две новых команды.

Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As Boolean)

Dim a As Object

For Each a In Application.CommandBars(«cell»).Controls

If a.Tag = «brccm» Then a.Delete

Next a

With Application.CommandBars(«cell»).Controls.Add(Type:=msoControlButton, _

before:=1, temporary:=True)

.Caption = «Окрасить ячейку»

.OnAction = «cvet1»

.Tag = «brccm»

End With

With Application.CommandBars(«cell»).Controls.Add(Type:=msoControlButton, _

before:=2, temporary:=True)

.Caption = «Обесцветить ячейку»

.OnAction = «cvet0»

.Tag = «brccm»

End With

End Sub

При выборе «Окрасить ячейку», выделенный диапазон заливается синим цветом. При нажатии на «Обесцветить ячейку», выделенный диапазон ячеек обесцвечивается.
Работу данного кода можно посмотреть на «Листе 3» в примере. На видеоролике так же можно посмотреть его работу.

Создание своего собственного меню.
Как убрать стандартные команды в меню правой кнопки мыши?

А сейчас я покажу другой вариант создания меню — более разумный.
Создадим своё собственное меню, со своими командами, и которое работает только в нашей книге.
Для этого воспользуемся дополнительными событиями для книги — это Workbook_Activate() иWorkbook_Deactivate().

Теперь разберём последовательность создания такого меню. Добавим в книгу новый модуль, на который разместим два макроса — NewMenu и MakroPrivet.

Option Explicit

Sub NewMenu()

Dim Contro As Object

‘Удаление Всех пунктов меню

For Each Contro In CommandBars(«Cell»).Controls

CommandBars(«Cell»).Controls(Contro.Caption).Delete

Next

‘СОздаём новое меню

CommandBars(«Cell»).Controls.Add.Caption = «Новое меню»

With CommandBars(«Cell»).Controls(«Новое меню»)

.OnAction = «MakroPrivet»

.FaceId = 263

End With

End Sub

Sub MakroPrivet() ‘Макрос, который воплняется при нажатии

MsgBox «Привет!», vbExclamation, «Привет»

End Sub

NewMenu — это макрос формирующий новое меню.
For Each… — это цикл, который перебирает все имеющиеся пункты в стандартном меню и удаляет их.
CommandBars(«Cell»).Controls.Add.Caption = «Новое меню» — при помощи этой команды мы создаём новый пункт меню с названием «Новое меню».
With CommandBars(«Cell»).Controls(«Новое меню»)… — Настраиваем параметры кнопки нового меню
.OnAction = «MakroPrivet» — это имя макроса, который сработает при нажатии на меню.
.FaceId = 263 — это «прибамбас» картинка, которая находится левее названия нашего меню «Новое меню».

MakroPrivet — как было указано выше, это макрос, который выполняется при нажатии на новое меню.
MsgBox «Привет!»… — сообщение, которое появляется при выполнении кода нового меню.

Теперь сделаем так, чтобы меню правой кнопки появлялось только при активации нашей книги. Т.е. если мы переключимся на другую книгу, то меню будет стандартное.
Для этого в окне VB щёлкаем слева по пункту «ЭтаКнига». Открывается окно. В левом верхнем окошке выбираем пункт Workbook и правом окошке Activate.

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

Private Sub Workbook_Activate()

End Sub

Вставим в этот макрос ссылку на макрос NewMenu, который находится в созданном модуле.

Private Sub Workbook_Activate()

NewMenu

End Sub

теперь при активации книги будет срабатывать макрос NewMenu, который и будет формировать наше новое меню.

Но тут есть один нюанс. При отткрытии ещё одного Excel-евского документа, не закрывая нашу книгу, в открытом документе будет появляться наше меню, что не желательно. Ведь мы хотим создать меню, которое будет работать только в нашей книге, а не в какой-то другой параллельно открытой. Чтобы такого не происходило добавим в нашу книгу макрос, который будет сбрасывать меню правой кнопки в настройки по умолчанию, при переключении пользователя на другую книгу.
Для этого в окне VB щёлкаем слева по пункту «ЭтаКнига». Открывается окно. В левом верхнем окошке выбираем пункт Workbook и правом окошке Deactivate

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

Private Sub Workbook_Deactivate()

Application.CommandBars(«Cell»).Reset

End Sub

Ну вот, теперь при активации нашей книги будет формироваться новое меню правой кнопки мыши. Но как только книга деактивируется, то-есть мы переключаемся на другой документ, меню сбрасывается.

Событие листа

В этом уроке я рассмотрю сразу три события листа. Они не такие значимые как в предыдущих уроках, но иногда из них можно извлечь хорошую пользу.

Рассмотрим событие, которое возникает при активации листа. Делается это следующим образом. Заходим в окно VB, щёлкаем слева по необходимому листу. Открывается окно. В левом верхнем окошке выбираем пункт Worksheet, а правом окошке Worksheet_Activate.

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

Private Sub Worksheet_Activate()

End Sub

Если в этот код поместить какое-нибудь информационное сообщение, то при активации листа (например перейдти на лист 2, а затем опять на лист 1), нам будет появляться это сообщение (Пример: Лист 1).

Private Sub Worksheet_Activate()

MsgBox «Вы перешли на следующий уровень!», vbInformation, «Пример»

End Sub

Worksheet_Deactivate

Рассмотрим событие, которое возникает при деактивации листа, т.е. когда мы уходим с него. Делается это следующим образом. В левом верхнем окошке выбираем пункт Worksheet, а правом окошкеWorksheet_Deactivate.

После этого появится следующие начало и конец макроса, который и отвечает за уход с листа — деактивацию.

Private Sub Worksheet_Deactivate()

End Sub

Если в этот код поместить какое-нибудь информационное сообщение, то при уходе с активного листа, нам будет появляться сообщение (Пример: Лист 2).

Private Sub Worksheet_Deactivate()

MsgBox «Вы покинули лист!», vbInformation, «Пример»

End Sub

Worksheet_Calculate

Рассмотрим событие, которое возникает при пересчёте листа. Напрмер, у нас на листе есть таблица в которой содержится куча формул. И вам необходимо отследить всяческий пересчёт таблицы. При помощи этого макроса это можно легко выполнить.
Делается это следующим образом. В левом верхнем окошке выбираем пункт Worksheet, а правом окошкеCalculate.

После этого появится следующие начало и конец макроса, который и отслеживает пересчёт листа.

Private Sub Worksheet_Calculate()

End Sub

Если в этот код поместить какое-нибудь информационное сообщение, то при пересчёте формул на листе, нам будет появляться сообщение, например такое (Пример: Лист 3):

Private Sub Worksheet_Calculate()

MsgBox «Пересчёт листа выполнен!» & vbNewLine & _

«Последние изменения внёс » & Application.UserName & «!», _

vbInformation, «Пример»

End Sub

Application.UserName — это имя компьютера.

Событие листа

В этом уроке я рассмотрю оставшиеся события листа. Они вообще редко применяются, как я убедился на собственном опыте.

Worksheet_FollowHyperlink

Рассмотрим событие, которое возникает при переходе по ссылке. Делается это следующим образом. Заходим в окно VB, щёлкаем слева по необходимому листу. Открывается окно. В левом верхнем окошке выбираем пункт Worksheet, а правом окошке FollowHyperlink.

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

Private Sub Worksheet_FollowHyperlink(ByVal Target As Hyperlink)

End Sub

Если в этот код поместить какое-нибудь информационное сообщение, то при переходе по ссылке мы его увидим (Пример: Лист 1).

Private Sub Worksheet_FollowHyperlink(ByVal Target As Hyperlink)

MsgBox «Вы перешли по ссылке на мой сайт!», vbInformation, «Пример»

End Sub

Работа со сводными таблицами

И оставшиеся события — это события, которое происходят при работе со сводными таблицами. Делаются они аналогично предыдущим.

Worksheet_PivotTableAfterValueChange — Это событие возникает после изменения или пересчета ячейки либо диапазона ячеек в сводной таблице (для ячеек, содержащих формулы).

Worksheet_PivotTableBeforeAllocateChanges — Это событие происходит перед применением изменений к сводной таблице.
Событие PivotTableBeforeAllocateChanges происходит непосредственно перед выполнением программой Excel инструкции UPDATE CUBE для применения всех изменений к источнику данных OLAP в сводной таблице, и сразу же после того, как пользователь выберет применение изменений в пользовательском интерфейсе.

Worksheet_PivotTableBeforeCommitChanges — Это событие происходит перед внесением изменений в источник данных OLAP для сводной таблицы.
Событие PivotTableBeforeCommitChanges происходит непосредственно перед выполнением программой Excel инструкции COMMIT TRANSACTION над источником данных OLAP в сводной таблице, и сразу же после того, как пользователь выберет сохранение изменений для всей сводной таблицы.

Worksheet_PivotTableBeforeDiscardChanges — Это событие происходит перед отменой изменений в сводной таблице.
Происходит непосредственно перед тем, как Excel выполняет инструкцию ROLLBACK TRANSACTION в источнике данных OLAP, если транзакция все еще активна и очищает все измененные значения в сводной таблице, после того как пользователь выбрал отмену изменений.

Worksheet_PivotTableChangeSync — Это событие происходит после изменений в сводной таблице.
Событие PivotTableChangeSync происходит во время большинства изменений в сводной таблице, таким образом, чтобы можно было написать код, реагирующий на действия пользователя, таких как очистка, группирование или обновление элементов в сводной таблице.

Worksheet_PivotTableUpdate — Это событие происходит при обновлении отчета сводной таблицы на рабочем листе.

Надёжные расположения

Надежное расположение — это такое место на жестком диске (диск, папка), где Любой файл, можно открывать без проверки средствами центра обеспечения безопасности; кроме того, такие файлы не открываются в режиме защищенного просмотра.
Другими словами, если у Вас есть на диске папка, в которой у Вас хранятся все Ваши разработки, например с именем «Мои макросы» и Вы её «поместили» в надёжное расположение, то какие бы вы файлы с макросами в неё не помещали, у Вас Excel никогда не спросит подтверждение на запуск макросов и т.п.,независимо от того какие настройки безопасности у Вас стоят. В надёжных расположениях макросы всегда включены. Очень удобно помещать программы, которые Вы пишите или проверяете, но которым Вы доверяете, чтобы лишний раз не мучаться и «Включать содержимое».

Делается это следующим образом. Заходим на ленте во вкладку файл/параметры:

В открывшемся окне с левой стороны выбираем Центр управления безопасностью, а справойПараметры центра управления безопасностью

В следующем окне слева выбираем пункт Надёжные расположения.

Для того, чтобы добавить какую-то свою папку в надёжное расположение необходимо нажать на кнопку«Добавить новое расположение». После этого откроется следующее окно

Нажимаем кнопку «Обзор» и выбираем ту папку в которой хотим разрешить все макросы. Обратите особое внимание на галочку «Также доверять всем вложенным папкам», если вы её не поставите, то макросы будут разрешены только в этой корневой папке, а вот если в ней имеются подпапки, то в них опять придётся разрешать и включать макросы в ручную.

Если же Вам не понравились Ваши надёжные расположения, то Вы можете их удалить или изменить.
Все папки, которые у Вас находятся в надёжных расположениях указаны в окне центра управления безопасностью в подпункте надёжные расположения, на рисунке ниже этот список показан в синем квадрате.

Понравилась статья? Поделить с друзьями:
  • Excel макрос по поиску строки
  • Excel макрос по копированию данных в ячейку
  • Excel макрос по возрастанию
  • Excel макрос по алгоритму
  • Excel макрос печать нескольких листов