Private Function SousDict(ByVal C As Long) As Dictionary ' (Récursif)
Dim Lignes() As Long, N As Long, ArgC As Variant, ArgR As Variant
On Error GoTo Erreur
Set SousDict = New Dictionary
If C < CMax Then ' Si ce n'est pas le dictionnaire de la dernière colonne qu'on est en train de construire :
Do: ArgC = TabArgs(L, C): Arg(C) = ArgC: Typ(C) = VarType(ArgC) ' Note chaque sous-clé courante pour les futurs tests de ruptures de séquence.
SousDict.Add Key:=ArgC, Item:=SousDict(C + 1) ' Affecte à cette sous-clé le sous dictionnaire de la colonne suivante … ICI APPEL RÉCURSIF
Loop Until Rupt < C ' … jusqu'à rupture de séquence sur une colonne précédente (il est alors forcément complet) voire sur 0 si tout est fini.
Else ' On est en train de construire le dictionnaire de la dernière colonne, celui des listes de lignes, une pour chaque dernière sous-clé.
ReDim Lignes(1 To 512) As Long
Do ' Niveau dictionnaire, tant que le niveau de rupture n'est pas inférieur à C, qui est donc ici CMax, la dernière colonne.
ArgC = TabArgs(L, C): Arg(C) = ArgC: Typ(C) = VarType(ArgC): N = 0 ' Note l'argument courant pour les tests de ruptures
Do ' Niveau sous-clé, tant que le niveau de rupture est supérieur à C, c'est à dire pas de rupture car c'est un doublon.
If N >= UBound(Lignes) Then ReDim Preserve Lignes(1 To (N \ 64 + 1) * 64) As Long
N = N + 1: Lignes(N) = L ' Note la ligne dans la table en construction.
If TIdx.Actif Then ' Si on n'était pas encore au dernier élément indexé, on demande le numéro du suivant et on cherche la rupture par rapport …
L = TIdx.Suivant ' … à tous les Arg(1 à CMax) notés aussi bien dans les appelant récursifs (< CMax) qu'ici plus haut (= CMax, donc = C).
For Rupt = 1 To CMax: ArgR = TabArgs(L, Rupt)
If VarType(ArgR) <> Typ(Rupt) Then Exit For ' Il y a rupture si la nouvelle sous-clé n'est plus du même type de variant.
If ArgR <> Arg(Rupt) Then Exit For ' Il y a évidemment rupture si la nouvelle sous-clé n'a plus la même valeur.
Next Rupt ' Si on va jusqu'au bout de la boucle, c'est encore un doublon et Rupt se retrouve = CMax + 1
Else: Rupt = 0: End If ' Si on était sur le dernier, tous les Loop Until Rupt < C devront se terminer dans tous les appels récursifs.
Loop Until Rupt <= C ' Niveau sous-clé terminé s'il y a une rupture quelconque.
ReDim Preserve Lignes(1 To N) As Long ' Ajustement de la table des lignes qu'on vient de construire au strict nécessaire.
SousDict.Add Key:=ArgC, Item:=Lignes ' Et son ajout comme Item au dictionnaire, sous-clé courante toujours encore notée quoique ancienne maintenant.
Loop Until Rupt < C ' Niveau dicionnaire terminé si la rupture est à un niveau inférieur.
End If
Exit Function ' Rend la main soit à DictionnArbo si C = 1, soit à l'appelant récursif si C > 1, finalisant son
' propre SousDict.Add Key:=ArgC, Item:=SousDict(C + 1) qui est le Sous-dictionnaire qu'on vient d'élaborer !
Erreur: MsgBox Err.Description: Stop: Resume
End Function