MyTetra Share
Делитесь знаниями!
Что необходимо для внесения изменений в проект VBA(макросы) программно
Время создания: 16.03.2019 23:43
Текстовые метки: Объектная модель, VBOM
Раздел: !Закладки - VBA - VBA управление кодами
Запись: xintrea/mytetra_db_adgaver_new/master/base/1512730827dhs4ub5aqi/text.html на raw.githubusercontent.com

Что необходимо для внесения изменений в проект VBA(макросы) программно

Рано или поздно у разработчика по различным причинам возникает желание внести какие-либо изменения в созданный им код или добавить в только что созданный кодом файл код 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

ThisWorkbook.VBProject.References.AddFromGuid _

                  GUID:="{0002E157-0000-0000-C000-000000000046}", Major:=5, Minor:=3



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

  1. Необходимо проставить доверие к проекту VBA:
    • Excel 2010: Файл -Параметры -Центр управления безопасностью -Параметры макросов -поставить галочку «Доверять доступ к объектной модели проектов 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


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


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


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 я пока не нашел.



'========================================================================================

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



Sub Check2_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



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




Так же в этом разделе:
 
MyTetra Share v.0.59
Яндекс индекс цитирования