添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

发布于: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++动态链接库