Рано или поздно у разработчика по различным причинам возникает желание внести какие-либо изменения в созданный им код или добавить в только что созданный кодом файл код VBA. Распространенная ситуация: создали файл обработки, разослали пользователям. Потом доработали код VBA, что-то там добавили, улучшили, а заменять файлы пользователей уже нельзя(они там данные вносят и хранят). Изменять отдельно код VBA каждого файла занятие не из самых привлекательных. Вот здесь-то как раз очень бы пригодилось изменять коды программно.
О том как именно изменять описано в других статьях, например: Как добавить код процедуры программно, скопировать модуль. Эта же статья посвящена тому, что необходимо знать прежде чем начать вносить изменения.
Итак, работать с объектной моделью проекта VBA нам позволяет библиотека Microsoft Visual Basic For Applications Extensibility. Её можно подключить через меню VBE:
Так же эту библиотеку к проекту можно подключить программно(по идентификатору GUID):
ThisWorkbook.VBProject.References.AddFromGuid _
GUID:="{0002E157-0000-0000-C000-000000000046}", Major:=5, Minor:=3 |
Что мне нравится в VBA так это то, что он допускает обращение к методам и свойствам объектов любой имеющейся библиотеки без её подключения в настройках, чем я постоянно и пользуюсь - в своих кодах я не использую текстовые константы из библиотеки Extensibility, заменив их числовыми. Это избавляет от проверки подключенной библиотеки на ПК конечного пользователя. Подключение же библиотеки позволяет использовать Intellisence для интуитивного просмотра свойст и методов объектов. Бывает очень полезно, если не знаете какое-либо свойство или метод или константу. Подключили библиотеку, подсмотрели, применили.
Но куда важнее то, без чего работа с проектом VBA программно невозможна. Я знаю два основных условия:
- Необходимо проставить доверие к проекту VBA:
- Excel 2010-2019: Файл -Параметры -Центр управления безопасностью -Параметры макросов -поставить галочку «Доверять доступ к объектной модели проектов VBA»;
- Excel 2007: Меню -Параметры Excel -Центр управления безопасностью -Параметры макросов -поставить галочку «Доверять доступ к объектной модели проектов VBA»;
- Excel 2003: Сервис –Параметры -вкладка Безопасность -Параметры макросов-Доверять доступ к Visual Basic Project
Причем сделать это необходимо на том ПК, на котором будет выполняться код.
- Изменяемый 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
Как добавить код процедуры программно, скопировать модуль
Управление безопасностью макросов
Как запустить файл с включенными макросами?
Программное изменение значения VBOM через реестр конечно же хорошо, но Excel при закрытии возвращает значение AccessVBOM, засранец. По крайней мере мой 2016-й так делает
Анатолий, так в статье об этом прямо пишется:
А далее приводится код для VB, т.е. отдельное приложение, написанное на Visual Basic и скомпилированное в exe.
Ограничение на программное внесение изменений в проект VBA - Если у книги включен общий (Совместный) доступ.
Есть решение? Иногда надо оперативно менять код не отключая пользователей от книги, а доступа к коду нет.
Алексей, нет решения. В общем доступе проект VBA заблокирован для внесения изменений.