Добавить модули в excel

Знакомство с понятиями модуль, процедура, форма в VBA Excel. Модули разных типов. Создание пользовательской формы. Встроенные диалоговые окна.

Самый простой способ перейти в редактор VBA — при активном окне программы Excel нажать сочетание клавиш Alt+F11 (здесь используется левая клавиша Alt). Это сочетание работает во всех версиях программы. Если в открывшемся окне нет слева окна проводника «Project-VBAProject», вызовите его через главное меню, выбрав «View» — «Project Explorer». Внутренние окна в редакторе VBA можно перетаскивать и размещать в других местах главного окна.

Модули рабочей книги Excel представляют из себя файлы, предназначенные для создания и хранения программного кода в виде процедур (подпрограмм, функций и пользовательских свойств). Модули бывают нескольких типов: стандартные модули и модули классов (рабочих книг, рабочих листов, диаграмм, пользовательских форм).

Стандартный модуль

Стандартный модуль представляет из себя отдельный файл, встроенный в рабочую книгу Excel и принадлежащий всему проекту VBA (VBAProject) со всеми его объектами (ThisWorkbook, Worksheets, Charts, UserForms). Стандартный модуль можно экспортировать, импортировать или удалить. Его публичные процедуры с уникальными именами доступны во всех остальных модулях рабочей книги без дополнительной адресации. Для публичных процедур с неуникальными именами требуется указание имени модуля, из которого они вызываются.

Создание стандартного модуля:

  1. Откройте рабочую книгу Excel, в которую планируете добавить новый стандартный модуль, или создайте новую книгу в учебных целях.
  2. Откройте редактор VBA сочетанием клавиш Alt+F11.
  3. В окне редактора VBA нажмите на пункт меню «Insert» и в открывшемся списке выберите «Module».

Таким образом, вы создали новый стандартный модуль. В проводнике справа появилась папка «Modules» и в ней файл «Module1» (или «Module» с другим номером, если в вашей книге модули уже были). Такие же модули создаются при записи макросов встроенным рекордером.

Открыть или перейти в окно открытого стандартного модуля можно, дважды кликнув по его имени в проводнике, или открыв на нем правой кнопкой мыши контекстное меню и выбрав «View Code». Кроме того, все уже открытые модули доступны во вкладке «Window» главного меню.

Важное примечание: в Excel 2007-2016 книги с программными модулями сохраняются как «Книга Excel с поддержкой макросов (.xlsm)». Если вы добавили модуль в книгу «Книга Excel (.xlsx)», то, при ее сохранении или закрытии, программа Excel предложит сохранить ее как «Книга Excel с поддержкой макросов (.xlsm)», иначе изменения (созданные или импортированные модули) не сохранятся.

Модули классов

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

Модуль книги

Модуль книги принадлежит только объекту Workbook (Рабочая книга). Открыть или перейти в окно открытого модуля книги можно, дважды кликнув в проводнике на пункте «ЭтаКнига», или открыв на нем правой кнопкой мыши контекстное меню и выбрав «View Code». Кроме того, открытый модуль доступен во вкладке «Window» главного меню.

Модуль листа

Модуль листа принадлежит только объекту Worksheet (Рабочий лист). Открыть модуль листа можно, дважды кликнув в проводнике по его имени, или открыв на нем правой кнопкой мыши контекстное меню и выбрав «View Code». Кроме того, перейти в модуль листа можно из рабочей книги, кликнув правой кнопкой мыши по ярлыку этого листа и выбрав в контекстном меню «Просмотреть код». Открытый модуль доступен во вкладке «Window» главного меню.

Модуль диаграммы

Модуль диаграммы принадлежит только объекту Chart (Диаграмма, вынесенная на отдельный лист рабочей книги). Открыть его можно так же, как и модуль рабочего листа.

Модуль формы

Модуль формы принадлежит только объекту UserForm (Пользовательская форма). Откройте редактор VBA сочетанием клавиш Alt+F11 и нажмите на пункт меню «Insert». В открывшемся списке выберите «UserForm». Таким образом вы создадите новую пользовательскую форму «UserForm1». В проводнике справа появилась папка «Forms» и в ней файл «UserForm1». Перейти в модуль формы можно, дважды кликнув по самой форме, или кликнув по имени формы в проводнике правой кнопкой мыши и выбрав в контекстном меню «View Code». Кроме того, открытый модуль доступен во вкладке «Window» главного меню.

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

Между открытыми окнами форм и модулей можно переходить, нажав в главном меню вкладку «Window», где перечислены все открытые модули и формы (активный объект отмечен галочкой).

Процедура

Процедуры VBA Excel, размещаемые в любом модуле, подразделяются на 3 типа:

  • Sub (подпрограмма),
  • Function (функция),
  • Property (пользовательские свойства).

Главное отличие функции от подпрограммы заключается в том, что функция возвращает результат вычислений, а подпрограмма — нет. Процедура Property предназначена для создания пользовательских свойств и управления ими (используется не часто).

В редакторе VBA Excel перейдите в стандартный модуль и нажмите на пункт меню «Insert». В открывшемся списке выберите «Procedure…». Появится окно с предложением ввести название процедуры, выбрать тип и зону видимости. Создайте пару процедур с разной зоной видимости, пусть одна будет Sub, а другая — Function. В промежутке между началом и концом процедуры пишется программный код.

Private Sub Test()

‘Здесь пишется программный код

End Sub

Зона видимости Private означает, что эту процедуру можно вызвать только из того же модуля, в котором она записана.

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

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

Первая запись:

и вторая запись:

равнозначны.

Форма

Формы в VBA Excel используются для создания диалоговых окон. Процедура создания новой формы описана в параграфе «Модуль формы». Обычно, вместе с новой формой открывается панель «ToolBox» с элементами управления, которые можно добавлять на форму. Если вы закрыли панель с элементами управлениями, отобразить ее снова можно через главное меню, выбрав «View» — «ToolBox».

Стоит добавить, что в VBA Excel есть два встроенных диалоговых окна — MsgBox и InputBox.

MsgBox — это окно для вывода информации с возвратом числового значения кнопки, нажатой пользователем.

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

Хитрости »

3 Август 2013              198851 просмотров


Как добавить код процедуры программно, скопировать модуль

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

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

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

  • Как копировать модуль из одной книги в другую;
  • Как создать новый модуль;
  • Как создать событийную процедуру (изменение данных на листе, открытие книги и т.п.).

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


 

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

  1. Экспорт имеющегося модуля(с процедурами) из книги с кодом в новую книгу. Чаще всего применяется когда кодов для записи в новую книгу довольно много и создавать их все, прописывая в коде, весьма неудобно и громоздко;
  2. Создание нового модуля и запись необходимых кодов в него. Применяется, если необходимо создать относительно короткие процедуры в модуле.

 
1. ЭКСПОРТ ИМЕЮЩЕГОСЯ МОДУЛЯ

