7

在 C/C++ 中,当我有一堆函数(指针)时,我可以将它们存储在数组或向量中,并以一定的顺序调用其中的一些。可以在 VBA 中完成类似的操作吗?

谢谢!

4

2 回答 2

15

是的,但我不推荐它。VBA 并不是真正为它而构建的。你已经用 Excel 标记了这个问题,所以我将描述它是如何为该 Office 产品完成的。一般概念适用于大多数 Office 套件,但每个不同的产品都有不同的Application.Run方法语法。

首先,了解动态调用过程(子/函数)的两种不同方法以及何时使用它们非常重要。

应用程序运行

Application.Run将运行子程序或调用存储在标准*.bas模块中的函数。

第一个参数是过程的名称(作为字符串传入)。之后,您最多可以传递 30 个参数。(如果您的程序需要的不止这些,请重构代码以热爱代码。

还有另外两件重要的事情需要注意Application.Run

  1. 您不能使用命名参数。Args 必须按位置传递。
  2. 作为参数传递的对象被转换为值。这意味着如果您尝试运行需要具有默认属性的对象作为参数的过程,您可能会遇到意外问题。

    Public Sub Test1()
        Application.Run "VBAProject.Module1.SomeFunction"
    End Sub
    

外卖:

使用标准模块时使用 Application.Run。

VBA.Interaction.CallByName

CallByName执行对象的方法,或设置/获取对象的属性。

它接受您要调用方法的对象的实例作为参数,以及方法名称(再次作为字符串)。

Public Sub Test2()
    Dim anObj As SomeObject
    Dim result As Boolean

    result = CallByName(anObj, "IsValid")
End Sub

外卖:

CallByName当你想调用一个类的方法时使用。

没有指针。

如您所见,这些方法都没有使用实际的指针(至少不是外部的)。它们接收字符串,然后使用这些字符串来查找指向您要执行的过程的指针。因此,您需要知道要执行的过程的确切名称。您还需要知道需要使用哪种方法。CallByName需要您要调用的对象的实例的额外负担。无论哪种方式,您都可以将这些名称作为字符串存储在数组或集合中。(哎呀,即使是字典也可能有意义。)

因此,您可以将它们硬编码为字符串,或者尝试在运行时提取适当的过程名称。为了提取过程名称,您需要通过Microsoft Visual Basic for Applications Extensibility库与 VBIDE 本身进行交互。在这里解释所有这些需要太多的代码和精力,但我可以为您指出一些好的资源。

文章和 SE 问题:

  1. Chip Pearson 的 VBA 编辑器编程
  2. 扩展 VBA 可扩展性库
  3. 获取 vbext_ProcKind 的丑陋解决方法正在破坏封装
  4. VBA 的自动测试框架
  5. 如何在运行时获取过程或函数名称
  6. 导入代码行
  7. VBA 中的元编程:VBIDE 以及为什么文档很重要

我的一些问答中的代码:

  1. vbeCodeModule
  2. vbe程序
  3. vbe 程序
于 2015-03-05T17:06:49.993 回答
1

一种解决方法是枚举并使用 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"
于 2019-02-22T15:05:28.010 回答