How can I load a VBA library reference and use it in the same procedure?

天涯浪子 提交于 2019-12-10 10:07:57

问题


I have a VBA script for Excel that adds a small procedure in the active workbook. The final version will add a procedure that auto-saves backup copies of the workbook.

The code requires the Microsoft Visual Basic for Applications Extensibility 5.3 library which I can add manually, but I'm interested in having a single script that can add that library into Excel and then use it.

Here's the code that adds the library reference to Excel. It works.

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

Below is the code that uses this library to add a VBA procedure into the active workbook. It works, but only if the required library reference has first been added to 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

The problem arises when I try to combine the two in a single procedure. Excel throws compile error "User defined type not defined". If I understand correctly, my code uses something called early binding. Excel looks for the library before any code is executed and can't find it.

The answer may be to adapt my code to use late binding so that Excel won't look for that library until after part of the script has executed and the library is available.

Using this post as a guide I modified part of the code to look like this:

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 threw error "Run-time error '429': ActiveX component can't create object".

Any idea how I can either modify this code to utilize late binding, or otherwise load the library reference and run the rest of the code in the same procedure/module?


回答1:


There is a false premise in your original code:

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

This code does not require any references per se. What does require a reference is the variable declaration above:

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

As soon as you have replaced them with As Object you can run the rest of the code as is without adding a reference. Make sure you have Option Explicit at the top to catch any now-undeclared constants you might be using.

However I would advise you consider a different approach, such as moving the code you want to putting into files into an adding that the files can refer to. Automatically adding VBA code to files is a security concern because it is a common way of spreading malware, it might set antiviruses off, and it requires the Trust access to the VBA project object model setting to be set in the user interface (which I would personally never set).



来源:https://stackoverflow.com/questions/39519805/how-can-i-load-a-vba-library-reference-and-use-it-in-the-same-procedure

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!