Рано или поздно у разработчика по различным причинам возникает желание внести какие-либо изменения в созданный им код или добавить в только что созданный кодом файл код VBA. Распространенная ситуация: создали файл обработки, разослали пользователям. Потом доработали код VBA, что-то там добавили, улучшили, а заменять файлы пользователей уже нельзя(они там данные вносят и хранят). Изменять отдельно код VBA каждого файла занятие не из самых привлекательных. Вот здесь-то как раз очень бы пригодилось изменять коды программно.
О том как именно изменять описано в других статьях, например: Как добавить код процедуры программно, скопировать модуль. Эта же статья посвящена тому, что необходимо знать прежде чем начать вносить изменения.

Итак, работать с объектной моделью проекта VBA нам позволяет библиотека Microsoft Visual Basic For Applications Extensibility. Её можно подключить через меню VBE:

Tools-References-Microsoft Visual Basic For Applications Extensibility 5.X (номер может быть другим)

Так же эту библиотеку к проекту можно подключить программно(по идентификатору GUID):

ThisWorkbook.VBProject.References.AddFromGuid _
                  GUID:="{0002E157-0000-0000-C000-000000000046}", Major:=5, Minor:=3

Что мне нравится в VBA так это то, что он допускает обращение к методам и свойствам объектов любой имеющейся библиотеки без её подключения в настройках, чем я постоянно и пользуюсь - в своих кодах я не использую текстовые константы из библиотеки Extensibility, заменив их числовыми. Это избавляет от проверки подключенной библиотеки на ПК конечного пользователя. Подключение же библиотеки позволяет использовать Intellisence для интуитивного просмотра свойст и методов объектов. Бывает очень полезно, если не знаете какое-либо свойство или метод или константу. Подключили библиотеку, подсмотрели, применили.
Но куда важнее то, без чего работа с проектом VBA программно невозможна. Я знаю два основных условия:

  1. Необходимо проставить доверие к проекту VBA:
    • Excel 2010-2019: Файл -Параметры -Центр управления безопасностью -Параметры макросов -поставить галочку «Доверять доступ к объектной модели проектов VBA»;
    • Excel 2007: Меню -Параметры Excel -Центр управления безопасностью -Параметры макросов -поставить галочку «Доверять доступ к объектной модели проектов VBA»;
    • Excel 2003: СервисПараметры -вкладка Безопасность -Параметры макросов-Доверять доступ к Visual Basic Project
    • Причем сделать это необходимо на том ПК, на котором будет выполняться код.

  2. Изменяемый VBA-проект не должен быть защищен.

Исключить первое условие программно нельзя. Точнее через VBA не получится изменить данный параметр, т.к. это будет происходить в любом случае при запущенном Excel, а при изменении данного параметра программно необходим перезапуск приложения. Да и изменить параметр возможно лишь через реестр, а не у всех пользователей может быть доступ не только к записи, но и даже к чтению реестра Windows. Зато можно проверить разрешен ли доступ к проектной модели VBA и если запрещен, то уведомить пользователя в необходимости это сделать и приложить инструкции по необходимым действиям.
Можно использовать такой код для проверки:

Sub Check_VBOM()
    Dim oVBProj As Object
    On Error Resume Next
    Set oVBProj = ActiveWorkbook.VBProject
    If Not oVBProj Is Nothing Then
        MsgBox "Доступ к проектной модели VBA разрешен", vbInformation
    Else
        MsgBox "Доступ к проектной модели VBA запрещен", vbInformation
    End If
End Sub

Главное его достоинство в том, что он не требует наличия каких-либо прав доступа к реестру.
А кодом ниже можно проверить доступ к объектной модели VBA проекта через реестр Windows, что означает необходимость наличия у пользователя прав доступа как минимум для чтения реестра:

Sub Change_VBOM()
    Dim objShell As Object, sExVersion As String, lLevel As Long
 
    'Определяем версию Excel и в зависимости от этого определяем ветку реестра
    sExVersion = Application.Version
 
    Set objShell = CreateObject("WScript.Shell")
    lLevel = objShell.RegRead("HKEY_CURRENT_USER\Software\Microsoft\Office\" & sExVersion & "\Excel\Security\AccessVBOM")
    'Проверяем доступ к объектной модели VBA
    If lLevel = 0 Then
        MsgBox "Доступ к проектной модели VBA запрещен", vbInformation
    Else
        MsgBox "Доступ к проектной модели VBA разрешен", vbInformation
    End If
    Set objShell = Nothing
End Sub

Если вдруг кому-то захочется поэкспериментировать, то вот код для VB, который меняет доступ программно:

Sub Change_VBOM()
    Dim objExcelApp As Object, objShell As Object, sExVersion As String, lLevel As Long
 
    'Определяем версию Excel и в зависимости от этого определяем ветку реестра
    Set objExcelApp = CreateObject("Excel.Application")
    sExVersion = objExcelApp.Version: objExcelApp.Quit
 
    Set objShell = CreateObject("WScript.Shell")
    lLevel = objShell.RegRead("HKEY_CURRENT_USER\Software\Microsoft\Office\" & sExVersion & "\Excel\Security\AccessVBOM")
    'Разрешаем доступ к объектной модели VBA
    'AccessVBOM - 0 - запрещен доступ; 1 - разрешен
    If lLevel = 0 Then
        objShell.RegWrite _
                "HKEY_CURRENT_USER\Software\Microsoft\Office\" & _
                sExVersion & "\Excel\Security\AccessVBOM", 1, "REG_DWORD"
    End If
    Set objExcelApp = Nothing: Set objShell = Nothing
End Sub

Зато снять пароль с проекта VBA можно средствами самого VBA. Об этом я рассказывал в статье Как программно снять пароль с VBA проекта?
Других ограничений на программное внесение изменений в проект VBA я пока не нашел.

Также см.:
Ошибка - Cant find project or library
Как добавить код процедуры программно, скопировать модуль
Управление безопасностью макросов
Как запустить файл с включенными макросами?

Loading

4 комментария

  1. Программное изменение значения VBOM через реестр конечно же хорошо, но Excel при закрытии возвращает значение AccessVBOM, засранец. По крайней мере мой 2016-й так делает

    1. Анатолий, так в статье об этом прямо пишется:

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

      А далее приводится код для VB, т.е. отдельное приложение, написанное на Visual Basic и скомпилированное в exe.

  2. Ограничение на программное внесение изменений в проект VBA - Если у книги включен общий (Совместный) доступ.
    Есть решение? Иногда надо оперативно менять код не отключая пользователей от книги, а доступа к коду нет.

Добавить комментарий

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.