Продолжая цикл статей про работу с проектом 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 проекта?