У меня есть сценарий VBA для Excel, который добавляет небольшую процедуру в активную книгу. В окончательной версии будет добавлена процедура, которая автоматически сохраняет резервные копии книги.Как загрузить ссылку на библиотеку VBA и использовать ее в той же процедуре?
Для этого кода требуется библиотека Microsoft Visual Basic for Applications Extensibility 5.3, которую я могу добавить вручную, но я заинтересован в том, чтобы иметь один скрипт, который может добавить эту библиотеку в Excel, а затем использовать ее.
Вот код, который добавляет ссылку на библиотеку в Excel. Оно работает.
On Error Resume Next ' If library already referenced, ignore the error
ThisWorkbook.VBProject.References.AddFromGuid _
GUID:="{0002E157-0000-0000-C000-000000000046}", _
Major:=5, Minor:=3
On Error GoTo 0 ' Resume normal error handling
Ниже приведен код, который использует эту библиотеку для добавления процедуры VBA в активную книгу. Он работает, но только если требуемая справочная библиотека была первой была добавлена в Excel:
Sub AddProcedureToModule()
' This script adds a sample VBA procedure to the active workbook
' Add Library Reference: Microsoft Visual Basic for Applications
' Extensibility 5.3
On Error Resume Next ' If library already referenced, ignore the error
ThisWorkbook.VBProject.References.AddFromGuid _
GUID:="{0002E157-0000-0000-C000-000000000046}", _
Major:=5, Minor:=3
On Error GoTo 0 ' Resume normal error handling
Dim VBProj As VBIDE.VBProject ' requires Ref: MS VB for Apps Extensibility 5.3
Dim VBComp As VBIDE.VBComponent ' requires Ref: MS...5.3
Dim CodeMod As VBIDE.CodeModule ' requires Ref: MS...5.3
Dim LineNum As Long
Const DQUOTE = """" ' one " character
Set VBProj = ActiveWorkbook.VBProject ' requires Ref: MS...5.3
Set VBComp = VBProj.VBComponents("Module1") ' requires Ref: MS...5.3
Set CodeMod = VBComp.CodeModule ' requires Ref: MS...5.3
' Insert code into workbook
With CodeMod
LineNum = .CountOfLines + 1
.InsertLines LineNum, "Public Sub SayHello()"
LineNum = LineNum + 1
.InsertLines LineNum, " MsgBox " & DQUOTE & "Hello World" & DQUOTE
LineNum = LineNum + 1
.InsertLines LineNum, "End Sub"
End With
End Sub
Проблема возникает, когда я пытаюсь объединить два в одной процедуре. Excel выдает ошибку компиляции «Определенный пользователем тип не определен». Если я правильно понимаю, в моем коде используется то, что называется ранним связыванием. Excel ищет библиотеку перед выполнением любого кода и не может ее найти.
Ответ может заключаться в том, чтобы адаптировать мой код для использования позднего связывания, чтобы Excel не искал эту библиотеку до тех пор, пока не выполнит часть скрипта и не будет доступна библиотека.
Использование this post в качестве руководства я изменял часть кода, чтобы выглядеть следующим образом:
Dim VBProj As Object
Dim VBComp As Object
Dim CodeMod As Object
Dim LineNum As Long
Const DQUOTE = """" ' one " character
Set VBProj = CreateObject("ActiveWorkbook.VBProject")
Set VBProj = ActiveWorkbook.VBProject
Set VBComp = CreateObject("VBProj.VBComponents(""Module1"")")
Set CodeMod = CreateObject("VBComp.CodeModule")
Excel бросил ошибку «Ошибка выполнения„429“: ActiveX компонент не может создать объект».
Любая идея, как я могу изменить этот код для использования позднего связывания или иным образом загрузить ссылку на библиотеку и запустить остальную часть кода в той же процедуре/модуле?
AFAIK, это невозможно. Вы не можете опоздать, потому что 'CreateObject' будет работать только с зарегистрированными типами. Вы не можете раннее связывание, потому что это требует перекомпиляции. – Comintern
Вы не используете 'CreateObject''. Вы объявляете все как «Объект», тогда вы сохраняете исходные назначения ('Set VBProj = ActiveWorkbook.VBProject' и т. Д.).Однако вся эта проблема является большой проблемой безопасности и требует установки тика «Доверять доступ к объектной модели проекта VBA». – GSerg
@GSerg, объявляющий в «Объекте» и сохраняя исходные задания, но могу ли вы объяснить проблему безопасности? – ChrisB