Любой код VBA должен где-то храниться. Для хранения кодов в VBA используются модули, которые хранятся в книге. Книга может содержать сколько угодно модулей. Каждый модуль в свою очередь может содержать множество процедур(макросов).
Все имеющиеся в книге модули можно посмотреть через редактор VBA (
рис.1
Сам проводник объектов может быть не отображен по умолчанию и тогда его необходимо отобразить: нажать
Модули делятся на пять основных типов:
Вообще, если точнее, то всего-то два типа модуля - обычный и модуль класса, т.к.
Модуль листа ,Модуль книги ,Модуль пользовательской формы иМодуль класса по своей сути являются модулями классов. Но я специально разделил их на несколько типов, т.к. именно такие типы часто употребляются при пояснениях в различных учебниках и на всевозможных форумах и в самих книгах Excel они по виду и некоторому функционалу различны.
Для того, чтобы создать новый
Удалить тоже просто: щелкнуть правой кнопкой мыши на нужном модуле в окне проекта и выбрать
Подробнее про удаление и перемещение модулей описано в конце этой статьи:
на рис.1 Module1
Самый распространенный тип модулей, который используется в большинстве случаев. Именно в них макрорекордер создает записываемые макросы. Все коды и процедуры в таких модулях пишутся вручную, либо копируются из других источников(другого модуля, с этого сайта и т.п.). В основном именно в стандартных модулях содержится большая часть кодов. Они предназначены для хранения основных процедур и Public переменных, которые могут быть доступны впоследствии из любого модуля. Как создать стандартный модуль: в окне проводника объектов щелкаем правой кнопкой мыши -
Многие коды, опубликованные в статьях на сайте необходимо размещать именно в стандартных модулях. Для этого достаточно создать новый стандартный модуль, скопировать текст кода с сайта и вставить.
Лист1 или Sheet1 -
Для каждого листа книги имеется свой отдельный модуль. Попасть в модуль листа проще, чем в остальные модули. Для этого надо просто щелкнуть правой кнопкой мыши по ярлычку листа и выбрать из контекстного меню пункт
Можно и более трудным путем пойти - через редактор VBA:
Размещая код в модуле листа следует помнить, что при копировании или переносе данного листа в другую книгу код так же будет скопирован, т.к. является частью листа. Это и плюс и минус одновременно. Плюс в том, что разместив код в модуле листа можно использовать этот лист в качестве шаблона для распространения со своими кнопками вызова этих кодов(в том числе создания книг кодом) и весь функционал будет доступен. Минус же заключается в некоторых нюансах обращения к ячейкам(подробнее можно ознакомиться в этой статье: Как обратиться к диапазону из VBA) и необходимости размещения ВСЕХ используемых процедур в этом листе, иначе при переносе в другие книги коды могут работать с ошибками.
В модуле листа содержатся встроенные событийные процедуры, каждая из которых отвечает за обработку определенного события на этом листе. Посмотреть их можно так: выбираете объект(на рисунке ниже список в левой части) Worksheet, а в правом списке выбираете событие(в этом списке все процедуры, доступные для выбранного листа):
Процедуры, события для которых уже используются, выделяются жирным шрифтом.
Названия событийных процедур носят достаточно информативные имена и большая их часть не нуждается в тщательной расшифровке. Но самые наиболее части применяемые в любом случае считаю нужным описать:
Activate - возникает при активации самого листа(но не возникает, если произошел переход из одной книги в другую и этот лист является там активным)BeforeDoubleClick - возникает при двойном клике мыши на любой ячейке листа. Важно обращать внимание на передаваемые аргументы: Target и Cancel. Target - ссылка на ячейку, в которой было произведено действие; Cancel - отвечает за отмену режима редактированияBeforeRightClick - возникает при клике правой кнопкой мыши на любой ячейке листа. Важно обращать внимание на передаваемые аргументы:Target иCancel .Target - ссылка на ячейку, в которой было произведено действие;Cancel - отвечает за отмену показа всплывающего менюCalculate - возникает при пересчете функций и формул на листеChange - возникает при изменении значений ячеек на листе. Важно обращать внимание на передаваемый аргументTarget .Target - ссылка на ячейку, которая была изменена. Может отличаться от активной в момент обработки ячейкиDeactivate - возникает при переходе с этого листа на другой лист этой же книгиFollowHyperlink - возникает при переходе по гиперссылке, созданной в этом листеSelectionChange - возникает при изменении адреса выделенной ячейки/области. Важно обращать внимание на передаваемый аргументTarget .Target - ссылка на диапазон ячеек, которые были выделены. Совпадает с выделенными на текущий момент ячейками
Достаточно важный момент: если захотите познакомиться поближе с событийными процедурами, всегда обращайте внимание на переменные, которые передаются в качестве аргументов в процедуру. В большинстве случаев рекомендую использовать именно эти переменные, а не выдумывать всякие возможности для вычисления объекта, который послужил причиной возникновения события. Для события листа
Private Sub Worksheet_Change(ByVal Target As Range) MsgBox "Адрес измененной ячейки: " & Target.Address & _ "; Адрес активной ячейки: " & Selection.Address, vbInformation, "www.excel-vba.ru" End Sub |
После этого запишите в ячейку
Примечание : для всех кодов, приведенных на сайте, достаточно просто открыть необходимый модуль(книги или листа) и вставить предложенный код. Корректировка может понадобиться только в случаях, когда в модуле Листа или Книги вашего файла уже имеется код в необходимой событийной процедуре.
ВАЖНО : могут быть обработаны только те событийные процедуры, которые можно выбрать из списка справа. Если простым языком - каждое событие из этого списка VBE регистрирует "внутри себя", что позволяет в дальнейшем его отслеживать. Если просто написать какое-либо событие "от себя" - то оно никогда не запустится, потому что VBE про него ничего не знает. Например, нам необходимо отследить смену имени листа. Мы создаем событие вроде Worksheet_ChangeName(). Но оно никогда не запустится, т.к. про такое событие VBE ничего не знает, нигде его не регистрирует и не отслеживает.
ЭтаКнига или ThisWorkbook:
В модуль книги можно попасть только через проводник объектов(Project Explorer) редактора VBA - двойной щелчок по
Но там применяются все те же правила - главное не забывать про аргументы, доступные из этих процедур и передаваемые им самим Excel. Например, для события
Private Sub Workbook_BeforeClose(Cancel As Boolean) If Me.Sheets("Отчет").Range("A1").Value = "" Then MsgBox "Необходимо заполнить ячейку A1 на листе 'Отчет'", vbCritical, "www.excel-vba.ru" Cancel = True 'отменяем закрытие книги End If End Sub |
Из кода видно, что на листе
Наиболее часто используемое событие открытия книга - Workbook_Open. Как понятно из названия, событие срабатывает при открытии книги:
Private Sub Workbook_Open() MsgBox "Открыли книгу с кодом", vbInformation, "www.excel-vba.ru" End Sub |
Важно помнить - код срабатывает только если открыта сама книга, в которой этот код записан. Если надо отслеживать открытие любой книги, то надо написать чуть больше кода. Подробнее в статье: Как отследить событие(например выделение ячеек) в любой книге?.
А ниже пример кода для модуля
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean) If SaveAsUI = False Then 'используется простое сохранить MsgBox "Эта книга является шаблоном. Сохранять её можно только через Сохранить как", vbCritical, "www.excel-vba.ru" Cancel = True 'отменяем сохранение книги End If End Sub |
Такое может потребоваться, если книга является шаблоном с полями для заполнения и необходимо предотвратить случайное сохранение исходного документа. Хотя это можно так же сделать без макросов - книгу можно сохранить с правами только на чтение.
И еще один пример - отслеживание активации листов. Может пригодиться, чтобы при активации конкретного листа сделать какое-либо конкретное действие. В коде ниже при активации листа "Лист4" будет показываться сообщение, но действие может быть любым(обновление данных, снятие защиты, установка защиты и т.п.):
Private Sub Workbook_SheetActivate(ByVal Sh As Object) If Sh.Name = "Лист4" Then MsgBox "Вы перешли на Лист4", vbInformation, "www.excel-vba.ru" End If End Sub |
Обращаю внимание, что здесь, как и раньше, мы используем передаваемые процедуре аргументы. В данном случае это объект
UserForm - на рис.1 UserForm1.
Содержатся внутри
ClassModule - на рис.1 Class1.
В большинстве случаев создается специально для отслеживания событий различных объектов. Вряд ли понадобиться начинающим изучение VBA, хотя все зависит от поставленной задачи. Но обычно начинающим изучать это кажется слишком сложным. В любом случае, перед работой с модулями классов лучше научиться хоть чуть-чуть работать с обычными модулями и самостоятельно писать процедуры. Как добавить такой модуль: в окне проводника объектов щелкаем правой кнопкой мыши-Insert-Class Module. Подробнее про модули классов и работу с ними можно почитать в этой статье: Работа с модулями классов. Там описаны все основные принципы и приложен файл примера.
Действия по удалению любого из модулей одинаковы для всех типов. Для этого необходимо перейти в проект VBA нужной книги, выбрать нужный модуль, щелкнуть по нему правой кнопкой мыши и в появившемся меню выбрать Remove (Имя модуля)...(Remove Module1, Remove UserForm1, Remove Class1 и т.п.). После этого появится окно с запросом "Do you want to export (имя модуля) before removing it?". Это означает, что VBA спрашивает: хотите ли Вы сохранить копию кодов модуля перед удалением? Как правило выбирать следует Нет. Но если Вы хотите сохранить текст кодов из удаляемого модуля в отдельном файле, то соглашаетесь, нажав Да. Будет предложено выбрать папку для сохранения модуля и можно даже задать ему отдельное имя.
Иногда нужно модуль из одной книги переместить в другую. Сделать это можно несколькими способами. Самый простой - открыть обе книги, перейти в проводник проектов -найти нужный модуль -захватить его левой кнопкой мыши и не отпуская кнопку перетащить на проект другой книги:
Следует помнить, что так можно перенести и скопировать только стандартный модуль, модуль класса и модуль
Если же надо сохранить стандартный модуль, модуль класса или модуль формы и не переносить сразу же в другую книгу, то можно экспортировать модуль. Для чего это может быть нужно? Как правило, чтобы перенести коды из дома на работу, переслать кому-то на другой ПК(пересылка файла с макросами может быть запрещена политикой безопасности компании) и т.п. Делается это просто: щелкаем на модуле правой кнопки мыши -Export file.
У экспортируемых модулей есть разные расширения, в зависимости от типа модуля. Для стандартных модулей это
Для переноса экспортированного модуля в другую книгу надо просто в проводнике объектов выделить нужный проект правой кнопкой мыши -Import module -выбрать в диалоговом окне нужный модуль.
Экспортировать можно любой модуль, а вот импортировать - нет. Модули листов и книг хоть и экспортируются в отдельные файлы(кстати, с расширением .cls), но импортировать их не получится в том виде, как это предполагается. Они будут импортированы как новые модули класса и только. Поэтому для переноса кодов из модулей листов и книг придется использовать все равно копирование и вставку непосредственно кодов.
И в довершение - можно переносить модули автоматически, кодами VBA: Как добавить код процедуры программно, скопировать модуль
Также см.:
Копирование модулей и форм из одной книги в другую
Что такое макрос и где его искать?
Как удалить макросы в книге?
Юлия, какой LOG и какое отношение он имеет к этой статье?
Дмитрий, добрый день!
ошиблась статьей, вопрос тоже к вам но по статье "Ведение журнала сделанных в книге изменений".
Дмитрий(Админ)
-я Вас люблю))))