Sub Copy_Module()
    Dim objVBProjFrom As Object, objVBProjTo As Object, objVBComp As Object
    Dim sModuleName As String, sFullName As String
    'расширение стандартного модуля
    Const sExt As String = ".bas"
 
    'имя модуля для копирования
    sModuleName = "Module1"
    On Error Resume Next
    'проект книги, из которой копируем модуль
    Set objVBProjFrom = ThisWorkbook.VBProject
    'необходимый компонент
    Set objVBComp = objVBProjFrom.VBComponents(sModuleName)
    'если указанного модуля не существует
    If objVBComp Is Nothing Then
        MsgBox "Модуль с именем '" & sModuleName & "' отсутствует в книге.", vbCritical, "Error"
        Exit Sub
    End If
    'проект книги для добавления модуля
    Set objVBProjTo = ActiveWorkbook.VBProject
    'полный путь для экспорта/импорта модуля. К папке должен быть доступ на запись/чтение
    sFullName = "C:" & sModuleName & sExt
    objVBComp.Export Filename:=sFullName
    objVBProjTo.VBComponents.Import Filename:=sFullName
    'удаляем временный файл для импорта
    Kill sFullName
End Sub

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

 
2. СОЗДАНИЕ НОВОГО МОДУЛЯ

Sub Create_NewModule()
    Dim objVBProj As Object, objVBComp As Object, objCodeMod As Object
    Dim sModuleName As String, sFullName As String
    Dim sProcLines As String
    Dim lLineNum As Long
 
    'добавляем новый стандартный модуль в активную книгу
    Set objVBComp = ActiveWorkbook.VBProject.VBComponents.Add(1)
    'получаем ссылку на коды модуля
    Set objCodeMod = objVBComp.CodeModule
    'узнаем количество строк в модуле
    '(т.к. VBA в зависимости от настроек может добавлять строки деклараций)
    lLineNum = objCodeMod.CountOfLines + 1
    'текст всставляемой процедуры
    sProcLines = "Sub Test()" & vbCrLf & _
        "    MsgBox ""Hello, World""" & vbCrLf & _
        "End Sub"
    'вставляем текст процедуры в тело нового модуля
    objCodeMod.InsertLines lLineNum, sProcLines
End Sub

Данная процедура добавит в активную книгу новый модуль и запишет в него процедуру:

Sub Test()
    MsgBox "Hello, World"
End Sub

 
 
CОЗДАНИЕ СОБЫТИЙНЫХ ПРОЦЕДУР
Помимо стандартных процедур, имеется возможность добавить и событийные(изменения на листе, открытие книги и т.п.). Я приведу примеры создания кода:

  • в Лист1 на изменении данных ячейки в новой книге
  • в ЭтаКнига(ThisWorkbook) на событие открытия книги.

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

 
CОЗДАНИЕ СОБЫТИЙНОЙ ПРОЦЕДУРЫ Worksheet_Change в Лист1

Sub CreateEventProcedure_WorkSheetChange()
    Dim objVBProj As Object, objVBComp As Object, objCodeMod As Object
    Dim lLineNum As Long
    'добавляем новую книгу
    Workbooks.Add
    'получаем ссылку на проект и модуль листа
    Set objVBProj = ActiveWorkbook.VBProject
    Set objVBComp = objVBProj.VBComponents("Лист1")
    Set objCodeMod = objVBComp.CodeModule
    'вставляем код
    With objCodeMod
        lLineNum = .CreateEventProc("Change", "Worksheet")
        lLineNum = lLineNum + 1
        .InsertLines lLineNum, "    MsgBox ""Hello World"""
    End With
End Sub

Важно: для русской версии используется ссылка на Лист1. Для английской как правило Sheet1

Set objVBComp = objVBProj.VBComponents("Sheet1")

 
CОЗДАНИЕ СОБЫТИЙНОЙ ПРОЦЕДУРЫ Workbook_Open

Sub CreateEventProcedure()
    Dim objVBProj As Object, objVBComp As Object, objCodeMod As Object
    Dim lLineNum As Long
    'добавляем новую книгу
    Workbooks.Add
    'получаем ссылку на проект и модуль книги
    Set objVBProj = ActiveWorkbook.VBProject
    Set objVBComp = objVBProj.VBComponents("ЭтаКнига")
    Set objCodeMod = objVBComp.CodeModule
    'вставляем код
    With objCodeMod
        lLineNum = .CreateEventProc("Open", "Workbook")
        lLineNum = lLineNum + 1
        .InsertLines lLineNum, "    MsgBox ""Hello World"""
    End With
End Sub

Важно: для русской версии используется ссылка на ЭтаКнига. Для английской ThisWorkbook

Set objVBComp = objVBProj.VBComponents("ThisWorkbook")

 

 
Функция CopyVBComponent
ПОЗВОЛЯЕТ КОПИРОВАТЬ ЛЮБОЙ КОМПОНЕНТ ИЗ ОДНОЙ КНИГИ В ДРУГУЮ

