在递归函数(VBA)中设置变量

时间:2018-06-18 01:23:07

标签: vba recursion

我创建了一个在For循环中调用的递归函数,但是我遇到了一个代码块的问题。从下面的代码中可以清楚地看出,应该有一个递归函数进入"向后" (回到调用它的For循环)。我想要发生的是让probInt变量不倒退(如果这有意义的话)。

例如,假设首次调用函数时第一个IF语句为FALSE,则probInt将设置为0,然后再次调用SOLVE。如果第二次调用该函数时IF语句为TRUE,则probInt将设置为1,然后该函数将退出 - 将我们返回到初始FOR循环。我发现当我返回到初始FOR循环时,probInt再次设置为0而不是1.我如何设置它以便即使递归函数倒退时probInt也保持为1?

Public probInt As Integer

Function Solve()
   If (some value in the spreadsheet) = 0 Then
       probInt = probInt + 1
       Exit Function
   End If

   For i = 0 To (some other value in the spreadsheet)
       probInt = 0
       Call Solve()
   Next i
Exit Function

1 个答案:

答案 0 :(得分:1)

Recursion很有意思,但它很快就会变得复杂,而且在使用全局变量时会很危险

你可以把它想象成一个循环的替代品,它可以在某些算法中非常有效,但在你的情况下,正如蒂姆所说,它可能被一个简单的循环取代(你的最终目标不是很好)明确,除非你想学习)

此外,您的Function应为Sub,因为它不会返回任何内容

<强> 1。递归与循环

Option Explicit

Public prob As Long     'Global - dangerous

Public Sub SetProb()
    Debug.Print prob    '0
    RecurseProb
    Debug.Print prob    '5

    Debug.Print prob    '5
    LoopProb
    Debug.Print prob    '0
End Sub

Public Sub RecurseProb()    'Recursion based on global variable
    prob = prob + 1
    If prob < 5 Then RecurseProb Else Exit Sub
End Sub

Public Sub LoopProb()
    While prob > 0
        prob = prob - 1
    Wend
End Sub

<强> 2。全局变量的危险 - 无限递归

其中2个程序同时修改prob全局

Public Sub SetProbInfinite()
    Debug.Print prob    '0
    RecurseProbInfinite 'Infinite loop - Run-time error 28: Out of stack space
End Sub

Public Function RecurseProbInfinite()   'Recursion based on global variable
    prob = prob + 1     'prob increments by 1
    If prob < 5 Then
        LoopProb        'prob decrements by 1
        RecurseProbInfinite
    Else
        Exit Function
    End If
End Function

第3。更安全的递归 - 使用参数

Public Sub SetProbSafe()            'Recursion based on parameter
    prob = 0
    prob = RecurseProbSafeRef(prob) 'Parameter sent ByRef
    Debug.Print prob    '5

    prob = 0
    prob = RecurseProbSafeVal(prob) 'Parameter sent ByVal
    Debug.Print prob    '1
End Sub

Public Function RecurseProbSafeRef(ByRef prob As Long) As Long
    If prob < 5 Then
        prob = prob + 1
        RecurseProbSafeRef prob
    End If
    RecurseProbSafeRef = prob
End Function

Public Function RecurseProbSafeVal(ByVal prob As Long) As Long
    If prob < 5 Then
        prob = prob + 1
        RecurseProbSafeVal prob
    End If
    RecurseProbSafeVal = prob
End Function

在处理二叉树时,VBA中的递归可能是非常有益和有效的(减少指数量),就像基于父子关系的对象模型一样,我们不知道树的“叶子”在哪里是(儿童没有自己的孩子),我们让每个对象确定它是否有孩子

我在基本性能测试中发现,VBA递归的另一个(令人惊讶的)事实是For循环比递归函数更快