【问题标题】:VBA Recursion Method - Exit Function Not ExitingVBA递归方法 - 退出函数不退出
【发布时间】:2020-04-28 14:10:05
【问题描述】:

为什么这个函数不退出?我已经尝试过 Exit Function 和 Exit For。在我到达 Ubound(arr) 语句后,我重置为 i = 0 并且调用堆栈恢复到 End Select 语句,此后 For 循环再次开始。这一定来自我执行的递归行?

Function AddArrToObj(ByRef arr As Variant, ByRef obj As Object, Optional ByVal i As Integer = 0)
    For i = LBound(arr) To UBound(arr)
        Select Case VBA.TypeName(obj)
            Case "Collection"
                obj.Add arr(i)
            Case "Dictionary"
                obj.Add i + 1 & " " & arr(i), arr(i)
            Case "Nothing"
                Set obj = New VBA.Collection
                Call AddArrToObj(arr, obj) 'Recursion
        End Select
        'Add Watch for i = 3 break on True
        'Why does this function not exit appropriately?
        If Not IsEmpty(obj) And i = UBound(arr) Then Exit Function
    Next i
End Function


Public Sub TestSO()
Dim collA       As VBA.Collection
Dim cmdStr      As String
cmdStr = "StackOverflow is a website."
arr = VBA.Split(cmdStr, " ")

    Call AddArrToObj(arr, collA)

End Sub

【问题讨论】:

  • If Not obj is Nothing And...

标签: vba recursion pass-by-reference


【解决方案1】:

您可以使用递归来完成此操作,但它不必要地复杂。根据经验,只有当递归算法更易于阅读和编写时,才应使用递归而不是迭代。否则,您应该使用迭代,因为使用递归可能会出现 stackoverflow 错误。话虽如此,这是一个使用递归的解决方案。我对您的代码进行了一些修改,以使用递归和迭代返回的集合对象。:

    Function AddArrToObj(ByRef arr As Variant, ByRef obj As Object, Optional ByVal i As Integer = 0)
    If obj Is Nothing And i <> 0 Then
        Set obj = New Collection
    End If

    For i = LBound(arr) To UBound(arr)
        Select Case VBA.TypeName(obj)
            Case "Collection"
                obj.Add arr(i)
            Case "Dictionary"
                obj.Add i + 1 & " " & arr(i), arr(i)
            Case "Nothing"
                Set obj = AddArrToObj(arr, obj, 1) 'Recursion
                Exit For
        End Select
    Next i

    Set AddArrToObj = obj
End Function

Public Sub TestSO()
Dim collA       As VBA.Collection
Dim cmdStr      As String
Dim arr() As String
Dim obj As Object
Dim elem As Variant

cmdStr = "StackOverflow is a website."
arr = VBA.Split(cmdStr, " ")

Set obj = AddArrToObj(arr, collA)

For Each elem In obj
    Debug.Print elem
Next elem

End Sub

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-28
    • 1970-01-01
    • 2018-07-29
    • 1970-01-01
    • 2021-11-18
    • 2012-10-27
    • 1970-01-01
    相关资源
    最近更新 更多