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)
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>
您期望的方法.
可以将函数作为参数传递,并准确地获得您所追求的行为,但这有点笨拙。这是通过利用类的默认属性来实现的,
myFunction
包含您的函数的类Public Function sayHi(ByVal s As String) As String
sayHi = "Hi " & s
End Function
Run Code Online (Sandbox Code Playgroud)
您应该在文件中的某处看到定义您的函数的行
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 的回答指定仅获取具有正确接口的子集