'---------------------------------------------------------------------------------------
' Procedure : CopyVBComponent
' DateTime  : 02.08.2013 23:10
' Author    : The_Prist(Щербаков Дмитрий)
'             http://www.excel-vba.ru
' Purpose   : Функция копирует компонент из одной книги в другую.
'             Возвращает True, если копирование прошло удачно
'             False - если компонент не удалось скопировать
'
' wbFromFrom             Книга, компонент из VBA-проекта которой необходимо копировать
'
' wbFromTo               Книга, в VBA-проект которой необходимо копировать компонент
'
' sModuleName            Имя модуля, который необходимо копировать.
'
' sModuleToName          Имя модуля, в который необходимо копировать.
'
' bOverwriteExistModule  Если True или 1, то при наличии в конечной книге
'                        компонента с именем sModuleName - он будет удален,
'                        а вместо него импортирован копируемый.
'                        Если False, то при наличии в конечной книге
'                        компонента с именем sModuleName функция вернет False,
'                        а сам компонент не будет скопирован.
'---------------------------------------------------------------------------------------
Function CopyVBComponent(sModuleName As String, ByVal sModuleToName As String, _
    wbFromFrom As Workbook, wbFromTo As Workbook, _
    bOverwriteExistModule As Boolean) As Boolean
 
    Dim objVBProjFrom As Object, objVBProjTo As Object
    Dim objVBComp As Object, objTmpVBComp As Object
    Dim sTmpFolderPath As String, sVBCompName As String, sModuleCode As String
 
    'Проверяем корректность указанных параметров
    On Error Resume Next
    Set objVBProjFrom = wbFromFrom.VBProject
    Set objVBProjTo = wbFromTo.VBProject
 
    'если в книге, из которой копируем нет проекта VBA
    If objVBProjFrom Is Nothing Then
        CopyVBComponent = False: Exit Function
    End If
    'если в книге, из которой копируем для проекта VBA установлен пароль
    If objVBProjFrom.Protection = 1 Then
        CopyVBComponent = False: Exit Function
    End If
 
    'если в книге, в которую копируем нет проекта VBA
    If objVBProjTo Is Nothing Then
        CopyVBComponent = False: Exit Function
    End If
    'если в книге, в которую копируем для проекта VBA установлен пароль
    If objVBProjTo.Protection = 1 Then
        CopyVBComponent = False: Exit Function
    End If
 
    'если не задано имя копируемого модуля
    If Trim(sModuleName) = "" Then
        CopyVBComponent = False: Exit Function
    End If
    'если не задано имя модуля для вставки кода - используем имя копируемого
    If Trim(sModuleName) = "" Then
        sModuleToName = sModuleName
    End If
 
    'проверяем, существует ли в книге из которой копируем заданный модуль
    Set objVBComp = objVBProjFrom.VBComponents(sModuleName)
    'модуля нет - выходим из функции
    If objVBComp Is Nothing Then
        CopyVBComponent = False: Exit Function
    End If
 
    '====================================================
    'полный путь для экспорта/импорта модуля. К папке должен быть доступ на запись/чтение
    sTmpFolderPath = Environ("Temp") & "" & sModuleToName & ".bas" '"
    If bOverwriteExistModule = True Then
        ' Если bOverwriteExistModule = True
        ' удаляем из временной папки и из конечного проекта
        ' модуль с указанным именем
        If Dir(sTmpFolderPath, 6) <> "" Then
            Err.Clear
            Kill sTmpFolderPath
            'удалить не удалось, модуль не сохранен. Выход из функции
            If Err.Number <> 0 Then
                CopyVBComponent = False: Exit Function
            End If
        End If
        'удаляем модуль из конечной книги
        With objVBProjTo.VBComponents
            Set objVBComp = Nothing
            Set objVBComp = .Item(sModuleToName)
            'только если это не модуль листа или книги(их можно только очистить, но не удалять)
            If objVBComp.Type <> 100 Then
                .Remove .Item(sModuleToName)
            End If
        End With
    Else
        Err.Clear
        Set objVBComp = objVBProjTo.VBComponents(sModuleToName)
        If Err.Number <> 0 Then
            'Err.Number 9 - отсутствие указанного компонента, что нам не мешает.
            'Если ошибка другая - выход из функции
            If Err.Number <> 9 Then
                CopyVBComponent = False: Exit Function
            End If
        End If
    End If
 
    '====================================================
    'Экспорт/Импорт компонента во временную директорию
    objVBProjFrom.VBComponents(sModuleName).Export sTmpFolderPath
    '====================================================
    'копируем
    Set objVBComp = Nothing
    Set objVBComp = objVBProjTo.VBComponents(sModuleToName)
    If objVBComp Is Nothing Then
        objVBProjTo.VBComponents.Import sTmpFolderPath
    Else
        'Если компонент - модуль листа или книги -
        'его нельзя удалить. Поэтому удаляем из него весь код
        'и добавляем код из копируемого компонента
        If objVBComp.Type = 100 Then
            'для простоты обращения в коде - делаем ссылку на копируемый модуль
            Set objTmpVBComp = objVBProjFrom.VBComponents(sModuleName)
            'копируем из него код
            With objVBComp.CodeModule
                .DeleteLines 1, .CountOfLines
                sModuleCode = objTmpVBComp.CodeModule.Lines(1, objTmpVBComp.CodeModule.CountOfLines)
                .InsertLines 1, sModuleCode
            End With
        End If
    End If
    'удаляем временный файл компонента
    Kill sTmpFolderPath
    CopyVBComponent = True
End Function

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

Sub CopyComponent()
    Workbooks.Add
    If CopyVBComponent("Module1", "", ThisWorkbook, ActiveWorkbook, True) Then
        MsgBox "Указанный компонент успешно скопирован в новую книгу", vbInformation
    Else
        MsgBox "Компонент не был скопирован", vbInformation
    End If
End Sub

Если необходимо копировать код из обычного модуля в модуль ЭтаКнига:

Sub CopyComponent()
    Workbooks.Add
    If CopyVBComponent("Module1", ActiveWorkbook.CodeName, ThisWorkbook, ActiveWorkbook, True) Then
        MsgBox "Указанный компонент успешно скопирован в новую книгу", vbInformation
    Else
        MsgBox "Компонент не был скопирован", vbInformation
    End If
End Sub

Приведенная функция так же может копировать коды и внутри одной книги: например, перенести код из стандартного модуля в модуль ЭтаКнига или модуль листа:

Sub CopyComponent()
    Workbooks.Add
    If CopyVBComponent("Module1", ThisWorkbook.CodeName, ThisWorkbook, ThisWorkbook, True) Then
        MsgBox "Указанный компонент успешно скопирован в новую книгу", vbInformation
    Else
        MsgBox "Компонент не был скопирован", vbInformation
    End If
End Sub

Думаю теперь у вас не должно возникнуть трудностей с переносом кодов из одной книги в другую.

Также см.:
Удалить макросы из книги
Как удалить макросы в книге?
Как программно снять пароль с VBA проекта?
Копирование модулей и форм из одной книги в другую


Статья помогла? Поделись ссылкой с друзьями!

  Плейлист   Видеоуроки


Поиск по меткам



Access
apple watch
Multex
Power Query и Power BI
VBA управление кодами
Бесплатные надстройки
Дата и время
Записки
ИП
Надстройки
Печать
Политика Конфиденциальности
Почта
Программы
Работа с приложениями
Разработка приложений
Росстат
Тренинги и вебинары
Финансовые
Форматирование
Функции Excel
акции MulTEx
ссылки
статистика

Microsoft Office Professional Edition 2003 Excel 2010 Еще…Меньше

Аннотация

При автоматизации Office продукта из Visual Basic может быть полезно переместить часть кода в модуль Microsoft Visual Basic для приложений (VBA), который может запускаться в пространстве процессов сервера. Это может повысить общую скорость выполнения приложения и решить проблемы, если сервер выполняет действие только при выполнении вызова.

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

Дополнительная информация

В следующем примере показано, как вставить модуль кода в Microsoft Excel, но для Word и PowerPoint можно использовать один и тот же модуль VBA.

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

Начиная с Microsoft Office XP, пользователь должен предоставить доступ к объектной модели VBA, чтобы любой код автоматизации, написанный для управления VBA, работал. Это новая функция безопасности с Office XP. Дополнительные сведения см. в следующей статье базы знаний:

282830 Программный доступ к Office XP VBA Project отклонен

