【发布时间】:2016-09-15 20:28:03
【问题描述】:
我有一个 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仅适用于已注册的类型。您不能提前绑定,因为这需要重新编译。 -
您没有使用任何
CreateObjects。您将所有声明为Object,然后保留原始分配(Set VBProj = ActiveWorkbook.VBProject等)。然而,整个事情是一个很大的安全问题,需要设置“信任对 VBA 项目对象模型的访问”勾选。 -
@GSerg 在“对象”处声明并保持原始分配有效,但您能解释一下安全问题吗?
-
顺便说一句,为了清楚起见,在这种情况下,声明对象工作没有引用或
CreateObject。它起作用的唯一原因是您可以使用ActiveWorkbook.VBProject请求一个对象,而不是创建一个。
标签: excel vba class late-binding vbide