Метод рекурсии VBA - функция выхода не завершена - PullRequest
0 голосов
/ 11 января 2020

Почему эта функция не выходит? Я пробовал и функцию выхода, и функцию выхода. После того, как я достигаю оператора Ubound (arr), i сбрасывается до i = 0, и стек вызовов возвращается к оператору End Select, после чего For For L oop начинается снова. Это должно быть из строки рекурсии, которую я выполняю?

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

1 Ответ

1 голос
/ 11 января 2020

Вы можете сделать это sh с помощью рекурсии, но это излишне сложно. Как правило, вы должны использовать рекурсию через итерацию только тогда, когда рекурсивные алгоритмы намного легче читать и писать. В противном случае вы должны использовать итерацию из-за возможной ошибки в стеке потока при использовании рекурсии. При этом, вот решение с использованием рекурсии. Я немного изменил ваш код, чтобы он работал как с использованием рекурсии, так и перебирал возвращаемый объект коллекции.:

    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
...