I'm trying to clean up code by stripping parameters from a function within a private scope, like this:

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

Is this possible? Compiler complains, "Expected End Function", since I'm beginning a function before ending the outer one. And Google is no help :( PS I can't define cleaner() outside of mainActionHappensHere(), since then the correct L and U won't get passed into it.

有帮助吗?

解决方案

VB.Net can do this, but I don't believe VBA can.

Two features that might help you simplify this code in other ways are overloaded functions or optional parameters. Here's an example using optional parameters:

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

complicatedFunction(x)

However, L and U must be constants for this to work.

FWIW, and in case it turns out that you're really working with a VB.Net dialect, the VB.Net syntax looks like this:

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

其他提示

There are no nested functions in VB, either VBA or VB6 or VB.NET.

Limiting the scope to VBA, your options would be:

  • Use GoSub, one of the oldest VB command, that is deprecated, frowned upon and has no upgrade equivalent in 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
    
  • Manually create a closure.

    Define a class that exposes L and U as fields or properties. Instantiate the class, set L and U once, then call function Cleaner, also defined in that class, that calls complicatedFunction with the stored L and U.

    Obviously this creates some overhead.

You can use this syntax

Dim fSomeFunction As Func(Of String, Boolean) = Function(ByVal something As String) As Boolean
                                                                     Return True
                                                                 End Function
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top