Retourner un Dictionnaire Dans une fonction

Bonjour,

Je cherche à réaliser une fonction récursive qui vas ajouter toutes les valeurs des cellules de deux colonnes dans un Dictionnaire.

J'ai donc fait ça :

Public Function rec_get_all_dum(start_row, res)

    If Not IsEmpty(Cells(start_row, 1)) Then
        res.Add Cells(start_row, 1), Cells(start_row, 2)
        res = rec_get_all_dum(start_row + 1, res)
    End If

    Set rec_get_all_dum = res

End Function

Et je lance ma fonction comme cela :

Set res = CreateObject("Scripting.Dictionary")
all = Feuil2.rec_get_all_dum(2, res)

A priori la fonction récursive fonctionne en elle même, mais je croit que c'est le fait de retourner un Dictionary le probléme (mais je suis pas sûr)

Voila l'erreur que ça affiche :

"Nombre d'arguments incorrect ou affectation de propriété incorrecte"

SI vous avez une piste je suis preneur

bonjour,

comme tu passes le dictionnaire dans les paramètres pas besoin de définir une fonction une sub suffit.

Public Sub rec_get_all_dum(start_row, res)
'sub récursive, mais je ne vois pas la nécessité de cette récursivité (voir sub alternative ci-dessous)
    If Not IsEmpty(Cells(start_row, 1)) Then
        res.Add Cells(start_row, 1), Cells(start_row, 2)
        rec_get_all_dum start_row + 1, res
    End If
End Sub

Sub test()
    Set res = CreateObject("scripting.dictionary")
    rec_get_all_dum 2, res
    'loadres 2, res
    all = res.Keys
    Cells(1, 3).Resize(res.Count) = Application.Transpose(all)
    all=res.items
    Cells(1, 4).Resize(res.Count) = Application.Transpose(all)
End Sub

' sub alternative non récursive 
Sub loadres(ByVal start_row, res)
    While Not IsEmpty(Cells(start_row, 1))
        res.Add Cells(start_row, 1), Cells(start_row, 2)
        start_row = start_row + 1
    Wend
End Sub

voici une exemple de retour d'un dictionnaire dans une fonction

Sub aargh()
    Set r = createdict(2)
    all = r.Keys
    Cells(1, 3).Resize(r.Count) = Application.Transpose(all)
    all = r.Items
    Cells(1, 4).Resize(r.Count) = Application.Transpose(all)
End Sub

Function createdict(start_row)
    Set res = CreateObject("scripting.dictionary")
    While Not IsEmpty(Cells(start_row, 1))
        res.Add Cells(start_row, 1), Cells(start_row, 2)
        start_row = start_row + 1
    Wend
    Set createdict = res
End Function

Bonjour,

Ta fonction récursive fonctionne bien le seul problème c'est qu'il te faut garder à l'esprit que l'affectation d'un objet à une variable se fait toujours avec l'instruction Set :

Sub Test()

    Dim Res As Object
    Dim I As Integer
    Dim Cle
    Dim Elem

    Set Res = CreateObject("Scripting.Dictionary")
    Set Res = rec_get_all_dum(ActiveSheet, 2, Res)

    For Each Elem In Res.Items: Debug.Print "valeur de l'item : "; Elem: Next Elem

    For Each Cle In Res.Keys: Debug.Print "valeur de la clé : "; Cle: Next Cle

End Sub

Public Function rec_get_all_dum(Fe As Worksheet, start_row, Res) As Object

    With Fe

        If Not IsEmpty(.Cells(start_row, 1)) Then

            Res.Add .Cells(start_row, 1).Value, .Cells(start_row, 2).Value
            Set Res = rec_get_all_dum(Fe, start_row + 1, Res)

        End If

    End With

    Set rec_get_all_dum = Res

End Function

Merci beaucoup pour vos réponses très claires !

Effectivement pour le set j'avais oublier quand l'utiliser donc merci

Ha oui effectivement c'est bien plus propre avec le sub sans return pour le coup

Et pour le moment le récursif n'est effectivement pas utile mais la fonction vas un peu se compliquer par la suite.

Encore merci pour vos réponses !

Petite précision concernant les fonctions récursives, elles sont, selon le cas, gourmande en mémoire et limitées dans la pile des appels qu'elles créent, un petit exemple que j'ai donné dans un autre post avec la fonction récursive très connue, la factorielle. Pour tester et comprendre le fonctionnement d'un fonction récursive, lancer la sub "Test" en pas à pas avec F8 pour avoir la factorielle de 10 et regarder dans la fenêtre d'exécution (Ctrl+G) :

Sub test()

    MsgBox Factorielle(10)

End Sub

Function Factorielle(Nb As Integer)

    'déclarées en static pour garder en mémoire les valeurs
    Static Rappel As Integer
    Static Fin As Boolean

    Rappel = Rappel + 1: Debug.Print Rappel

    If Nb = 1 Then 'Point de sortie, absolument obligatoire pour éviter une boucle sans fin !

        Factorielle = 1
        Fin = True
        Debug.Print "Maintenant, phase de calcul !"

    Else

        'à chaque appel, le résultat est stoké en mémoire
        'ce qui crée unne pile des appels
        Factorielle = Nb * Factorielle(Nb - 1)

    End If

    'on remonte la pile des appels
    If Fin = True Then Rappel = Rappel - 1: Debug.Print Rappel

End Function

Ce qu'il est possible de voir avec ta fonction :

Public Function rec_get_all_dum(Fe As Worksheet, start_row, Res) As Object

    Static Pos As Integer 'Static permet de garder en mémoire comme une variable déclarée en tête de module

    With Fe

        If Not IsEmpty(.Cells(start_row, 1)) Then

            Res.Add .Cells(start_row, 1).Value, .Cells(start_row, 2).Value
            Set Res = rec_get_all_dum(Fe, start_row + 1, Res)

        End If

    End With

    Stop 'arrête le déroulement du code pour permettre la suite avec F8 !
    Pos = Pos + 1
    Debug.Print "Appel de la pile numéro : "; Pos

    Set rec_get_all_dum = Res

End Function
Rechercher des sujets similaires à "retourner dictionnaire fonction"