Instructions de Boucle dans une Variable Dynamique (DynVar Loop Statement)
Sommaire
Introduction
Les Variables Dynamiques (DynVar) permettent de définir une valeur à partir d'une formule, contrairement aux variables de saisie pour lesquelles une valeur est fixée lors du remplissage d'un formulaire par exemple.
L'Instruction de Boucle (loop-statement) au sein d'une Variable Dynamique correspond à une syntaxe spécifique, à placer en première ligne de la formule d'une Variable Dynamique, et qui permet d'indiquer que, pour une variable de liste et une formule (SmartExpression) données, la formule doit être exécutée (calculée) autant de fois que d'éléments présents dans la liste.
Syntaxe
Il existe deux types d'instruction de boucle :
- "map" qui permet de produire une liste à partir d'une variable de liste existante (mapping), où chaque élément de la liste produite est le résultat d'une formule (une SmartExpression) ;
- "reduce" qui permet de produire une valeur simple (un nombre, une date, une chaîne de caractère…) à partir d'une variable de liste existante, sur laquelle aura été appliquée une formule (une SmartExpression) sur chacun de ses éléments en prenant compte du résultat de l'itération précédente. Le résultat du "reduce" correspond donc à la valeur résultante de la dernière itération de la boucle.
L'instruction de boucle possède une syntaxe spécifique présente dés la première ligne d'une formule de Variable Dynamique. Voir exemple de paramétrage via un tableau Excel :
Les instructions de boucle contiennent 3 parties paramétrables :
- Le type de fonction de boucle (#map ou #reduce)
- Les définitions des variables de boucle : sous la forme
LISTE as LIST_ITEM
, où LISTE est une variable de liste existante, et LIST_ITEM est un "alias" (nom arbitraire) utilisable seulement dans le corps de cette boucle, et qui aura pour valeur, tour à tour, chaque élément de la liste.
- La SmartExpression a executer en boucle
Les variables de contexte de la SmartExpression exécutée en boucle :
La SmartExpression qui est exécutée a chaque occurence de la boucle peut contenir les variables habituelles (celles du Datastore ainsi que les autres variables dynamiques), mais aussi certaines variables spéciales et contextuelle à la boucle :
_KEY
: la valeur de la clé pour l'itération courante ;_INDEX
: l'index de l'itération (respectivement 1, 2, 3…).
Notez que, même au sein d'une itération, il est aussi toujours possible de connaître la taille de la liste grâce à LISTE._COUNT
.
Le Mapping
Les instructions de boucle de type #map
permettent de produire une liste à partir d'une variable "list" existante, où chaque élément de la liste produite est le résultat de la SmartExpression fournie.
Ce type de boucle est principalement utilisée pour créer des listes de correspondance. Chaque entrée d'une liste étant constituée d'une clé et d'une valeur, le mapping va permettre de créer une nouvelle liste, pour laquelle les clés sont conservées mais les valeurs sont remplacées par le résultat de la SmartExpression fournie.
Définition de variables de la boucle : Dans le cadre d'une boucle #map
une seule définition de variable est attendue : la liste à parcourir vers l'élément de l'itération courante (l'alias).
Ex: ASSOCIES_LIST as ASSOCIE
, CHILDREN_LIST as CHILD_ITEM
etc …
Exemple de Variable Dynamique avec #map
Obtenir une liste PARTNERS_POURCENT_LIST
, où pour chaque associé d'une liste ASSOCIES, on va calculer le pourcentage de part qui revient à chacun d'eux, sur un total de 5000 parts :
#map list ASSOCIES as ASSOCIE_ITEM (ASSOCIE_ITEM.ACTIONS / 5000) * 100
Exemple d'usage de ce mapping dans un SmartDoc
Maintenant qu'on a généré une liste PARTNERS_POURCENT_LIST
, on va pouvoir utiliser ses valeurs "complexes" dans des contextes de boucle.
Par exemple, dans un document, on peut vouloir afficher pour chaque associé son nom et le pourcentage qu'il détient, sachant que ce pourcentage ne se trouve pas initialement dans la liste ASSOCIES
(complétée par une Slide répétée du formulaire) mais dans la liste PARTNERS_POURCENT_LIST
issue du mapping.
Exemple d'usage de ce mapping dans un SmartForm
Tout comme dans l'exemple précédent, on peut vouloir afficher un champ "Coucou", dans une slide répétée du SmartForm, uniquement si l'associé détient plus de 50% des parts. Le pourcentage détenu par l'associé ne se trouve malheureusement pas dans la liste ASSOCIES
mais dans la liste PARTNERS_POURCENT_LIST
issue du mapping (car ce sont des pourcentages calculées dynamiquement).
On va donc conditionner le champ avec la SmartExpression get_value(PARTNERS_POURCENT_LIST, ASSOCIES._KEY) > 50.0
, qui signifie : "Dans la liste PARTNERS_POURCENT_LIST, la valeur correspondante à la clé ASSOCIES._KEY est elle supérieure à 50 ?".
Reduce
Les instructions de boucle de type #reduce
permettent de produire une valeur simple (un nombre, une date, une chaîne de caractère…) à partir d'une liste existante, sur laquelle aura été appliquée une formule (la SmartExpression) sur chacun de ses éléments ;
Définition de variables de la boucle : Dans le cadre d'une boucle #reduce
, deux définitions de variable sont attendues : la liste à parcourir vers l'élément de l'itération courante (l'alias), et, la valeur initiale (ex: 0, true…) de la variable spéciale _PREV (qui a pour valeur le résultat de l'itération précédente et dont la dernière valeur sera celle de la Variable Dynamique).
Exemples de Variables Dynamiques avec #reduce
Obtenir une valeur booléenne IS_ANY_ASSOCIEE_NAMED_DAM
, qui vaut TRUE, si pour une liste d'ASSOCIES, au moins un des membres s'appelle "Damien" :
#reduce list ASSOCIES as ASSOCIE_ITEM, false as _PREV : _PREV or ASSOCIE_ITEM.PRENOM == "DAMIEN"
__
Obtenir une valeur booléenne IS_ALL_PARTNERS_TEN_POURCENT
, valant TRUE, si pour une liste d'ASSOCIES, tous les membres ont plus de 500 parts :
#reduce list ASSOCIES as ASSOCIE_ITEM, true as _PREV : _PREV and ASSOCIE_ITEM.ACTIONS > 500.0
__
Renvoie une variable numérique COUNT_PARTNERS_WITH_500_OR_MORE
donnant le nombre des associés qui ont au moins 500 parts :
#reduce list ASSOCIES as ASSOCIE_ITEM, 0 as _PREV : _PREV + (ASSOCIE_ITEM.ACTIONS > 500.0 ? 1 : 0)
__
Renvoie une variable numérique AVERAGE_PARTNERS_YEARS_OLD
, correspondant à la moyenne d'âge de tous les associés :
#reduce list ASSOCIES as ASSOCIE_ITEM, 0 as _PREV : _PREV + (ASSOCIE_ITEM.AGE / ASSOCIES._COUNT)
__
Renvoie la clé correspondante à l'associé qui est indiqué comme président (et false si aucun d'eux ne l'est) :
#reduce list ASSOCIES as ASSOCIE_ITEM, false as _PREV : ASSOCIE_ITEM.IS_PRESIDENT == true ? _KEY : _PREV