Шаги по построению примера

  1. Сначала создайте новый текстовый файл с именем KbTest.bas (без .txt расширения). Это модуль кода, который мы вставляем в Excel во время запуска.

  2. В текстовом файле добавьте следующие строки кода:

       Attribute VB_Name = "KbTest"

    ' Your Microsoft Visual Basic for Applications macro function takes 1
    ' parameter, the sheet object that you are going to fill.

    Public Sub DoKbTest(oSheetToFill As Object)
    Dim i As Integer, j As Integer
    Dim sMsg As String
    For i = 1 To 100
    For j = 1 To 10

    sMsg = "Cell(" & Str(i) & "," & Str(j) & ")"
    oSheetToFill.Cells(i, j).Value = sMsg
    Next j
    Next i
    End Sub

  3. Сохраните текстовый файл в каталоге C:KbTest.bas, а затем закроем его.

  4. Начните Visual Basic и создайте стандартный проект. По умолчанию создается форма 1.

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

    Например, выберите один из следующих ок.

    • В Microsoft Office Excel 2007 выберите библиотеку 12.0.

    • В Microsoft Office Excel 2003 выберите библиотеку 11.0.

    • В Microsoft Excel 2002 выберите библиотеку 10.0.

    • В Microsoft Excel 2000 выберите библиотеку 9.0.

    • Для Microsoft Excel 97 выберите библиотеку 8.0.

  6. Добавьте кнопку в форму 1 и поместите следующий код в обработник события Click:

       Private Sub Command1_Click()
    Dim oXL As Excel.Application
    Dim oBook As Excel.Workbook
    Dim oSheet As Excel.Worksheet
    Dim i As Integer, j As Integer
    Dim sMsg As String

    ' Create a new instance of Excel and make it visible.
    Set oXL = CreateObject("Excel.Application")
    oXL.Visible = True

    ' Add a new workbook and set a reference to Sheet1.
    Set oBook = oXL.Workbooks.Add
    Set oSheet = oBook.Sheets(1)

    ' Demo standard Automation from out-of-process,
    ' this routine simply fills in values of cells.
    sMsg = "Fill the sheet from out-of-process"
    MsgBox sMsg, vbInformation Or vbMsgBoxSetForeground

    For i = 1 To 100
    For j = 1 To 10
    sMsg = "Cell(" & Str(i) & "," & Str(j) & ")"
    oSheet.Cells(i, j).Value = sMsg
    Next j
    Next i

    ' You're done with the first test, now switch sheets
    ' and run the same routine via an inserted Microsoft Visual Basic
    ' for Applications macro.
    MsgBox "Done.", vbMsgBoxSetForeground
    Set oSheet = oBook.Sheets.Add
    oSheet.Activate

    sMsg = "Fill the sheet from in-process"
    MsgBox sMsg, vbInformation Or vbMsgBoxSetForeground

    ' The Import method lets you add modules to VBA at
    ' run time. Change the file path to match the location
    ' of the text file you created in step 3.
    oXL.VBE.ActiveVBProject.VBComponents.Import "C:KbTest.bas"

    ' Now run the macro, passing oSheet as the first parameter
    oXL.Run "DoKbTest", oSheet

    ' You're done with the second test
    MsgBox "Done.", vbMsgBoxSetForeground

    ' Turn instance of Excel over to end user and release
    ' any outstanding object references.
    oXL.UserControl = True
    Set oSheet = Nothing
    Set oBook = Nothing
    Set oXL = Nothing

    End Sub

  7. Для Excel 2002 и для более поздних версий Excel необходимо включить доступ к проекту VBA. Это можно сделать одним из описанных ниже способов.

    • В Excel 2007 нажмите кнопку Microsoft Office и выберите Excel параметры. Щелкните Центр управления доверием и выберите центр управления Параметры. Нажмите кнопку Параметры, щелкните, чтобы выбрать поле Доверять доступу к объектной модели проекта VBA, а затем нажмите кнопку ОК два раза.

    • В Excel 2003 и более ранних версиях Excel пункт Макрос в меню Инструменты и нажмите кнопку Безопасность. В диалоговом окне Безопасность перейдите на вкладку Надежные источники и выберите Visual Basic Project доступ.

  8. Запустите Visual Basic проекта.

Ссылки

Дополнительные сведения об автоматизации Office от Visual Basic см. на сайте Office поддержки разработки по следующему адресу:

http://support.microsoft.com/ofd

Нужна дополнительная помощь?

На чтение 8 мин. Просмотров 5.1k.

Итог: в этой статье мы сравниваем различные места для хранения макросов, функций и кода VBA в Excel. Мы специально смотрим на модули кода, листовой модуль и модуль ThisWorkbook, чтобы узнать различия между тем, как работает каждый из них. Мы также узнаем, как запускать макросы на основе событий или действий пользователя.

Уровень мастерства: Средний

5 Modules to Store VBA Macro Code in a Project Workbook2

Содержание

  1. Видео: объяснение кодовых модулей VBA
  2. Скачать файл
  3. 5 мест для хранения кода VBA в рабочей книге
  4. Code vs Sheet vs ThisWorkbook Module
  5. Какое лучшее место для хранения моего кода?

Видео: объяснение кодовых модулей VBA

Скачать файл

Загрузите файл Excel.

VBA Code Modules.xlsm (25.3 KB)

5 мест для хранения кода VBA в рабочей книге

На самом деле есть 5 различных модулей, в которых мы можем хранить код VBA в рабочей книге. Каждый из них виден в окне Project Explorer (Ctrl + R) в редакторе VB. Вот краткий обзор каждого типа объекта.

  1. Code Modules — модули кода являются наиболее распространенным местом, где мы храним макросы. Модули находятся в папке «Модули» в рабочей книге.
  2. Sheet Modules — у каждого листа в книге есть объект листа в папке «Объекты Microsoft Excel». Двойной щелчок объекта листа открывает его модуль кода, в который мы можем добавить процедуры обработки событий (макросы). Эти макросы запускаются, когда пользователь выполняет определенное действие на листе.
  3. ThisWorkbook Module — каждая книга содержит один объект ThisWorkbook в нижней части папки объектов Microsoft Excel. Мы можем создавать макросы на основе событий, которые выполняются, когда пользователь выполняет действия в / над книгой.
  4. Userforms — пользовательские формы — это интерактивные формы или окна, в которые мы можем добавлять элементы управления, такие как раскрывающиеся меню, списки, флажки, кнопки и т. Д. Каждая пользовательская форма хранится в папке «Формы» и имеет модуль кода, в который можно помещать макросы, которые будут запускаться. когда форма открыта и / или пользователь взаимодействует с элементами управления в форме.
  5. Class Modules — классы хранятся в папке «Модули классов» и позволяют нам писать макросы для создания объектов, свойств и методов. Классы могут использоваться, когда мы хотим создать пользовательские объекты или коллекции, которые не существуют в Библиотеке объектов.

Когда мы дважды щелкаем или щелкаем правой кнопкой мыши>
Просмотр кода (сочетание клавиш: F7) на любом из этих объектов в окне Project
Explorer, окно кода открывается справа от редактора VB. Окно кода выглядит
одинаково для каждого из объектов. Это просто большой пустой холст, где мы
можем напечатать код.

Double Click a Code Module to View Code Window in VBA Editor

Для этого поста мы собираемся сравнить первые 3 модуля, перечисленные выше.

Code vs Sheet vs ThisWorkbook Module

Это, вероятно, 3 наиболее распространенных места, где мы можем хранить макросы (подпроцедуры) и функции (UDF) в наших проектах VBA.

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

Итак, давайте посмотрим на каждый объект более подробно.

Code Modules

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

Когда у нас есть макрос в модуле кода, мы можем запустить его из окна макроса (вкладка «Разработчик» или «Просмотр вкладки»> «Макросы»). Мы также можем запустить макрос, назначив его кнопке или фигуре. Когда пользователь нажимает кнопку, макрос запускается. Ознакомьтесь с моей статьей и видео о том, как создать Персональную книгу макросов и добавить кнопки на ленту для получения более подробной информации.

Overview of Code Module for VBA Macros in VB Editor1

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

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

Sheet Modules & Event Procedure Macros

Каждый лист в книге имеет объект листа в редакторе VB. Они перечислены в папке «Объекты Microsoft Excel» для каждой открытой книги в окне «Проект».

Объект листа отображает кодовое имя листа и имя вкладки в скобках. Имя вкладки — это имя, отображаемое в книге, которое пользователь может изменить.

Двойной щелчок по объекту листа откроет окно его модуля кода.

