Lu76Fer
XLDnaute Occasionnel
Préambule
En cherchant à simplifier la déclaration de tableau imbriqué, j'ai exploré certaines pistes qui s'avéreront infructueuses ...
Pour clarifier, voici un petit exemple de déclaration :
Et j'aurai souhaité le déclarer comme ceci :
treeAr = [4, 7, 5, [4, 6, 8], 7]
Mais les crochets sont utilisés pour contenir une fonction utilisateur en langage Universel (l'anglais). Il est possible de déclarer un tableau de Variant à 2 dimensions avec cette syntaxe ou de lancer une fonction de son classeur mais pas une routine :
Les limites : on ne peut pas lancer une fonction 'microsoft' mais seulement une fonction utilisateur ou une fonction appartenant à son classeur.
Après réflexion, je me suis dit que je pourrais faire ma notation sous forme de chaîne puis au travers d'une routine, remplacer '[' par 'Array(' et ']' par ')' puis demander une exécution du code à la volée à l'aide de la fonction 'Eval' qui devait me faire cela mais cette fonction n'existe qu'en VB ou sous Access et je ne suis pas vraiment sûr de ce qu'il est possible de faire avec.
Il existe bien aussi une fonction 'Application.Evaluate' mais ce n'est qu'une syntaxe différente de la notation abrégée [...]
Ma Notation Simplifiée
A l'approche de Noël et étant frustré de ne pas avoir ma Notation Simplifiée tel le gamin qui se verrait refuser sa liste de jouets, j'ai décidé de créer la mienne ...
et treeAr devient :
Comme il s'agit d'une chaîne de caractère et que les espaces sont ignorés (supprimés) j'ai fait le choix de ne gérer que des chaînes(String) sans espace ni guillemet et des nombres entiers relatifs(Integer).
Le code pourrait facilement être modifié pour gérer des types différents ou mieux gérer les chaînes de caractère... En cas d'erreur de syntaxe la routine renvoie Null
J'ai choisi '§' comme nom pour ma routine appelant la fonction récursive afin de créer une notation concise. A noter que l'on peut aussi utiliser les symboles suivants : ù,µ,£
Les évolutions possibles
En cherchant à simplifier la déclaration de tableau imbriqué, j'ai exploré certaines pistes qui s'avéreront infructueuses ...
Pour clarifier, voici un petit exemple de déclaration :
VB:
Dim treeAr As Variant,
treeAr = Array(4, 7, 5, Array(4, 6, 8), 7)
treeAr = [4, 7, 5, [4, 6, 8], 7]
Mais les crochets sont utilisés pour contenir une fonction utilisateur en langage Universel (l'anglais). Il est possible de déclarer un tableau de Variant à 2 dimensions avec cette syntaxe ou de lancer une fonction de son classeur mais pas une routine :
VB:
treeAr = [A1:C2] 'ou
treeAr = [Toto] 'Si on a nommé une zone Toto dans le classeur actif
'*** Avec une fonction du classeur ***
Function nAjout(ParamArray n()) As Variant
Dim v As Variant
For Each v In n
nAjout = nAjout + v
Next v
End Function
'(...)
Dim v As Integer
v = [nAjout(8,6,9)]
debug.print v
Après réflexion, je me suis dit que je pourrais faire ma notation sous forme de chaîne puis au travers d'une routine, remplacer '[' par 'Array(' et ']' par ')' puis demander une exécution du code à la volée à l'aide de la fonction 'Eval' qui devait me faire cela mais cette fonction n'existe qu'en VB ou sous Access et je ne suis pas vraiment sûr de ce qu'il est possible de faire avec.
Il existe bien aussi une fonction 'Application.Evaluate' mais ce n'est qu'une syntaxe différente de la notation abrégée [...]
VB:
v = [nAjout(8,6,9)]
'peut aussi s'écrire :
v = Evaluate("nAjout(8,6,9)")
Ma Notation Simplifiée
A l'approche de Noël
VB:
Dim treeAr As Variant,
treeAr = "[4, 7, -5, [pim, pam, poum], 7]": § treeAr
Comme il s'agit d'une chaîne de caractère et que les espaces sont ignorés (supprimés) j'ai fait le choix de ne gérer que des chaînes(String) sans espace ni guillemet et des nombres entiers relatifs(Integer).
Le code pourrait facilement être modifié pour gérer des types différents ou mieux gérer les chaînes de caractère... En cas d'erreur de syntaxe la routine renvoie Null
J'ai choisi '§' comme nom pour ma routine appelant la fonction récursive afin de créer une notation concise. A noter que l'on peut aussi utiliser les symboles suivants : ù,µ,£
VB:
'Fonction appelante de "AbNotToTreeArray"
' treeAr : (String) Notation abrégée AbNot="[{val}|{AbNot},{val}|{AbNot},(...)]"
' ex : "[4, 7, 5,[4, 6,[titi,Gros-Minet], 8]]" rem. : "..." implicite car treeAr est une chaine
'Renvoie : un tableau arborescent de valeur de type String(sans , ou espace) ou Integer (si numérique)
' et Null en cas d'erreur syntaxique en entrée
Sub §(ByRef treeAr As Variant)
Dim size As Integer, sAbNot As String
On Error GoTo badSyntax
sAbNot = Replace(treeAr, " ", "")
size = Len(sAbNot)
If AbNotToTreeArray(treeAr, sAbNot, size, 2) <> (size + 1) Then GoTo badSyntax
Exit Sub
badSyntax:
treeAr = Null
End Sub
'Fonction récursive permettant de convertir une notation abrégée 'sAbNot' en tableau arborescent de données 'treeAr'
' size : nombre de caractère à traiter dans 'sAbNot' à partir de 'pos' (initialisée par <Len(sAbNot)> au départ)
' pos : 'position de lecture' dans 'sAbNot' (Attention, il faut 'passer' le 1er '[')
'Retour : nouvelle 'position de lecture' de 'sAbNot'
Private Function AbNotToTreeArray(ByRef treeAr As Variant, ByRef sAbNot As String, size As Integer, pos As Integer) As Integer
Dim i1 As Integer, v2 As Variant, isOpn As Boolean, newPos As Integer
Dim idx As Integer, elt As Variant, subAr As Variant
ReDim treeAr(size - 3)
Do
i1 = InStr(pos, sAbNot, "[")
v2 = InStr(pos, sAbNot, "]")
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 isOpn Then '[ : donnée de type Sub-Array alors appel récursif
newPos = AbNotToTreeArray(subAr, sAbNot, size - i1 + 1, i1 + 1) 'newPos : future position après le Sub-Array (subAr)
i1 = i1 - 1
End If
If i1 > pos Then
v2 = Split(Mid(sAbNot, pos, i1 - pos), ",")
For Each elt In v2 'Type String par défaut
If IsNumeric(elt) Then elt = CInt(elt) 'Si val Numérique, conversion en Integer
treeAr(idx) = elt: idx = idx + 1
Next elt
End If
If isOpn Then '[
treeAr(idx) = subAr: idx = idx + 1
pos = newPos: isOpn = False
Else
ReDim Preserve treeAr(idx - 1)
i1 = i1 + 1
AbNotToTreeArray = IIf(Mid(sAbNot, i1, 1) = ",", i1 + 1, i1)
Exit Function
End If
Loop Until False 'Sortie si Erreur ou i1=v2=0
End Function
Les évolutions possibles
- Il est possible de faire une version gérant les espaces dans les chaînes en introduisant un traitement préalable dans la routine '§'. Les chaînes pourraient être mise entre simple quote afin de faire la différence entre les espaces superflus et les espaces d'une chaîne.
- Il est aussi possible de prendre en charge les nombres réels et les dates en modifiant la fonction récursive et en utilisant isDate, CDate ...
Dernière édition: