2016-09-15 12 views
2

У меня есть сценарий 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 компонент не может создать объект».

Любая идея, как я могу изменить этот код для использования позднего связывания или иным образом загрузить ссылку на библиотеку и запустить остальную часть кода в той же процедуре/модуле?

+1

AFAIK, это невозможно. Вы не можете опоздать, потому что 'CreateObject' будет работать только с зарегистрированными типами. Вы не можете раннее связывание, потому что это требует перекомпиляции. – Comintern

+1

Вы не используете 'CreateObject''. Вы объявляете все как «Объект», тогда вы сохраняете исходные назначения ('Set VBProj = ActiveWorkbook.VBProject' и т. Д.).Однако вся эта проблема является большой проблемой безопасности и требует установки тика «Доверять доступ к объектной модели проекта VBA». – GSerg

+0

@GSerg, объявляющий в «Объекте» и сохраняя исходные задания, но могу ли вы объяснить проблему безопасности? – ChrisB

ответ

3

Существует ложная предпосылка в исходном коде:

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 

Этот код не требует каких-либо ссылок самих по себе. Что требуется ссылка является объявление переменной выше:

Dim VBProj As VBIDE.VBProject 
Dim VBComp As VBIDE.VBComponent 
Dim CodeMod As VBIDE.CodeModule 

Как только вы заменили их As Object вы можете запустить остальную часть кода, без добавления ссылки. Удостоверьтесь, что у вас есть Option Explicit вверху, чтобы поймать любые неизрасходованные константы, которые вы могли бы использовать.

Однако я бы посоветовал вам рассмотреть другой подход, например, перемещение кода, который вы хотите помещать в файлы, в добавление, к которому могут обращаться файлы. Автоматическое добавление кода VBA в файлы является проблемой безопасности, поскольку это распространенный способ распространения вредоносного ПО, поэтому он может отключить антивирусы, и для него необходимо установить параметр Trust access to the VBA project object model в пользовательском интерфейсе (который я лично никогда не установлю).

+0

объявление в «Объекте» и сохранение исходных заданий, но можете ли вы объяснить проблему безопасности? – ChrisB

+1

Из-за ссылки «Этот параметр безопасности затрудняет несанкционированные программы для создания« самовоспроизводящегося »кода, который может повредить системы конечных пользователей». –

 Смежные вопросы

  • Нет связанных вопросов^_^