excel vba:特殊类型 - 函数作为函数的参数

Rom*_*ass 21 vba arguments functional-programming function excel-vba

VBA中的函数没有特殊类型.我很难看到如何在Excel VBA中添加函数作为函数的参数.

我想要完成的是这样的事情:

function f(g as function, x as string) as string
        f = g(x)
end function
Run Code Online (Sandbox Code Playgroud)

目前,我有一组小函数都在重复自己但只调用一个特定的函数.

dav*_*vid 20

由于VBA的根源在于交互式语言,因此它始终具有执行文本的能力:

function f(g as string, x as string) as string
        f = application.run(g,x)
end function

MyStringA = f("functionA",string1)
MyStringB = f("functionB",string1)
Run Code Online (Sandbox Code Playgroud)

编辑添加:我认为在当前版本的Excel中,应用程序(Excel)只能"运行"您可以在电子表格单元格中显示的内容.这意味着功能,而不是子程序.要执行子例程,请将其包装在函数包装器中:

function functionA(x as string)
    Call MySubA(x)
end function
Run Code Online (Sandbox Code Playgroud)

  • 在Excel VBA 2010中,此语法给出了一个编译错误“ Expected:statement of statement”。参数周围需要括号:f = Application.Run(g,x) (2认同)

Gar*_*ill 19

从你的代码中,函数g接受一个字符串参数并返回一个字符串.我建议你创建一个名为IStringFunction的类模块,作为所有函数都支持的接口的定义,因此:

类模块:IStringFunction

Public Function Evaluate(ByVal s As String) As String
End Function
Run Code Online (Sandbox Code Playgroud)

然后,创建几个实现此接口的示例函数:

类模块:HelloStringFunction

Implements IStringFunction

Public Function IStringFunction_Evaluate(ByVal s As String) As String
    IStringFunction_Evaluate = "hello " & s
End Function
Run Code Online (Sandbox Code Playgroud)

类模块:GoodbyeStringFunction

Implements IStringFunction

Public Function IStringFunction_Evaluate(ByVal s As String) As String
    IStringFunction_Evaluate = "goodbye " & s
End Function
Run Code Online (Sandbox Code Playgroud)

...最后,一些测试代码来执行这些功能:

(标准)模块:测试

Sub Test()

    Dim oHello As New HelloStringFunction
    Dim oGoodbye As New GoodbyeStringFunction

    MsgBox Evaluate(oHello, "gary")
    MsgBox Evaluate(oGoodbye, "gary")

End Sub

Private Function Evaluate(ByVal f As IStringFunction, ByVal arg As String) As String
    Evaluate = f.Evaluate(arg)
End Function
Run Code Online (Sandbox Code Playgroud)

请注意,实现接口的类必须具有<Interface>_<Method>上面示例中命名的方法,而不仅仅是<Method>您期望的方法.

在这里下载简单的演示中间演示

  • 这对他没有太大帮助,因为他仍然必须为每个班级编写单独的评估函数。 (2认同)

Gre*_*edo 5

可以将函数作为参数传递,并准确地获得您所追求的行为,但这有点笨拙。这是通过利用类的默认属性来实现的,

创建一个myFunction包含您的函数的类

Public Function sayHi(ByVal s As String) As String
    sayHi = "Hi " & s
End Function
Run Code Online (Sandbox Code Playgroud)

导出它,并在文本编辑器中打开 .cls 文件

您应该在文件中的某处看到定义您的函数的行

Public Function sayHi(ByVal s As String) As String
Run Code Online (Sandbox Code Playgroud)

在它下面,添加 line Attribute Value.VB_UserMemId = 0,现在它看起来像这样:

Public Function sayHi(ByVal s As String) As String
Attribute Value.VB_UserMemId = 0
    sayHi = "Hi " & s
End Function
Run Code Online (Sandbox Code Playgroud)

您在这里所做的是标记sayHi为类的默认属性。现在您可以单独通过类对象调用该函数class(args),而不是class.function(args)

保存修改后的文件并将其导入到您的 VBA 项目中

测试模块

Sub test()
    Dim parameterFunction As Object         'this is what we'll be passing to our routine
    Set parameterFunction = New myFunction  'create instance of the function object
    MsgBox f(parameterFunction, "Greedo")
End Sub

Function f(ByVal g As Object, ByVal x As String) As String
        f = g(x)
End Function
Run Code Online (Sandbox Code Playgroud)

*注意,这样你可以传递任何函数;但您可以改为ByVal g As IStringFunction根据Gary McGill 的回答指定仅获取具有正确接口的子集