Notation Simplifiée pour définir une collection ou un tableau arborescent

Notation Simplifiée pour définir une collection ou un tableau arborescent 3.1

Bonjour à toutes et tous, camarades codeurs !

Je propose ici une notation pour simplifier l'initialisation de données sous la forme d'une structure arborescente.
Dans la discussion suivante j'explique le cheminement de mon raisonnement :
Notation-simplifiee-pour-definir-un-tableau-arborescent

Pour résumer voici un exemple avec des entiers :
VB:
Dim s As String, v As Variant
    v = Array(5, 8, Array(14, -5, Array(-9, Array(-7, 54)), 87), 84, 4)
    ' Ce tableau sera initialisé comme ceci
    s = "[5,8,[14,-5,[-9,[-7,54]],87],84,4]"

Je propose une implémentation qui prend en charge les données suivantes selon le paramétrage défini :
  • Les entiers avec une conversion au choix en Integer, Long ou Byte
  • Les décimaux avec une conversion au choix en Double ou Single
  • Le Texte avec ou sans Trim (suppression ou non des espaces en début et fin de ligne)
  • Les dates
  • Les objets en les associants à des Alias et noté ainsi #{Alias}
Il y a aussi la prise en charge de données spécifiques qui sont interprétés ainsi :
  • @ : valeur nulle (Null)
  • ¤ : élément vide (Empty)
  • $ : chaîne vide ("")

Mise en application
La fonction §
Il s'agit de la fonction qui convertie la notation simplifiée soit en Collection ou Tableau arborescent.
Par défaut la fonction est initialisée pour prendre en charge uniquement des entiers convertis en Integer et elle permet de récupérer une collection arborescente ou après reconversion, un tableau arborescent.
Je remercie au passage @Dranreb pour la pertinence de ses remarques qui m'a incité à utiliser la collection comme structure dans ma fonction récursive plutôt qu'un tableau.

Voici un exemple avec une Collection en retour :
VB:
Dim cl As Collection, s As String
    s = "[5,8,[14,-5,[-9,[¤,@]],87],84,4]"
    Set cl = §(s)
Et ci-dessous un exemple avec un tableau en retour et donc le paramètre toArray à True :
VB:
Dim v As Variant
    v = "[5,8,[14,-5,[-9,[¤,@]],87],84,4]"
    § v, True
Il faut rappeler que les éléments d'une collection sont accessibles en lecture seule alors que les éléments d'un tableau peuvent être modifiés.

La fonction Set§
Les paramètres :
  • sClass : "N" par défaut. Combinaison des symboles suivants :
    • 'N' : Nombre entier relatif ou naturel
    • 'R' : Nombre réel ou décimal
    • 'T' : Texte
    • 'D' : Date
    • 'O' : Objet, tous excepté la Collection
  • sNNbType : "I" par défaut. Conversion pour les entiers, soit 'I'nteger, 'L'ong ou 'B'yte
  • sRealType : "D" par défaut. Conversion pour les décimaux, soit 'D'ouble ou 'S'ingle
  • p§Sep : "," ,ou ";" si sClass inclue 'T' ou 'R', par défaut. Caractère qui sépare les données
  • keepSpc : False par défaut. Si vrai, les espaces en début et à la fin de chaque donnée sont conservés
Exemples :
VB:
' Texte seul, sans Trim
Set§ "T", , , , True

' Texte, Entier(Long), Décimal (Single) seul avec un séparateur '#'
Set§ "TNR", "L", "S", "#"

Les fonctions pour référencer des objets
Il faut tout d'abord initialiser les références aux objets avec InitAliasObj§ puis ajouter des alias pour les objets que l'on souhaite référencer.
Lorsque l'on a plus besoin de ces références il est nécessaire de supprimer ces références aux objets en rappelant InitAliasObj§.
Voici un exemple avec une classe utilisateur 'UserClass' :
VB:
Dim uc As New UserClass, rg As Range, cl As Collection, s As String
    InitAliasObj§
    AddAliasObj§ uc, "UsCl"
    Set rg = Range("A1")
    AddAliasObj§ rg, "RgA1"
    Set§ "NO"
    s = "[5,8,[#UsCl,#RgA1],84,4]"
    Set cl = §(s)
    InitAliasObj§

Les Tests
Il y a une interface pour tester les fonctions dans le classeur joint à cette ressource
Voici le contenu des modules importants qui compose ce classeur :
  • M§ : toutes les fonctions pour initialiser une structure arborescente
  • TestGame : le jeu de test avec lequel il est possible de tester et visualiser des Notations Simplifiées
  • Tools : des fonctions génériques

Version simplifiée de la fonction §
Voici une implémentation spécifique pour gérer uniquement des entiers de type Integer :
VB:
'Fonction : Notation Abrégée = Txt§ -> Tree Collection Cl§.
'   sTxt§ : Notation abrégée = "[{val}|{Txt§},{val}|{Txt§},(...)]"
'       ex : "[4, 7, 5,[4, 6,[87 , -5], 8] ]"
'Retour : Collection Arborescente de données
'Erreur syntaxique de Txt§ : Nothing(en Retour)
Function §(ByRef sTxt§ As String) As Collection
Dim pos As Integer, size As Integer
    On Error GoTo badSyntax
    sTxt§ = Replace(sTxt§, " ", "")
    size = Len(sTxt§): pos = 2
    Set § = Txt§ToCl§(sTxt§, pos)
    If pos <> (size + 1) Then GoTo badSyntax
    Exit Function
badSyntax:
    Set § = Nothing
End Function

'Fonction récursive permettant de convertir la Notation Abrégée 'pTxt§' en Tree Collection Cl§
'   pos : 'position de lecture' dans 'pTxt§' (Attention, il faut 'passer' le 1er '[')
'Retour : Collection Arborescente de données Cl§
Private Function Txt§ToCl§(pTxt§ As String, ByRef pos As Integer) As Collection
Dim elt As Variant, isOpn As Boolean, i1 As Integer, v2 As Variant, p As Byte
    Set Txt§ToCl§ = New Collection
    Do
        i1 = InStr(pos, pTxt§, "[")
        v2 = InStr(pos, pTxt§, "]")
        If (i1 > 0) Xor (v2 > 0) Then   'v1=Min(i1,v2) sauf si =0
            If i1 > v2 Then isOpn = True Else i1 = v2
        Else
            If i1 < v2 Then isOpn = True Else i1 = v2
        End If
        If i1 > pos Then
            v2 = Split(Mid(pTxt§, pos, i1 - pos + isOpn), ",") 'Séparateur : ','
            For Each elt In v2  'Type String par défaut
' Traitement de donnée
                Txt§ToCl§.Add CInt(elt)
' Fin de traitement
            Next elt
        End If
        If isOpn Then  '[, tableau imbriqué
            pos = i1 + 1
            Txt§ToCl§.Add Txt§ToCl§(pTxt§, pos)
            isOpn = False
        Else    '] de Fin
            i1 = i1 + 1
            pos = IIf(Mid(pTxt§, i1, 1) = ",", i1 + 1, i1) 'Séparateur : ','
            Exit Function
        End If
    Loop Until False    'Sortie si Erreur ou i1=v2=0
End Function

Sub Test§()
Dim cl As Collection, s As String
    s = "[8, 3,[5, 6, 9,[5], 98], -47]": Set cl = §(s)
End Sub
Remarque : pour adapter la fonction pour des données spécifiques il suffit de modifier la partie Traitement de donnée.
Auteur
Ludovic FERRON
Version
1.0
  • J'aime
Réactions: YounesChibouti