Overview of Sheet Module for VBA Macros in VB Editor

Мы можем добавить обычные макросы в объект листа.

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

  1. Выберите «Рабочий лист» в раскрывающемся меню
    «Объекты». Событие выбора будет автоматически добавлено в окно кода. Это
    событие по умолчанию, но мы НЕ должны использовать это событие. Событие SelectionChange
    запускается каждый раз, когда пользователь выбирает ячейку на листе.
  2. Щелкните раскрывающийся список «Процедура»,
    чтобы увидеть список других процедур обработки событий.
  3. Выберите одно из событий из списка, и его код
    процедуры (макроса) будет добавлен в модуль кода листа. Теперь мы можем
    добавить код внутри процедуры, которая будет выполняться, когда пользователь
    выполняет действие.

Add a VBA Event Procedure to the Sheet Code Module in the VB Editor

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

VBA Macro to Select Entire Row and Column On Cell or Range Selection - SelectionChange Event

Модули листа могут содержать несколько процедур обработки событий. Он также может содержать обычные процедуры (макросы) и функции.

На странице справки по объекту MSDN Worksheet есть список всех событий рабочего листа и их справочных статей.

Модуль ThisWorkbook и макросы процедуры события

Каждая рабочая книга содержит один объект с именем
ThisWorkbook. Объект ThisWorkbook хранится в нижней части папки объектов
Microsoft Excel.

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

Overview of ThisWorkbook Module for VBA Macros in VB Editor1

Модуль ThisWorbook очень похож на модули листа. Основное отличие состоит в том, что процедуры обработки событий в модуле ThisWorkbook могут выполняться, когда действия выполняются во всей книге. События модуля листа выполняются только тогда, когда действия выполняются на конкретном листе, в котором находится код.

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

  1. Выберите Workbook из выпадающего меню Object.
  2. Событие Workbook_Open автоматически добавляется
    в модуль. Этот макрос запускается при открытии книги и включении макросов. Вы
    можете удалить код этого события, если вы не хотите его использовать.
  3. Выберите другое событие из выпадающего списка
    Процедуры.
  4. Код для этой процедуры будет добавлен в модуль.
    Добавьте код в процедуру, которая будет выполняться, когда пользователь
    выполнит это действие в книге.

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

На странице справки по объекту MSDN Worksheet есть список всех событий рабочего листа и их справочных статей.

Какое лучшее место для хранения моего кода?

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

Поместите весь код в листовые модули

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

Организовать код в кодовых модулях

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

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

Планируйте свое наследие с умом!

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

Пожалуйста, оставьте комментарий ниже с любыми вопросами. Спасибо!

Даже если вы не умеете программировать, то существует множество мест (книги, сайты, форумы), где можно найти готовый код макросов на VBA для огромного количества типовых задач в Excel. По моему опыту, большинство пользователей рано или поздно собирают свою личную коллекцию макросов для автоматизации рутинных процессов, будь то перевод формул в значения, вывод суммы прописью или суммирования ячеек по цвету. И тут встает проблема — код макросов на Visual Basic нужно где-то хранить, чтобы потом использовать в работе.

Самый простой вариант — сохранять код макросов прямо в рабочем файле, зайдя в редактор Visual Basic с помощью сочетания клавиш Alt+F11 и добавив новый пустой модуль через меню Insert — Module:

Добавление модуля в книгу

При таком способе возникает, однако, несколько неудобств:

  • Если рабочих файлов много, а макрос нужен везде, как например макрос преобразования формул в значения, то и копировать код придется в каждую книгу.
  • Нужно не забыть сохранить файл в формате с поддержкой макросов (xlsm) или в формате двоичной книги (xlsb).
  • При открытии такого файла защита от макросов будет каждый раз выдавать предупреждение, которое нужно подтвердить (ну, или отключить защиту полностью, что может быть не всегда желательно).

Более изящным решением будет создание своей собственной надстройки (Excel Add-in) — отдельного файла особого формата (xlam), содержащего все ваши «любимые» макросы. Плюсы такого подхода:

  • Достаточно будет один раз подключить надстройку в Excel — и можно будет использовать её VBA процедуры и функции в любом файле на этом компьютере. Пересохранять ваши рабочие файлы в xlsm- и xlsb-форматы, таким образом, не потребуется, т.к. исходный код будет храниться не в них, а в файле надстройки.
  • Защита от макросов вас тоже беспокоить уже не будет, т.к. надстройки по определению входят в доверенные источники.
  • Можно сделать отдельную вкладку на ленте Excel с красивыми кнопками для запуска макросов надстройки.
  • Надстройка — это отдельный файл. Его легко переносить с компьютера на компьютер, делиться им с коллегами или даже продавать ;)

Давайте рассмотрим весь процесс создания своей собственной надстройки для Microsoft Excel по шагам.

Шаг 1. Создаем файл надстройки

Открываем Microsoft Excel с пустой книгой и сохраняем ее под любым подходящим именем (например MyExcelAddin) в формате надстройки с помощью команды Файл — Сохранить как или клавиши F12, указав тип файла Надстройка Excel (Excel Add-in):

Сохраняем файл в формате надстройки

Обратите внимание, что стандартно Excel хранит надстройки в папке C:UsersВаше_имяAppDataRoamingMicrosoftAddIns, но, в приниципе, можно указать любую другую удобную вам папку.

Шаг 2. Подключаем созданную надстройку

Теперь созданную нами на прошлом шаге надстройку MyExcelAddin надо подключить к Excel. Для этого идем в меню Файл — Параметры — Надстройки (File — Options — Add-Ins), жмем на кнопку Перейти (Go) в нижней части окна. В открывшемся окне жмем кнопку Обзор (Browse) и указываем положение нашего файла надстройки.

Если вы все сделали правильно, то наша MyExcelAddin должна появиться в списке доступных надстроек:

Список надстроек

Шаг 3. Добавляем в надстройку макросы

Наша надстройка подключена к Excel и успешно работает, но в ней нет пока ни одного макроса. Давайте её наполним. Для этого нужно открыть редактор Visual Basic сочетанием клавиш Alt+F11 или кнопкой Visual Basic на вкладке Разработчик (Developer). Если вкладки Разработчик не видно, то её можно отобразить через Файл — Параметры — Настройка ленты (File — Options — Customize Ribbon).

В левом верхнем углу редактора должно быть окно Project (если его не видно, то включите его через меню View — Project Explorer):

Project Explorer

В этом окне отображаются все открытые книги и запущенные надстройки Microsoft Excel, в том числе и наша VBAProject (MyExcelAddin.xlam) Выделите её мышью и добавьте в неё новый модуль через меню Insert — Module. В этом модуле мы и будем хранить VBA-код наших макросов надстройки.

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

Код макроса

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

Наш макрос FormulasToValues, как легко сообразить, преобразует формулы в значения в выделенном предварительно диапазоне. Иногда такие макросы называют еще процедурами. Чтобы его запустить, нужно выделить ячейки с формулами и открыть специальное диалоговое окно Макросы с вкладки Разработчик (Developer — Macros) или сочетанием клавиш Alt+F8. Обычно в этом окне отображаются доступные макросы из всех открытых книг, но макросы надстроек здесь не видны. Несмотря на это, мы можем ввести имя нашей процедуры в поле Имя макроса (Macro name), а затем нажать кнопку Выполнить (Run) — и наш макрос заработает:

