Excel VBA 将函数或子程序存储在数组中
Excel VBA store functions or subroutines in an array
在C/C++中,当我有一堆函数(指针)时,我可以将它们存储在数组或向量中,然后按一定顺序一起调用其中一些。可以在 VBA 中做类似的事情吗?
谢谢!
是的,但我不推荐它。 VBA 并不是真正为它而建。您已使用 Excel 标记此问题,因此我将描述如何针对该 Office 产品完成此操作。一般概念适用于大多数 Office 套件,但每个不同的产品对 Application.Run
方法都有不同的语法。
首先,了解动态调用过程的两种不同方法 (sub/function) 以及何时使用它们很重要。
Application.Run
Application.Run
将 运行 子程序或调用存储在标准 *.bas
模块中的函数。
第一个参数是过程的名称(作为字符串传入)。之后,您最多可以传递 30 个参数。 (如果您的程序需要更多,为了代码的热爱而重构。)
关于 Application.Run
还有两件重要的事情需要注意。
- 您不能使用命名参数。参数必须按位置传递。
作为参数传递的对象被转换为值。这意味着如果您尝试 运行 一个需要将默认属性作为参数的对象的过程,您可能会遇到意外问题。
Public Sub Test1()
Application.Run "VBAProject.Module1.SomeFunction"
End Sub
外卖:
使用标准模块时使用 Application.Run。
VBA.Interaction.CallByName
CallByName
执行一个对象的方法,或者sets/gets一个属性一个对象。
它将要调用方法的对象的实例作为参数,以及方法名称(同样是字符串)。
Public Sub Test2()
Dim anObj As SomeObject
Dim result As Boolean
result = CallByName(anObj, "IsValid")
End Sub
外卖:
当你想调用一个class的方法时使用CallByName
。
没有指针。
如您所见,这些方法都不使用实际指针(至少不使用外部指针)。它们接受字符串,然后使用这些字符串找到指向您要执行的过程的指针。因此,您需要知道要执行的过程的 确切 名称。您还需要知道需要使用哪种方法。 CallByName
有额外的负担需要您要调用的对象的实例。无论哪种方式,您都可以将这些名称存储为数组或集合中的字符串。 (哎呀,连字典都说得通。)
因此,您可以将它们硬编码为字符串,或者尝试在 运行 时提取适当的过程名称。为了提取过程名称,您需要通过 Microsoft Visual Basic for Applications Extensibility 库与 VBIDE 本身进行交互。在这里解释所有这些需要太多的代码和工作,但我可以为您指出一些很好的资源。
文章和 SE 问题:
- Chip Pearson's Programming The VBA Editor
- Extending the VBA Extensibility Library
- Ugly workaround to get the vbext_ProcKind is breaking encapsulation
- Automagic testing framework for VBA
- How to get the procedure or function name at runtime
- Import Lines of Code
- Meta Programming in VBA: The VBIDE and Why Documentation is Important
我的一些问答代码:
解决方法是枚举并使用 switch 语句。您可以将枚举类型(长整型)存储在数组中。例如:
Enum FType
func1
func2
func3
End Enum
Sub CallEnumFunc(f As FType, arg As String)
Select Case f
Case func1: MyFunction1(arg)
Case func2: MyFunction2(arg)
Case func3: MyFunction3(arg)
End Select
End Sub
Dim fArray(1) As FType
fArray(0) = func1
fArray(1) = func2
CallEnumFunc fArray(1), "blah"
在C/C++中,当我有一堆函数(指针)时,我可以将它们存储在数组或向量中,然后按一定顺序一起调用其中一些。可以在 VBA 中做类似的事情吗?
谢谢!
是的,但我不推荐它。 VBA 并不是真正为它而建。您已使用 Excel 标记此问题,因此我将描述如何针对该 Office 产品完成此操作。一般概念适用于大多数 Office 套件,但每个不同的产品对 Application.Run
方法都有不同的语法。
首先,了解动态调用过程的两种不同方法 (sub/function) 以及何时使用它们很重要。
Application.Run
Application.Run
将 运行 子程序或调用存储在标准 *.bas
模块中的函数。
第一个参数是过程的名称(作为字符串传入)。之后,您最多可以传递 30 个参数。 (如果您的程序需要更多,为了代码的热爱而重构。)
关于 Application.Run
还有两件重要的事情需要注意。
- 您不能使用命名参数。参数必须按位置传递。
作为参数传递的对象被转换为值。这意味着如果您尝试 运行 一个需要将默认属性作为参数的对象的过程,您可能会遇到意外问题。
Public Sub Test1() Application.Run "VBAProject.Module1.SomeFunction" End Sub
外卖:
使用标准模块时使用 Application.Run。
VBA.Interaction.CallByName
CallByName
执行一个对象的方法,或者sets/gets一个属性一个对象。
它将要调用方法的对象的实例作为参数,以及方法名称(同样是字符串)。
Public Sub Test2()
Dim anObj As SomeObject
Dim result As Boolean
result = CallByName(anObj, "IsValid")
End Sub
外卖:
当你想调用一个class的方法时使用CallByName
。
没有指针。
如您所见,这些方法都不使用实际指针(至少不使用外部指针)。它们接受字符串,然后使用这些字符串找到指向您要执行的过程的指针。因此,您需要知道要执行的过程的 确切 名称。您还需要知道需要使用哪种方法。 CallByName
有额外的负担需要您要调用的对象的实例。无论哪种方式,您都可以将这些名称存储为数组或集合中的字符串。 (哎呀,连字典都说得通。)
因此,您可以将它们硬编码为字符串,或者尝试在 运行 时提取适当的过程名称。为了提取过程名称,您需要通过 Microsoft Visual Basic for Applications Extensibility 库与 VBIDE 本身进行交互。在这里解释所有这些需要太多的代码和工作,但我可以为您指出一些很好的资源。
文章和 SE 问题:
- Chip Pearson's Programming The VBA Editor
- Extending the VBA Extensibility Library
- Ugly workaround to get the vbext_ProcKind is breaking encapsulation
- Automagic testing framework for VBA
- How to get the procedure or function name at runtime
- Import Lines of Code
- Meta Programming in VBA: The VBIDE and Why Documentation is Important
我的一些问答代码:
解决方法是枚举并使用 switch 语句。您可以将枚举类型(长整型)存储在数组中。例如:
Enum FType
func1
func2
func3
End Enum
Sub CallEnumFunc(f As FType, arg As String)
Select Case f
Case func1: MyFunction1(arg)
Case func2: MyFunction2(arg)
Case func3: MyFunction3(arg)
End Select
End Sub
Dim fArray(1) As FType
fArray(0) = func1
fArray(1) = func2
CallEnumFunc fArray(1), "blah"