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

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

Но для начала, думаю было бы не лишним привести пример кода, который проверяет наличие в книге самого VBA проекта и его доступность для внесения изменений:
ПРОВЕРКА НАЛИЧИЯ ЗАЩИТЫ VBA ПРОЕКТА

'---------------------------------------------------------------------------------------
' Procedure : IsVBProjLock
'             http://www.excel-vba.ru
' Purpose   : Функция проверки наличия защиты у VBA проекта
'             True  - вернет, если проект защищен
'             False - вернет, если проект доступен для внесения изменений
'---------------------------------------------------------------------------------------
Function IsVBProjLock(wbCheck As Workbook) As Boolean
    Dim oVBProj As Object
    Set oVBProj = wbCheck.VBProject
    If Not oVBProj Is Nothing Then
        IsVBProjLock = (oVBProj.Protection <> 0)
    End If
End Function

Вызов функции IsVBProjLock:

Sub Check_VBProjLock()
    MsgBox "VB проект книги " & IIf(IsVBProjLock(ActiveWorkbook), "закрыт", "доступен"), vbInformation
End Sub

Если защита не установлена - функция вернет False и мы можем быть уверены в том, что в данный проект мы сможем внести изменения.

ПРОВЕРКА НАЛИЧИЯ НУЖНОГО МОДУЛЯ

'---------------------------------------------------------------------------------------
' Procedure : IsModuleExists
'             http://www.excel-vba.ru
' Purpose   : Функция проверки наличия нужного модуля в проекте
' Аргументы функции:
'             sModuleName - имя VBA компонента для проверки
'             objVBProj   - если указан, наличие компонента проверяется в указанном VBA проекте
'                           если не указан - в проекте активной книги
' Результат функции:
'             True        - вернет, если модуль существует
'             False       - вернет, если модуль отсутствует
'---------------------------------------------------------------------------------------
Function IsModuleExists(sModuleName As String, Optional ByVal objVBProj As Object = Nothing) As Boolean
    If objVBProj Is Nothing Then
        Set objVBProj = ActiveWorkbook.VBProject
    End If
    On Error Resume Next
    IsModuleExists = CBool(Len(objVBProj.VBComponents(sModuleName).Name))
End Function

Вызов функции IsModuleExists:

Sub Check_VBComponentExists()
    MsgBox "Модуль 'Module1' " & IIf(IsModuleExists("Module2"), "существует", "отсутствует"), vbInformation
End Sub

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


Так же можно проверить не только наличие модуля, но и наличие процедуры или функции по её имени:
ПРОВЕРКА НАЛИЧИЯ ФУНКЦИИ/ПРОЦЕДУРЫ

'---------------------------------------------------------------------------------------
' Procedure : IsFunctionExists
'             http://www.excel-vba.ru
' Purpose   : Функция проверки наличия функции/процедуры в проекте
' Аргументы функции:
'             sProcName   - имя функции/процедуры для проверки
'             objVBProj   - если указан, наличие функции/процедуры проверяется в указанном VBA проекте
'                           если не указан - в проекте активной книги
' Результат функции:
'             Имя модуля, в котором найдена искомая процедура или функция
'---------------------------------------------------------------------------------------
Function IsFunctionExists(sProcName As String, Optional ByVal objVBProj As Object = Nothing)
    If objVBProj Is Nothing Then
        Set objVBProj = ActiveWorkbook.VBProject
    End If
    On Error Resume Next
    Dim lProcLineNum As Long, lProcKind As Long, vMdl
    'цикл по всем модулям проекта(стандартные, классы, формы, листы, книги)
    For Each vMdl In objVBProj.VBComponents
        'ProcStartLine требует в обязательном порядке указания типа процедуры
        'Всего 4 типа:
        '   vbext_pk_Proc  = 0 (Sub or Function procedure)
        '   vbext_pk_Let   = 1 (Property Let procedure)
        '   vbext_pk_Set   = 2 (Property Set procedure)
        '   vbext_pk_Get   = 3 (Property Get procedure)
        For lProcKind = 0 To 3
            'ProcStartLine - встроенная функция
            ' ищет в указанном модуле(vMdl) номер строки с именем заданной процедуры
            lProcLineNum = vMdl.CodeModule.ProcStartLine(sProcName, lProcKind)
            'если lProcLineNum не равно 0 - процедура есть в модуле
            If lProcLineNum > 0 Then
                IsFunctionExists = vMdl.Name
                Exit Function
            End If
        Next
    Next
End Function

Вызов функции IsPocedureExists:

Sub IsPocedureExists()
    Dim sFunctionName As String, sRes As String
    'имя искомой процедуры
    sFunctionName = "MessageFrom_Excel_vba_ru"
    'вызов функции для поиска
    sRes = IsFunctionExists(sFunctionName)
    If sRes <> "" Then
        MsgBox "Функция '" & sFunctionName & "' найдена в модуле: " & sRes, vbInformation
    Else
        MsgBox "Функция '" & sFunctionName & "' отсутствует", vbInformation
    End If
End Sub

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

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

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