Здесь же можно назначить сочетание клавиш для быстрого запуска макроса — за это отвечает кнопка Параметры (Options) в предыдущем окне Макрос:

Назначаем сочетание клавиш макросу

При назначении клавиш имейте ввиду, что здесь учитывается регистр и раскладка клавиатуры. Поэтому, если вы назначите сочетание, например, Ctrl+Й, то, по факту, вам придется в будущем следить за тем, чтобы у вас была включена именно русская раскладка и жать дополнительно Shift, чтобы получить заглавную букву.

Для удобства можно добавить и кнопку для нашего макроса на панель быстрого доступа в левом верхнем углу окна. Для этого выберите Файл — Параметры — Панель быстрого доступа (File — Options — Customize Quick Access Toolbar), а затем в выпадающем списке в верхней части окна опцию Макросы. После этого наш макрос FormulasToValues можно поместить на панель кнопкой Добавить (Add) и выбрать для него значок кнопкой Изменить (Edit):

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

Шаг 4. Добавляем в надстройку функции

Кроме макросов-процедур, существуют еще и макросы-функции или как их еще называют UDF (User Defined Function = пользовательская функция). Давайте создадим в нашей надстройке отдельный модуль (команда меню Insert — Module) и вставим туда код такой функции:

Пользовательская функция

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

Заметьте, что синтаксис функции отличается от процедуры:

  • используется конструкция Function …. End Function вместо Sub … End Sub
  • после названия функции в скобках указываются её аргументы
  • в теле функции производятся необходимые вычисления и затем результат присваивается переменной с названием функции

Также обратите внимание, что эту функцию не нужно, да и невозможно запустить как предыдущий макрос-процедуру через диалоговое окно Макросы и кнопку Выполнить. Такую макрофункцию нужно использовать как стандартную функцию листа (СУММ, ЕСЛИ, ВПР…), т.е. просто ввести в любую ячейку, указав в качестве аргумента значение суммы с НДС:

Используем созданную UDF

… или ввести через стандартное диалоговое окно вставки функции (кнопка fx в строке формул), выбрав категорию Определенные пользователем (User Defined):

Выбираем пользовательскую функцию

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

  1. Откройте редактор Visual Basic сочетанием клавиш Alt+F11
  2. Выделите надстройку в панели Project и нажмите клавишу F2, чтобы открыть окно Object Browser
  3. Выберите в верхней части окна в выпадающем списке свой проект надстройки
  4. Щелкните по появившейся функции правой кнопкой мыши и выберите команду Properties.
  5. Введите описание функции в окно Description
  6. Сохраните файл надстройки и перезапустите Excel.

Добавляем свое описание для UDF

После перезапуска у функции должно отобразиться описание, которое мы ввели:

Описание функции

Шаг 5. Создаем вкладку надстройки в интерфейсе

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

Информация об отображаемых вкладках по умолчанию содержится внутри книги и должна быть оформлена в виде специального XML-кода. Проще всего писать и редактировать такой код с помощью специальных программ — XML-редакторов. Одна из самых удобных (и бесплатных) — это программа Максима Новикова Ribbon XML Editor.

Алгоритм работы с ней следующий:

  1. Закройте все окна Excel, чтобы не было конфликта файлов, когда мы будем редактировать XML-код надстройки.
  2. Запустите программу Ribbon XML Editor и откройте в ней наш файл MyExcelAddin.xlam
  3. При помощи кнопки tabs в левом верхнем углу добавьте заготовку кода для новой вкладки:

    Добавляем новую вкладку для надстройки

  4. В пустые кавычки нужно вписать id нашей вкладки и группы (любые уникальные идентификаторы), а в label — названия нашей вкладки и группы кнопок на ней:

    Добавляем id и названия

  5. При помощи кнопки button на панели слева добавляем заготовку кода для кнопки и дописываем к ней теги:

    Добавляем кнопку

    — label — это текст на кнопке
    — imageMso — это условное название изображения на кнопке. Я использовал иконку с красной кнопкой, которая имеет название AnimationCustomAddExitDialog. Названия всех доступных кнопок (а их несколько сотен!) можно найти на большом количестве сайтов в интернете, если искать по ключевым словам «imageMso». Для начала можно сходить сюда.
    onAction — это имя процедуры обратного вызова — специального короткого макроса, который будет запускать наш основной макрос FormulasToValues. Назвать эту процедуру можно как угодно. Мы добавим её чуть позже.

  6. Проверить правильность всего сделанного можно с помощью кнопки с зеленой галочкой сверху на панели инструментов. Там же рядом нажмите на кнопку с дискетой для сохранения всех изменений.
  7. Закрываем Ribbon XML Editor
  8. Открываем Excel, заходим в редактор Visual Basic и добавляем к нашему макросу процедуру обратного вызова KillFormulas, чтобы она запускала наш основной макрос замены формул на значения.

    Добавляем процедуру обратного вызова

  9. Сохраняем внесенные изменения и, вернувшись в Excel проверяем результат:

    Созданная вкладка для надстройки

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

Ссылки по теме

  • Что такое макросы, как их использовать в работе, где взять код макросов на Visual Basic.
  • Как сделать заставку при открытии книги в Excel
  • Что такое Личная Книга Макросов и как её использовать

Надстройки Excel – это прекрасная альтернатива создания макросов доступных для использования любых других файлов рабочих книг. Если Вам понравиться создавать свои надстройки и вы войдете во вкус, то это полезное и интересное занятие может еще для вас приносить неплохой доход. Надстройки можно публиковать и продавать в магазине Office Store. В данном примере мы покажем, как создать свою достройку с макросом, написанным на коде самого простого и весьма востребованного языка программирования VBA (Visual Basic for Applications).

Как сделать и установить надстройку в Excel

Чтобы создать, добавить и включить свою надстройку с макросом, следует:

  1. Создайте новую рабочую книгу: «ФАЙЛ»-«Создать»-«Пустая книга». Или нажмите комбинацию горячих клавиш CTRL+N.
  2. Создать файл XLA.

  3. Откройте редактор макросов: «РАЗРАБОТЧИК»-«Код»-«Visual Basic».
  4. Редактор Visual Basic.

  5. Вставьте новый модуль выбрав инструмент: «Insert»-«Module».
  6. Код макроса.

  7. В окне модуля введите свой код макроса. Возьмем простейший пример макроса:
  8. Sub MyMakros()
    Dim polzovatel As String
    Dim data_segodnya As Date
    polzovatel = Application.UserName
    data_segodnya = Now
    MsgBox "Макрос запустил пользователь: " & polzovatel & vbNewLine & data_segodnya
    End Sub

  9. Закройте окно редактора макросов и выберите инструмент: «ФАЙЛ»-«Сохранить как» (CTRL+S). В поле «Имя файла:» введите название для своей тестовой программы. А из выпадающего списка «Тип файла:» выберите значение «Надстройка Excel 97-2003» (*.xla). Автоматически откроеться папка для установки надстроек: C:Documents and SettingsUser_Name AppDataRoamingMicrosoftAddIns. И нажмите на кнопку «Сохранить».
  10. Сохранение совместимости.

  11. Перед тем как установить надстройку в Excel, закройте все открытые рабочие книги снова запустите программу Excel.
  12. Выберите инструмент: «ФАЙЛ»-«Параметры»-«Надстройки». Внизу из выпадающего списка «Управление:» укажите на опцию «Надстройки Excel» и нажмите на кнопку «Перейти».
  13. Параметры Excel.

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

