Version 3
Cette fonction a pour objectif d'extraire des données d'une chaîne JSON. Par exemple le retour d'une fonction SERVICEWEB.
Voir :
- Exploiter des données d'Internet avec la fonction SERVICEWEB 1
- Exploiter des données d'Internet avec la fonction SERVICEWEB 2 (suite)
Utilisation
On la chaîne suivante par exemple :
Remarque : ici v2 (clé cX Objet1) n'est pas une chaîne d'où l'absence des guillemets.
On veut récupérer par exemple :
- Toutes les paires clé/valeur de Objet2 à Objet3.
- Les valeurs correspondantes à la clé "cX" pour tous les objets (v2, v3 ,v6).
- La valeur cX de Objet2 (v3).
On considérera que :
- Chaque objet génèrera une ligne de valeurs.
- Chaque paire clé/valeur génèrera une paire de colonne de valeurs.
Syntaxe d'utilisation
=Filtre.JSON(Chaine;[NumObjetDebut];[NumObjetFin];[ValeurCle];[NbcarPrefixe];[NbcarSuffixe])
Arguments
- Chaîne : (obligatoire) La chaîne à convertir.
- NumObjetDebut : (facultatif) (Valeur numérique positive) Position du premier objet à extraire (par défaut 1).
- NumObjetFin : (facultatif) (Valeur numérique positive) Position du dernier objet à extraire (par défaut le dernier).
- ValeurCle : (facultatif) (Valeur texte) Clé à rechercher (par défaut toutes les clés).
N'accepte pas les matrices => peut-être en version 4 😁. - NbcarPrefixe : (facultatif) (Valeur numérique positive) Nombre de caractères à ignorer en début de chaîne (par défaut 0).
- NbcarSuffixe : (facultatif) (Valeur numérique positive) Nombre de caractères à ignorer en fin de chaîne (par défaut 0).
Remarques
- La chaîne de départ doit être entre crochet ([...]).
- Pour ignorer des caractères en début et en fin de chaîne, utilisez les arguments NbcarPrefixe et NbcarSuffixe.
- Les objets imbriqués ({...}) et tableaux imbriqués ([...]) ne sont pas interprétés.
Exemples d'utilisation
Extraction de tous les objets.
Extraction de toutes les valeurs de la clé cX.
Le code de la fonction
=LAMBDA(Chaine;NumObjetDebut;NumObjetFin;ValeurCle;NbcarPrefixe;NbcarSuffixe;
LET(
Lch;NBCAR(Chaine);
NbcarPrefixe2;SI(
OU(ISOMITTED(NbcarPrefixe);NbcarPrefixe<0;SIERREUR(NbcarPrefixe>Lch-ABS(NbcarSuffixe);VRAI));
0;NbcarPrefixe);
NbcarSuffixe2;SI(
OU(ISOMITTED(NbcarSuffixe);NbcarSuffixe<0;SIERREUR(NbcarSuffixe>Lch-NbcarPrefixe2;VRAI));
0;NbcarSuffixe);
chN;STXT(Chaine;NbcarPrefixe2+2;Lch-NbcarSuffixe2-NbcarPrefixe2-2);
LchN;Lch-NbcarPrefixe2-NbcarSuffixe2;
s;SEQUENCE(LchN);
chM;CONCAT(MAP(s;LAMBDA(Vs;LET(
chG; STXT(chN;1;Vs);
tHTb;NBCAR(SUBSTITUE(chG;"]";""))=NBCAR(SUBSTITUE(chG;"[";""));
tHOb;(NBCAR(SUBSTITUE(chG;"}";""))-1)<=NBCAR(SUBSTITUE(chG;"{";""));
c;STXT(chN;Vs;1);
ccc;SI(ET(Vs>1;Vs<LchN-1);STXT(chN;Vs-1;3);"");
SI(ET(tHTb;tHOb;ccc="},{");CAR(30);
SI(ET(tHTb;tHOb;OU(ccc=""",""";ccc=""":""";DROITE(ccc;2)=",""";GAUCHE(ccc;2)=""":"));
CAR(31);
c))))));
matFc;MAKEARRAY(1;3;LAMBDA(l;c;INDEX({"""";"";""""};c)&CAR(31)&INDEX({"""";"""";""};c)));
matFl;MAKEARRAY(1;2;LAMBDA(l;c;INDEX({"}";"""}"};c)&CAR(30)&"{"""));
tabR;FRACTIONNER.TEXTE(STXT(chM;3;LchN-SI(STXT(chM;LchN-3;1)="""";6;5));matFc;matFl);
derLigne;LIGNES(tabR);
numObjetDebut2;SI(OU(
ISOMITTED(numObjetDebut);
numObjetDebut<0;
ESTTEXTE(numObjetDebut);
numObjetDebut>derLigne);
1;numObjetDebut);
numObjetFin2;SI(OU(
ISOMITTED(numObjetFin);numObjetFin<0;
ESTTEXTE(numObjetFin);
numObjetFin<numObjetDebut2;
numObjetFin>derLigne);
derLigne;numObjetFin);
objR;SI(
ET(numObjetDebut2=1;numObjetFin2=derLigne);
tabR;CHOISIRLIGNES(tabR;SEQUENCE(numObjetFin2-numObjetDebut2+1;;numObjetDebut2)));
SI(
ISOMITTED(ValeurCle);
objR;
SIERREUR(INDEX(ObjR;
SEQUENCE(numObjetFin2-numObjetDebut2+1);
BYROW(objR;LAMBDA(obj1R;EQUIV(ValeurCle;obj1R;0)))+1);
"Non trouvée"))))
(74 fonctions, 26 fonctions différentes, 2 255 caractères, je pense que c'est mon record 😁)
Interprétation de cette formule
> On fractionne la chaîne en ligne à chaque changement d'objet en se basant sur la présence des accolades fermante puis ouvrante si elles ne sont pas dans un objet ({...}) ou une liste ([...]) avec la fonction FRACTIONNER.TEXTE.
> Chaque objet est fractionné en colonne en se basant sur le caractère deux points ( : séparateur clé/valeur de l'élément) et le caractère virgule ( , séparateur des éléments) s'ils ne sont pas dans un objet ({...}) ou une liste ([...]).
> On "marque" les fractionnements des lignes en remplaçant les virgules correspondantes par le caractère ASCII 30 (séparateur d'enregistrement) et celui des colonnes en remplaçant les deux points correspondants par le caractère ASCII 31 (séparateur d'unité).
> Pour cela on va "parcourir" chaque caractère de la chaîne avec une fonction MAP pour réaliser ces remplacements.
>En se basant sur la comparaison du nombre de crochets/accolades ouvrant (marquant un début de table/objet) et fermants (marquant une fin de table/objet) se trouvant avant le caractère évalué (chaîne à gauche), on déterminera si l'on est dans une table ou un objet imbriqué.
- Lch : Longueur de la chaîne.
- NbcarPrefixe2 : si NbcarPrefixe est omis ou négatif ou plus long que le chaîne sans le suffixe ou en texte, on prend la valeur 0.
- NbcarSuffixe2 : si le NbcarSuffixe est omis ou négatif ou plus long que le chaîne sans NbcarPrefixe2 ou en texte, on prend la valeur 0.
- chN : Chaîne Nettoyée (suppression des caractères préfixes et suffixes).
- LchN : Longueur de la chaîne Nettoyée (chN).
Remplacement sélectif des deux points et virgules pour prendre en compte les tables/objets imbriqués :
- s : séquence de valeur de 1 à Lch servant à parcourir chaque caractère de chN.
- chM Chaîne chN Modifiée où les virgules et deux points ont été remplacés sauf dans les tables et objets imbriqués.
Via la fonction MAP on parcourt chN : soit le caractère d'origine est renvoyé soit c'est le caractère ASCII 30 ou 31, le tout assemblé avec une fonction CONCAT.- Vs : Une des valeurs de s (séquence).
- chG : Chaîne à Gauche du caractère évalué.
- tHTb : Booléen à VRAI si le caractère évalué est Hors Tableau (décompte des caractères différents de crochet dans chG).
- tHOb : Booléen à VRAI si le caractère évalué est Hors Objet (décompte des caractères différents d'accolade dans chG, plus complexe du à la présence de la première accolade ouvrante en début de chaîne).
- c : Le caractère évalué.
- ccc : Chaîne constituée du caractère précèdent le caractère évalué, du caractère évalué et du caractère suivant (gestion des effets de bord du au premier et dernier caractère évalué).
Les 2 fonctions SI permettent le choix entre conserver le caractère évalué ou prendre le caractère ASCII 30 ou 31.
- matFc : matrice des 3 cas de Fractionnement en colonnes.
- matFl : matrice des 2 cas de Fractionnement en lignes.
matFc et matFl permettent de supprimer les guillemets, accolades et crochets lors du fractionnement. - tabR : Tableau Résultats contenant tous les objets, clés et valeurs.
La fonction FRACTIONNER.TEXTE réalise le fractionnement en gérant le cas particulier si la dernière valeur est en format chaîne (le guillemet présent à la fin devra être supprimé). - derLigne : Nombre de lignes/objets de tabR.
- numObjetDebut2 : si NumObjetDebut est omis ou négatif ou du texte ou supérieur à derLigne on prend la valeur 1.
- numObjetFin2 : si NumObjetFin est omis ou négatif ou du texte ou inférieur à NumObjetFin ou supérieur à derLigne on prend la valeur derLigne.
- objR : Objets Résultat correspondant à la plage NumObjetDebut2 à NumObjetFin2.
Formule terminale de fonction LAMBDA :
S'il n'y a pas de recherche de clé on renvoie objR sinon les valeurs correspondantes à la recherche (avec BYROW, on crée le tableau des positions des valeurs à récupérer).
Merci pour votre attention bienveillante.
Un commentaire