VBA调用外部函数(工作簿 COM链接库 C链接库)方法¶
发布于:2019-04-20 | 分类:python/vba/cpp
为便于代码的重复利用和合理组织,VBA支持从当前工作簿调用其他文件中的函数,例如Excel插件*.xlam
、宏文件*.xlsm
、.NET
编译和注册的COM
链接库*.dll
,以及C语言风格的动态链接库*.dll
。本文以计算两个单元格数值和为例,简述跨工作簿函数调用方法。
Excel插件/宏文件¶
可以通过**加载引用**或者**直接调用**两种方式使用Excel插件/宏文件中定义的函数。新建add.xlsm
,重命名VBA工程名称为Test_add
,然后添加一个模块test_add_module
,最后创建如下的add()
函数:
' add.xlsm -> test_add_module -> add()
Function add(ByVal A As Object, ByVal B As Object)
add = A.Value + B.Value
End Function
加载引用¶
Developer
-> Visual Basic
-> Tools
-> References...
-> Browse...
,选择add.xlsm
文件所在位置,即可将其加载到test.xlsm
工程中。test.xlsm
工程中出现References
节点,包含Reference to add.xlsm
子节点。如下图所示,可以通过View
-> Object Browser
查看是否成功加载add()
函数。
接下来即可在VBA代码或者公式编辑器中使用,并且具备智能提示功能。
Debug.Print Add(Range("A1"), Range("B1"))
直接加载¶
Application.Run()
可以跨工作簿使用函数 1:
' :param Macro: 被调用函数的绝对地址,格式:workbook.xlsm!module.function
' :Arg1,...Arg30: 最多支持30个位置参数的输入
' :return: 返回Variant类型,可以转换为目标类型
Application.Run (Macro, Arg1, Arg2, ..., Arg30) As Variant
从之前的引用中删除add.xlsm
,然后测试如下的调用代码:
Sub test()
Dim res As Single
res = Application.Run("'full\path\to\add.xlsm'!test_add_module.add", Range("A1"), Range("B1"))
Debug.Print res
End Sub
也可以直接在公式编辑器中使用:
=add.xlsm!test_add_module.add(A1,B1)
.NET
编译和注册的链接库¶
类似于调用工作簿中的函数,VBA也可以采用 加载引用 和 直接调用 两种方式引用VB.NET
创建的动态链接库类型的COM
组件。首先,参考VB.NET
封装COM组件 2 的方法创建、编译和注册如下类:
' TestDLL.dll -> Test_add
<ComClass(Test_add.ClassId, Test_add.InterfaceId, Test_add.EventsId)> _
Public Class Test_add
#Region "COM GUIDs"
...
#End Region
' A creatable COM class must have a Public Sub New()
' with no parameters, otherwise, the class will not be
' registered in the COM registry and cannot be created
' via CreateObject.
Public Sub New()
MyBase.New()
End Sub
Function add(ByVal A As Object, ByVal B As Object)
Return A.Value + B.Value
End Function
End Class
加载引用¶
同上在Tools
-> References
加载注册后的文件TestDLL.tlb
,然后测试如下调用代码,同理具备智能提示功能。
Sub test()
Dim OBJ As Test_add
Set OBJ = New Test_add
Debug.Print OBJ.Add([A1], [B1])
End Sub
我们也可以通过程序的方式自动加载引用,ThisWorkbook.VBProject.References
,具体参考VBA自动添加前期引用的文章 3。
直接调用¶
如果不想前期显式地引用库文件,可以使用CreateObject("COM_DLL_name.class_name")
创建已注册的类,然后使用其中的函数。参考代码:
Sub test()
Dim OBJ As Object
Set OBJ = CreateObject("TestDLL.Test_add")
Debug.Print OBJ.Add([A1], [B1])
End Sub
C风格动态链接库¶
VBA可以采用如下方式引用C语言风格的动态链接库函数:
' 64 bit dll
Private Declare PtrSafe Function [function_name] Lib ["path_to_dll"] ([parameters_list]) As [type]
' 32 bit dll
Private Declare Function [function_name] Lib ["path_to_dll"] ([parameters_list]) As [type]
具体细节和注意事项参考此前的文章VBA调用c++动态链接库。