Private Function SousDict(ByVal C As Long) As Dictionary ' (Récursif)
Dim Lignes() As Long, N As Long, ArgR As Variant, TypR As Integer
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: TypeEtVal(Typ(C), Arg(C)) = TabDico(L, C) ' Note chaque sous-clé courante pour les futurs tests de ruptures de séquence.
SousDict.Add Key:=Arg(C), Item:=SousDict(C + 1) ' ICI, APPEL RÉCURSIF. Affecte à cette sous-clé le sous dictionnaire de la colonne suivante.
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 liste 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.
TypeEtVal(Typ(C), Arg(C)) = TabDico(L, C): N = 0 ' Note l'argument courant pour les tests de ruptures 6 lignes plus bas.
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é :
L = TIdx.Suivant ' On demande le numéro de ligne du suivant, puis on cherche la rupture par rapport à tous les Arg(1 à CMax) notés …
For Rupt = 1 To CMax: TypeEtVal(TypR, ArgR) = TabDico(L, Rupt) ' …aussi bien dans les appelant récursifs qu'ici plus haut.
If TypR <> 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 qu'il s'agit encore d'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:=CStr(Arg(C)), Item:=Lignes ' Et son ajout comme Item au dictionnaire, sous-clé Arg(C) 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 ainsi 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 ' <--- cette ligne était précédée d'une apostrophe
End Function