Включить.

Надстройка VBA готова! Теперь во всех открытых рабочих книгах можно будет воспользоваться макросами из вашего *.xla файла. Чтобы убедиться в этом снова откройте редактор Visual Basic (ALT+F11).

Проверка.

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



Как удалить надстройку в Excel

Чтобы отключить вашу надстройку снова откройте окно «ФАЙЛ»-«Параметры»-«Надстройки»-«Перейти» и снимите соответственную галочку в появившемся диалоговом окне. Для полного удаления надстройки придется удалить ее файл *.xla из папки C:Documents and SettingsUser_Name AppDataRoamingMicrosoftAddIns.

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

Внимание! В данном примере мы использовали формат рабочей книги для сохранения файла в формате «Надстройка 97-2003». Это позволяет использовать ее в разных версиях Excel. Например, файлы, сохраненные в формате *.xlam не может быть использована в версии 2007 и старше. Поэтому лучше воспользоваться старым форматом файлов надстройке *.xla.

Читайте также: скачать VBA код программы надстройки сумма прописью с копейками на русском, украинском и английском языке. Или перевод числа в текст средствами Excel.

Примечание. Если вы хотите защитить паролем доступ к своим исходным кодам макросов, тогда выберите инструмент в редакторе Visual Basic: «Tools»-«VBAProject Properties». На закладке «Protection» в поле ввода «Password:» введите пароль для защиты доступу к макросам проекта рабочей книги. В поле ввода «Confirm password:» введите пароль повторено и нажмите на кнопку ОК.

Время на прочтение
7 мин

Количество просмотров 2.1K

В статье описан простой контроллер инициализации модулей VBA Excel.

Все типы модулей VBA MS Excel позволяют создавать код, автоматически выполняемый при загрузке и/или выгрузке модуля.

Однако, для обычных модулей с макросами, VBComponent.Type=001, примера автоматической инициализации автор в сети не обнаружил.

Вступление

Автоматическая инициализация модуля VBA MS Excel производится по факту наличия в модуле подпрограммы с заданным интерфейсом.

Это удобно. Наличие подпрограммы с заданным интерфейсом включает автоматические инициализацию модуля. Удаление из кода модуля подпрограммы — выключает.

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

Private Sub Worksheet_Activate()
    ' your code here
End Sub

Private Sub Worksheet_Deactivate()
    ' your code here
End Sub

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

Вторая — перед тем как, как фокус ввода будет потерян.

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

Таким же образом устроен механизм инициализации классов, книг и форм MS Excel.

Но, иногда возникает потребность автоматической инициализации обычных модулей с макросами, Type=001.

Постановка задачи

  1. Создать автоматический вызов процедур инициализации и завершения для обычных модулей VBA.

  2. Повторить привычный механизм управления инициализацией — наличие в модуле VBA подпрограммы с известным именем.

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

Решение задачи

Синтаксис MS EXCEL VBA, допускает:

  1. размещение в разных модулях подпрограмм с одинаковыми именами и интерфейсом;

  2. косвенный вызов подпрограмм VBA по имени внутри переменной;

  3. уточняющий синтаксис VBA.

Договоримся об именовании подпрограмм инициализации и завершения:

  • moduleInit(ByRef Wb As Workbook) — автоматически вызываемая процедура инициализации;

  • moduleLeave(ByRef Wb As Workbook) — автоматически вызываемая процедура завершения;

  • В любом модуле VBA, подпрограммы инициализации могут отсутствовать или присутствовать, совместно или по одной.

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

Инициализируемый модуль определяется местоположением вызываемой подпрограммы.

Для включения автоматической инициализации добавляем в любое место модуля макросов подпрограмму инициализации:

Option Explicit

' Your VBA module code here

Public Sub moduleInit(ByRef Wb As Workbook)

' The starting code for your VBA module is here

End Sub

Для завершения работы модуля, помещаем соответствующую подпрограмму где-нибудь рядом:

Option Explicit

' Your VBA module code here

Public Sub moduleLeave(ByRef Wb As Workbook)

' The final code for your VBA module is here

End Sub

Public Sub moduleInit(ByRef Wb As Workbook)

' The starting code for your VBA module is here

End Sub

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

Контроллер инициализации

Интерфейс контроллера инициализации содержит две константы и одну подпрограмму.

Public Const vbaMODULE_INIT As String = "moduleInit"
Public Const vbaMODULE_LEAVE As String = "moduleLeave"

Public Sub vbaWbModuleControl( _
			subName As String, _
			Optional printDebugOnly As Boolean = False)

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

Прототипы подпрограмм инициализации завершения:

Public Sub moduleInit(ByRef Wb As Workbook)	' module initialization
Public Sub moduleLeave(ByRef Wb As Workbook)	' module completion

В подпрограмме контроллера инициализации vbaWbModuleControl два параметра:

  • subName — название подпрограммы инициализации или завершения;

  • printDebugOnly — запуск контроллера в режиме отладки.

Каждый раз при вызове, контроллер инициализации «пробегает» по всем модулям проекта VBA MS Excel, создаёт список подпрограмм с именем subName по факту их присутствия, запускает на исполнение передавая, как параметр, объект рабочей книги.

Порядок запуска подпрограмм инициализации определяется порядком создания модулей VBA.

Запуск vbaWbModuleControl с параметром printDebugOnly=True выдаёт на консоль отладки список всех функций инициализации или завершения в порядке вызова, но без вызова.

Для инициализации модулей макросов по событиям получения или потери фокуса ввода электронной таблицы, контроллер инициализации размещается в обработчике событий _Activate().

Private Sub Workbook_Activate()

	vbaWbModuleControl vbaMODULE_INIT

End Sub

Private Sub Workbook_Deactivate()

	vbaWbModuleControl vbaMODULE_LEAVE

End Sub

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

Private Sub Workbook_Open()

 	vbaWbModuleControl vbaMODULE_INIT

End Sub

Private Sub Workbook_BeforeClose(Cancel As Boolean)

  vbaWbModuleControl vbaMODULE_LEAVE

End Sub

Для восстановления инициализации после сбоя во время отладки контроллер запускается в ручном режиме.

Sub ReInitProject()

 	vbaWbModuleControl vbaMODULE_INIT

End Sub

Интеграция контроллера

Контроллер инициализации интегрируется в новый проект простым переносом исходного текста [^C;^V] в модуль макросов VBA Excel.

Контроллер работает без начальной инициализации.

В современных версиях MS Excel дополнительно отмечается чекбокс «Доверять доступ к объектной модели макросов VBA» в разделе «Центр управления безопасности».

Исходный код контроллера инициализации

