VBA中是否可以使用嵌套函数?

VBA中是否可以使用嵌套函数?,vba,parameter-passing,nested-function,inline-functions,Vba,Parameter Passing,Nested Function,Inline Functions,我试图通过从私有范围内的函数中剥离参数来清理代码,如下所示: Function complicatedFunction(x as Double, param1 as Double, param2 as Double) ... End Function Function mainActionHappensHere(L as Double, U as Double ...) Function cleaner(x) cleaner = complicatedFunct

我试图通过从私有范围内的函数中剥离参数来清理代码,如下所示:

Function complicatedFunction(x as Double, param1 as Double, param2 as Double)
    ...
End Function

Function mainActionHappensHere(L as Double, U as Double ...)
    Function cleaner(x)
        cleaner = complicatedFunction(x, L, U)
    End Function
    ...
    cleaner(x)                       'Many calls to this function
    ...
End Function
Sub complicatedFunction(x as Double, param1 as Double, param2 as Double) 
    ...
End Sub

Function mainActionHappensHere(L as Double, U as Double ...)
    Dim cleaner As Func(Of Double, Object) = 
        Function(x) 
            Return complicatedFunction(x, L, U)
        End Function

    Dim y = cleaner(x)                       'Many calls to this function
    ...
End Function

这可能吗?编译器抱怨“预期的结束函数”,因为我在结束外部函数之前开始一个函数。谷歌也帮不了什么忙:(PS我不能在mainActionHappensHere()之外定义cleaner(),因为那样就不会把正确的L和U传递给它了。

VB.Net可以做到这一点,但我不相信VBA可以做到

重载函数或可选参数可能有助于以其他方式简化此代码。以下是使用可选参数的示例:

Function complicatedFunction(x as Double, Optional param1 as Double = L, Optional param2 as Double = U) As Object
...
End Function

complicatedFunction(x)
然而,L和U必须是常数才能工作

FWIW,如果事实证明您使用的是VB.Net方言,则VB.Net语法如下所示:

Function complicatedFunction(x as Double, param1 as Double, param2 as Double)
    ...
End Function

Function mainActionHappensHere(L as Double, U as Double ...)
    Function cleaner(x)
        cleaner = complicatedFunction(x, L, U)
    End Function
    ...
    cleaner(x)                       'Many calls to this function
    ...
End Function
Sub complicatedFunction(x as Double, param1 as Double, param2 as Double) 
    ...
End Sub

Function mainActionHappensHere(L as Double, U as Double ...)
    Dim cleaner As Func(Of Double, Object) = 
        Function(x) 
            Return complicatedFunction(x, L, U)
        End Function

    Dim y = cleaner(x)                       'Many calls to this function
    ...
End Function

VB中没有嵌套函数,无论是VBA、VB6还是VB.NET

将范围限制为VBA,您可以选择:

  • Use是最早的VB命令之一,它已被弃用、不受欢迎,并且在VB.NET中没有同等的升级版本:

    Function mainActionHappensHere(L as Double, U as Double ...)
        Dim ResultOfCleaner As Variant
        ...
        x = 5 : GoSub cleaner                       'Many calls to this function
        'Use ResultOfCleaner here
        ...
        x = 42 : GoSub cleaner                      'Many calls to this function
        'Use ResultOfCleaner here
        ...
        Exit Function
    
    cleaner:
        ResultOfCleaner = complicatedFunction(x, L, U)
        Return
    End Function
    
  • 手动创建一个闭包

    定义一个类,该类将
    L
    U
    作为字段或属性公开。实例化该类,设置
    L
    U
    一次,然后调用函数
    Cleaner
    ,该函数也在该类中定义,使用存储的
    L
    U
    调用
    复杂函数

    显然,这会产生一些开销


您可以使用此语法

Dim fSomeFunction As Func(Of String, Boolean) = Function(ByVal something As String) As Boolean
                                                                     Return True
                                                                 End Function

不,VBA中没有嵌套函数,但是如果你想使它更精简,那么就声明函数私有,只有该模块才能看到它。为什么你不能用参数L、U和x在外部声明它。从mainActionHappensHere传入L和U,它是等价的。它在逻辑上是等价的,但不更干净。我将使用com复杂函数(x,L,U)写得到处都是,我希望通过让cleaner(x)写得到处都是,代码更容易理解。PS如果我在mainActionHappensHere()之外声明cleaner(),mahh()仍然能够“看到”cleaner(),但当我从cleaner()内部调用复杂函数()时,它将不知道“L”是什么和“U”是指,因为它们超出了范围!如果你真的想这样做,那么就将L和U声明为模块级而不是方法级。但我仍然认为这是一个从无到有的问题-调用
mySub x,y,z
与调用
mySub x
相比,调用
mySub x
在功能上意味着
mySub x,y,z
在我看来,on几乎没有“清理”任何东西。我想最后一个选项,取决于他的设置,是声明L和U模块级别,并将cleaner声明为一个普通函数,在模块级别L和U中传递到可怕的复杂函数。't two可能会很难看;)vb.net可以嵌套函数,正如我在下面演示的那样。@Cor_Blimey在模块级使用
L
U
时,顶层函数将变为不可重入安全的。@JoelCoehoorn这些不是嵌套函数,而是lambda。在函数中声明一个局部变量,并为其分配一个“lambda”类型的对象。您仍然没有嵌套函数。这与此用途相同。不仅是VB.NET,而且VB.NET>=2010,其中首次出现了多行lambda。是的,尽管这足够简单,可以在需要时简化为单行lambda。Dang,我希望我现在正在使用VB.NET。。。这些lambda表达式将是我的解决方案!对于记录,cleaner(x)确实有一个返回值(它需要是一个函数,而不是一个子函数),我在上面省略了它。“编译错误”(在VBA中)