Attribute VB_Name = "mWbInit"
'***************************************************************************
' Module "mWbInit.bas"
' Controller for automatic initialization of VBA modules
'
' Copyright (c) 2022, "Nikolay E. Garbuz" <nik_garbuz@list.ru>
'
' This program is free software: you can redistribute it and/or modify
' it under the terms of the GNU Lesser General Public License version 3 as
' published by the Free Software Foundation.
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY; without even the implied warranty of
' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
' GNU General Public License for more details.
'
' You should have received a copy of the GNU Lesser General Public License
' along with this program.  If not, see <http://www.gnu.org/licenses/>.
'
' Authored by Nikolay Garbuz <nik_garbuz@list.ru>
' Modified by
'
' TAB Size .EQ 4
'***************************************************************************

Option Explicit
Option Compare Text

' Public Sub moduleInit(ByRef Wb As Workbook)
Public Const vbaMODULE_INIT As String = "moduleInit"

' Public Sub moduleLeave(ByRef Wb As Workbook)
Public Const vbaMODULE_LEAVE As String = "moduleLeave"


' Call vbaWbModuleControl vbaMODULE_INIT    ' for initialization
' Call vbaWbModuleControl vbaMODULE_LEAVE   ' for release

Public _
Sub vbaWbModuleControl( _
                        subName As String, _
                        Optional printDebugOnly As Boolean = False _
)
    vbaWbModuleRun ThisWorkbook, subName, printDebugOnly
End Sub

Public _
Sub vbaWbModuleRun( _
                    ByRef Wb As Workbook, _
                    subName As String, _
                    Optional printDebugOnly As Boolean = False _
)
    Dim i As Integer
    Dim subList() As String
    
    i = vbaSubroutineList(ThisWorkbook, subName, subList)
    
    If i > 0 Then
        If printDebugOnly Then
            Debug.Print Join(subList(), vbCrLf)
        Else
            For i = LBound(subList) To UBound(subList)
                Application.Run subList(i), Wb
            Next i
        End If
    End If
    
    Erase subList
End Sub

Private _
Function vbaSubroutineList( _
                                ByRef Wb As Workbook, _
                                sName As String, _
                                ByRef sList() As String _
) As Integer

    Dim i As Long
    Dim j As Long
    Dim k As Long
    Dim l As Long
    Dim sc As Long
    Dim fc As Long
    Dim sLine As String
    Dim modName As String
    Dim subName As String
    Dim chkName As String
    
    ReDim sList(0)
    
    i = InStr(sName, ".")
    
    If i > 0 Then
        modName = Left(sName, i - 1)
        subName = Mid(sName, i + 1)
    Else
        modName = ""
        subName = sName
    End If
    
    sc = vbaModuleIdx(Wb, modName)
    If sc > 0 Then
        fc = sc
    Else
        sc = 1
        fc = Wb.VBProject.VBComponents.Count
    End If
    
    With Wb.VBProject.VBComponents
        For i = sc To fc
            l = .Item(i).CodeModule.CountOfLines
            For j = 1 To l
                chkName = ""
                Do
                    sLine = .Item(i).CodeModule.Lines(j, 1)
                    If Right(sLine, 1) = "_" Then
                        chkName = chkName & Left(sLine, Len(sLine) - 1)
                        j = j + 1
                    Else
                        chkName = chkName & sLine
                        Exit Do
                    End If
                Loop

                chkName = vbaRemComment(chkName)
                chkName = vbaRemPrefix(chkName)
                chkName = vbaRemIdentLine(chkName)
                chkName = vbaSubroutineName(chkName)
                
                If chkName <> "" Then
                    If subName = "*" Or StrComp(subName, chkName) = 0 Then
                        If UBound(sList) < k Then
                            ReDim Preserve sList(UBound(sList) + 10)
                        End If
                        
                        sList(k) = .Item(i).Name & "." & chkName
                        k = k + 1
                    End If
                End If
            Next j
        Next i
    End With
    
    If k > 0 Then
        ReDim Preserve sList(k - 1)
    End If

    vbaSubroutineList = k

End Function

Private _
Function vbaModuleIdx( _
    							ByRef Wb As Workbook, _
    							sModuleName As String _
) As Integer

    Dim i As Integer
    Dim m As String
    
    vbaModuleIdx = 0
    
    With Wb.VBProject.VBComponents
        For i = 1 To .Count
            m = .Item(i).Name
            If StrComp(sModuleName, m) = 0 Then
                vbaModuleIdx = i
                Exit Function
            End If
        Next i
    End With
    
End Function

Private _
Function vbaSubroutineName(sLn As String) As String
    
    Const maskSubName As String = "sub *(*)*"
    Const maskFuncName As String = "function *(*)*"
    
    Dim p_space As Integer
    Dim p_bra As Integer
    Dim sn As String
    
    sn = ""
    
    If (sLn Like maskSubName) Or (sLn Like maskFuncName) Then
        p_space = InStr(sLn, " ") + 1
        p_bra = InStr(sLn, "(")
        sn = Mid(sLn, p_space, p_bra - p_space)
    End If
    
    vbaSubroutineName = Trim(sn)

End Function

Private _
Function vbaRemComment(sLn As String) As String
    
    Const comSymbols = "REM ,', REM ,: REM "
   
    Dim i As Long
    Dim s As String
    Dim pc As Long
    
    Static csym() As String

    On Error GoTo InitArray

    i = 0
    Do
        s = csym(i)
        
        pc = InStr(sLn, s)
        
        If pc = 1 Then
            sLn = ""
            Exit Do
        Else
            If pc > 1 And i > 0 Then
                sLn = Left(sLn, pc - 1)
                Exit Do
            End If
        End If
        
        i = i + 1
    Loop Until i > UBound(csym)
    
    vbaRemComment = sLn
    
    On Error GoTo 0
    
    Exit Function
    
InitArray:
    csym = Split(comSymbols, ",")
    s = csym(0)
    Resume Next
    
End Function

Private _
Function vbaRemPrefix(sLn As String) As String
    
      Const prefixKeys = "Public ,Private ,Friend ,Static "

    Dim i As Long
    Dim s As String
    Dim ps As Long
    Dim pf As Long
    
    Static pref() As String
    
    On Error GoTo InitArray
    
    i = 0
    Do
        s = pref(i)
        
        ps = InStr(sLn, s)
        
        If ps > 0 Then
            pf = ps + Len(s)
            If ps = 1 Then
                sLn = Mid(sLn, pf)
            Else
                sLn = Left(sLn, ps - 1) & Mid(sLn, pf)
            End If
        End If
        
        i = i + 1
    Loop Until i > UBound(pref)
    
    vbaRemPrefix = sLn
    
    On Error GoTo 0
    
    Exit Function
    
InitArray:
    pref = Split(prefixKeys, ",")
    s = pref(0)
    Resume Next
    
End Function

Private _
Function vbaRemIdentLine(sLn As String) As String
    
    Const lnSymbols = " " & vbTab & vbCr & vbLf

    While sLn <> "" And InStr(lnSymbols, Left(sLn, 1)) > 0
        sLn = Mid(sLn, 2)
    Wend
    
    vbaRemIdentLine = sLn
End Function

Понравилась статья? Поделить с друзьями:
  • Добавить меру в сводную таблицу в excel
  • Добавить меню разработчик в excel 2007
  • Добавить маркеры на график в excel
  • Добавить маркер на диаграмму excel
  • Добавить макрос в excel для всех книг