Scripting
Aperçu
Le scripting permet de calculer la valeur finale d'une question profil avec du code, au lieu d'une sélection manuelle.
Utilisez cette fonctionnalité lorsque vous avez besoin d'une logique avancée (par exemple : calcul de score, segmentation, libellés de statut, ou classification dynamique selon les réponses précédentes).
Prérequis
Pour utiliser le scripting, configurez votre question avec tous les éléments suivants :
- Type de question : Question profil
- Mode : Automatic
- Type du mode automatique : Scripting (
Compute a value with a script)
Quand cette configuration est activée, une zone de texte dédiée apparaît (de type éditeur) où vous pouvez écrire le script qui calcule la valeur finale du répondant.
Les scripts s'exécutent dans un bac à sable sécurisé, sans accès au système de fichiers, au réseau ou aux classes Java, et sont limités à 500 ms de temps d'exécution. Gardez vos scripts courts et évitez les calculs répétés pour rester largement sous cette limite.
Références aux réponses précédentes
Les variables suivent un format structuré selon le type de question :
[Référence question].[Référence élément].[Propriété]
Questions profil / adaptatives
| Variable | Description | Exemple de valeur |
|---|---|---|
Q1.ANSWER | Réponse(s) complète(s), séparées par une virgule | "Oui" ou "Option A,Option B" |
Q1.COUNT | Nombre de réponses sélectionnées | 1 ou 3 |
Q1.A001, Q1.A002, ... | Nième réponse sélectionnée (index à partir de 1) | "Option A" |
Batterie d'items
I1, I2, ... correspondent aux références des items dans la batterie.
| Variable | Description | Exemple de valeur |
|---|---|---|
Q2.I1.ANSWER | Réponse(s) de l'item I1 | "Satisfait" |
Q2.I1.COUNT | Nombre de réponses pour l'item I1 | 1 |
Q2.I1.A001 | Première réponse de l'item I1 | "Satisfait" |
Hotspot
Z1, Z2, ... correspondent aux références des zones dans le hotspot.
| Variable | Description | Exemple de valeur |
|---|---|---|
Q3.Z1.ANSWER | Réponse de la zone Z1 | "Sélectionné" |
Q3.Z1.COUNT | Nombre de réponses pour la zone Z1 | 1 ou 0 |
Questions ouvertes
F1, F2, ... correspondent aux références des champs dans la question ouverte.
| Variable | Description | Exemple de valeur |
|---|---|---|
Q4.F1.ANSWER | Réponse du champ F1 | "Jean Dupont" |
Q4.F2.ANSWER | Réponse du champ F2 | "jean@email.com" |
Questions R3M (3 mots / Expérience)
| Variable | Description | Exemple de valeur |
|---|---|---|
Q5.WORD1.ANSWER | Premier mot | "Innovation" |
Q5.WORD2.ANSWER | Deuxième mot | "Qualité" |
Q5.WORD3.ANSWER | Troisième mot | "Service" |
Réponses possibles
En plus des réponses données par le répondant, vous pouvez lire la liste des réponses possibles définies sur une question, une batterie ou un hotspot, c'est-à-dire les choix de réponse proposés au répondant. Le format est toujours :
[Référence question].[Référence réponse]
Cette notation n'a pas de niveau item ou zone : les réponses possibles sont communes à toute la question. On écrit donc Q2.A1 pour une batterie et Q3.A1 pour un hotspot, jamais Q2.I1.A1 ou Q3.Z1.A1.
Par exemple, avec la question suivante :
- Q1 : « Aimez-vous le Coca-Cola ? »
- A1 : Oui
- A2 : Non
| Variable | Description | Exemple de valeur |
|---|---|---|
Q1.A1 | Texte de la réponse possible A1 de la question Q1 | "Oui" |
Q1.A2 | Texte de la réponse possible A2 de la question Q1 | "Non" |
Q12.A4 | Texte de la réponse possible A4 de la question Q12 | - |
Q1.A1 // → "Oui"
Q1.A2 // → "Non"
// Vérifier si le répondant a choisi "Oui", sans écrire le libellé en dur
contains(split(getAnswer('Q1')), Q1.A1) // → true si A1 a été cochée
Ne confondez pas Q1.A1 et Q1.A001. Q1.A1 utilise la référence d'une réponse possible (A1) et retourne toujours son texte, que le répondant l'ait cochée ou non. Q1.A001 utilise un index sur trois chiffres (001) et retourne la première réponse effectivement cochée par le répondant.
Itérations de boucle
Quand une question est répétée dans une boucle, chaque itération expose son propre jeu de variables via la notation LOOPn (index à partir de 1, cohérent avec la numérotation des variables de remplacement) :
Q1.LOOP1.ANSWER // première itération
Q1.LOOP2.ANSWER // deuxième itération
Q1.LOOP3.ANSWER // troisième itération
Quand le script s'exécute lui-même dans une boucle, utilisez la variable CURRENT_LOOP_INDEX pour récupérer le numéro de l'itération courante (index à partir de 1, comme la notation LOOPn ci-dessus) :
var iterationCourante = CURRENT_LOOP_INDEX;
// CURRENT_LOOP_INDEX est un int, à convertir en texte
var iterationCourante = text(CURRENT_LOOP_INDEX);
CURRENT_LOOP_INDEX n'est disponible que si la question profil se trouve elle-même dans une boucle.
Fonctions d'accès aux données
Plutôt que de lire les variables brutes, utilisez les fonctions d'accès dédiées ci-dessous. Elles sont recommandées : plus lisibles, elles retournent null (ou 0 pour les comptages) en cas de réponse manquante ou de référence invalide, au lieu d'échouer.
| Type de question | Fonction | Équivalent à |
|---|---|---|
| Profil / adaptative | getAnswer(questionRef) | Q1.ANSWER |
| Profil / adaptative | getAnswerOrDefault(questionRef, default) | Q1.ANSWER, ou default si sans réponse |
| Profil / adaptative | getAnswer(questionRef, index) | Q1.A001 |
| Profil / adaptative | getAnswerCount(questionRef) | Q1.COUNT |
| Batterie | getItemAnswer(questionRef, itemRef) | Q2.I1.ANSWER |
| Batterie | getItemAnswer(questionRef, itemRef, index) | Q2.I1.A001 |
| Batterie | getItemAnswerCount(questionRef, itemRef) | Q2.I1.COUNT |
| Hotspot | getZoneAnswer(questionRef, zoneRef) | Q3.Z1.ANSWER |
| Hotspot | getZoneAnswer(questionRef, zoneRef, index) | - |
| Hotspot | getZoneAnswerCount(questionRef, zoneRef) | Q3.Z1.COUNT |
| Question ouverte | getFieldAnswer(questionRef, fieldRef) | Q4.F1.ANSWER |
| Question ouverte | getFieldAnswer(questionRef, fieldIndex) | Q4.F1.ANSWER (par position) |
| R3M (3 mots) | getWord1(questionRef) / getWord2(...) / getWord3(...) | Q5.WORD1.ANSWER, etc. |
| R3M (3 mots) | getWord(questionRef, wordRef) | Q5.WORD1.ANSWER |
getAnswer('Q1') // → "Oui"
getAnswerOrDefault('Q1', 'N/A') // → "Oui", ou "N/A" si Q1 est sans réponse
getAnswer('Q1', 1) // → "Option A"
getAnswerCount('Q1') // → 3
getItemAnswer('Q2', 'I1') // → "Satisfait"
getItemAnswerCount('Q2', 'I1') // → 2
getZoneAnswer('Q3', 'Z1') // → "Sélectionné"
getZoneAnswerCount('Q3', 'Z1') // → 1
getFieldAnswer('Q4', 'F1') // → "Jean Dupont"
getFieldAnswer('Q4', 1) // → "Jean Dupont"
getWord1('Q5') // → "Innovation"
getWord('Q5', 'WORD2') // → "Qualité"
Une référence invalide ou hors limites (par exemple getItemAnswer('Q2', 'I999')) retourne null plutôt que de générer une erreur. Vérifiez toujours la valeur null avant de l'utiliser dans une comparaison ou un calcul.
Vérifier l'existence d'une réponse
Utilisez ces fonctions pour vérifier qu'une réponse existe avant de la lire, en alternative à la comparaison du résultat de getAnswer(...) (et des autres fonctions d'accès) à null.
| Fonction | Description |
|---|---|
hasAnswered(ref) | Retourne true si ref a une réponse, c'est-à-dire si la variable ref.ANSWER existe |
exists(ref) | Retourne true si la variable exacte ref existe dans les données de réponse |
hasAnswered('Q1') // → true si Q1 a été répondu
hasAnswered('Q2.I1') // → true si l'item I1 de la batterie Q2 a été répondu
hasAnswered('Q3.Z1') // → true si la zone Z1 du hotspot Q3 a été répondue
exists('Q1.ANSWER') // → équivalent à hasAnswered('Q1')
exists('Q1.COUNT') // → true si la variable de comptage de Q1 existe
exists('Q1.A002') // → true si une deuxième réponse a été sélectionnée pour Q1
if (hasAnswered('Q1')) {
getAnswer('Q1');
} else {
'N/A';
}
hasAnswered(ref) est un raccourci pour exists(ref + '.ANSWER') et accepte n'importe quelle référence de question, d'item (Q2.I1), de zone (Q3.Z1) ou de champ (Q4.F1). exists(ref) est plus générique : elle vérifie n'importe laquelle des variables brutes décrites dans « Références aux réponses précédentes » ci-dessus (par exemple exists('Q1.A002') pour vérifier si une deuxième réponse a été sélectionnée).
hasAnswer(ref) fonctionne toujours mais est dépréciée — utilisez hasAnswered(ref) à la place.
Paramètres d'URL
Utilisez getQueryParameter(name) pour lire un paramètre de la chaîne de requête du lien d'enquête (par exemple un code de langue, un identifiant de panéliste, ou un paramètre de tracking ajouté à l'URL d'invitation).
| Fonction | Description | Équivalent à |
|---|---|---|
getQueryParameter(name) | Retourne la valeur du paramètre d'URL name, ou null s'il est absent | PARAM.<NAME> (<NAME> en majuscules), ex. PARAM.SOURCE pour getQueryParameter('source') |
var lang = getQueryParameter('lang');
// Pour un lien d'enquête tel que https://.../survey?lang=en → "en"
var lang = getQueryParameter('lang');
if (lang == 'en') {
'English';
} else if (lang == 'fr') {
'Français';
} else {
'N/A';
}
Quand le paramètre est absent de l'URL, getQueryParameter retourne null. Vérifiez toujours la valeur null avant de l'utiliser dans une comparaison ou une concaténation.
Variables du formulaire
Les variables définies au niveau global du formulaire (en dehors de toute question) sont accessibles directement par leur nom, ou via la fonction dédiée getFormVariable(index).
| Fonction | Description | Équivalent à |
|---|---|---|
getFormVariable(index) | Retourne la valeur de la variable de formulaire numéro index | VAR_1, VAR_2, ... |
var produit = VAR_1;
// équivalent, en utilisant la fonction d'accès :
var produit = getFormVariable(1);
Syntaxe de base de JexlScript
Le scripting est basé sur JexlScript. Si vous connaissez les structures de contrôle proches de JavaScript, vous reconnaîtrez rapidement la syntaxe.
Règles essentielles :
- Terminer chaque instruction par
; - Utiliser
varpour déclarer une variable - Utiliser
if (...) { ... }pour les conditions - Utiliser
else { ... }pour la logique alternative - Utiliser
==,!=,>,<,>=,<=,&&,||,!pour les comparaisons et tests logiques - Le résultat du script est la valeur de la dernière expression évaluée — un
returnexplicite n'est pas requis, maisreturn ...;est également pris en charge
Exemple de script
var genre = text(getAnswer('Q1'));
var age = integer(getAnswer('Q2'), 0);
var value = 'N/A';
if (genre == 'Homme' || genre == 'Femme') {
value = genre;
if (age > 45) {
value = value + ' - hors cible';
} else {
value = value + ' - dans la cible';
}
}
value
Ce que fait cet exemple :
- Lit le genre depuis
Q1en texte - Lit l'âge depuis
Q2en entier, avec0par défaut si la valeur est manquante ou invalide - Construit un libellé uniquement pour les valeurs de genre attendues
- Retourne
N/Asi aucune classification valide n'est possible
Fonctions de conversion
| Fonction | Alias français | Description |
|---|---|---|
number(value) | nombre(value) | Convertit une valeur en nombre décimal |
number(value, default) | nombre(value, default) | Idem, avec default utilisé si la conversion échoue |
integer(value) | entier(value) | Convertit une valeur en nombre entier (tronque les décimales) |
integer(value, default) | entier(value, default) | Idem, avec default utilisé si la conversion échoue |
text(value) | texte(value) | Convertit une valeur en texte |
isNumeric(text) | - | Retourne true si text peut être converti en nombre |
toNumbers(list) | - | Convertit une liste de valeurs textuelles en liste de nombres |
number('42') // → 42.0
number('abc', 0) // → 0 (valeur par défaut, 'abc' n'est pas un nombre)
integer('3.14') // → 3
text(42) // → "42"
isNumeric('42') // → true
isNumeric('abc') // → false
toNumbers(['1', '2', '3']) // → [1, 2, 3]
Fonctions mathématiques
| Fonction | Alias français | Description |
|---|---|---|
round(number) | arrondi(number) | Arrondit à l'entier le plus proche |
round(number, decimals) | - | Arrondit au nombre de décimales indiqué |
max(a, b) | - | Retourne le plus grand des deux nombres |
min(a, b) | - | Retourne le plus petit des deux nombres |
abs(number) | - | Retourne la valeur absolue |
modulo(a, b) | - | Retourne le reste de la division de a par b |
exp(number) | exponential(number) / exponentielle(number) | Calcule l'exponentielle (e^x) |
sum(list) | - | Retourne la somme d'une liste de nombres |
avg(list) | - | Retourne la moyenne d'une liste de nombres |
round(3.7) // → 4
round(3.14159, 2) // → 3.14
max(10, 20) // → 20
min(10, 20) // → 10
abs(-42) // → 42
modulo(10, 3) // → 1
exp(1) // → 2.718281828...
sum([10, 20, 30]) // → 60
avg([10, 20, 30]) // → 20
Fonctions de texte
| Fonction | Alias français | Description |
|---|---|---|
length(text) | longueur(text) | Retourne la longueur d'un texte |
trim(text) | - | Supprime les espaces en début et fin de texte |
isBlank(text) | - | Retourne true si text est vide ou ne contient que des espaces |
split(text) | - | Découpe text en liste, en utilisant , comme séparateur |
split(text, delimiter) | - | Découpe text en liste, en utilisant le séparateur delimiter |
toList(entry1, entry2, ...) | - | Construit une liste à partir des valeurs texte fournies (nombre d'arguments variable) |
join(list, separator) | - | Assemble les éléments de list en un seul texte, avec separator |
contains(list, value) | - | Retourne true si value fait partie des éléments de list |
containsAny(list, values) | - | Retourne true si list contient au moins un élément de values |
containsAll(list, values) | - | Retourne true si list contient tous les éléments de values |
count(list) | - | Retourne le nombre d'éléments de list |
length('Bonjour') // → 7
trim(' Bonjour ') // → "Bonjour"
isBlank(' ') // → true
isBlank('Bonjour') // → false
split('A,B,C') // → ["A", "B", "C"]
split('A;B;C', ';') // → ["A", "B", "C"]
toList('A', 'B', 'C') // → ["A", "B", "C"]
join(['A', 'B', 'C'], ';') // → "A;B;C"
contains(split('A,B,C'), 'B') // → true
containsAny(split('A,B,C'), ['B', 'Z']) // → true
containsAll(split('A,B,C'), ['A', 'B']) // → true
count(split('A,B,C')) // → 3
containsAny(split(getAnswer('Q1')), toList(Q1.A1, Q1.A2)) // → true si la réponse A1 ou A2 a été cochée en Q1
containsAll(split(getAnswer('Q1')), toList('A', 'B')) // → true si les options A et B ont toutes deux été cochées en Q1
split et contains sont utiles ensemble pour vérifier si une option précise a été sélectionnée dans une réponse à choix multiple, puisque getAnswer(...) retourne les valeurs sélectionnées sous forme d'un seul texte séparé par des virgules : contains(split(getAnswer('Q1')), 'Option A').
Fonctions de date et d'heure
Ces fonctions donnent accès à la date/heure courante, permettent d'extraire ou de reformater une date/heure provenant d'une réponse, d'ajouter ou de soustraire une durée à une date, une heure, ou une valeur de date/heure arbitraire, et de calculer l'écart entre deux dates ou deux heures.
Composants de la date/heure courante
| Fonction | Description | Exemple de valeur |
|---|---|---|
day() | Jour du mois courant | 17 |
month() | Mois courant (1-12) | 8 |
year() | Année courante | 2026 |
hour() | Heure courante (0-23) | 14 |
minute() | Minute courante | 32 |
second() | Seconde courante | 5 |
La date/heure courante est calculée en utilisant le fuseau horaire configuré dans la variable SYSTEM.TIMEZONE, ou le fuseau horaire par défaut du système s'il n'est pas configuré.
Extraire un composant d'une date/heure donnée
Utilisez ces variantes pour extraire un composant d'une date/heure provenant d'une réponse (par exemple une date de naissance collectée dans une question ouverte), plutôt que de la date/heure courante. value est analysée selon format, puis le composant demandé est retourné.
| Fonction | Description | Exemple |
|---|---|---|
day(value, format) | Jour du mois extrait de value | day('17/08/2026', 'dd/MM/yyyy') → 17 |
month(value, format) | Mois (1-12) extrait de value | month('17/08/2026', 'dd/MM/yyyy') → 8 |
year(value, format) | Année extraite de value | year('17/08/2026', 'dd/MM/yyyy') → 2026 |
hour(value, format) | Heure (0-23) extraite de value | hour('14:32:05', 'HH:mm:ss') → 14 |
minute(value, format) | Minute extraite de value | minute('14:32:05', 'HH:mm:ss') → 32 |
second(value, format) | Seconde extraite de value | second('14:32:05', 'HH:mm:ss') → 5 |
day('17/08/2026', 'dd/MM/yyyy') // → 17
month('17/08/2026', 'dd/MM/yyyy') // → 8
year('17/08/2026', 'dd/MM/yyyy') // → 2026
hour('14:32:05', 'HH:mm:ss') // → 14
minute('14:32:05', 'HH:mm:ss') // → 32
second('14:32:05', 'HH:mm:ss') // → 5
day, month et year attendent une value contenant une date ; hour, minute et second attendent une value contenant une heure. format doit correspondre exactement à value.
Date/heure courante sous forme de texte
| Fonction | Description | Exemple de valeur |
|---|---|---|
date() | Date courante, au format dd/MM/yyyy | "17/08/2026" |
date(format) | Date courante, avec un format personnalisé | date('yyyy-MM-dd') → "2026-08-17" |
time() | Heure courante, au format HH:mm:ss | "14:32:05" |
time(format) | Heure courante, avec un format personnalisé | time('HH:mm') → "14:32" |
L'argument format suit la syntaxe des patterns Java DateTimeFormatter. Les lettres les plus courantes sont d/M/y pour jour/mois/année et H/m/s pour heure/minute/seconde (par exemple dd/MM/yyyy, yyyy-MM-dd, HH:mm:ss).
Analyser et reformater une date/heure donnée
date(value, format) et time(value, format) analysent value selon format et la retournent formatée de la même façon. Comme l'entrée et la sortie utilisent le même pattern, ces fonctions servent surtout à valider qu'une réponse correspond bien au format attendu avant de l'utiliser ailleurs dans le script.
| Fonction | Description | Exemple |
|---|---|---|
date(value, format) | Analyse value comme une date selon format, la retourne formatée de la même façon | date('2026-08-17', 'yyyy-MM-dd') → "2026-08-17" |
time(value, format) | Analyse value comme une heure selon format, la retourne formatée de la même façon | time('14:32:05', 'HH:mm:ss') → "14:32:05" |
date('2026-08-17', 'yyyy-MM-dd') // → "2026-08-17"
time('14:32:05', 'HH:mm:ss') // → "14:32:05"
Ajouter une durée à la date/heure courante
Chaque fonction retourne la date (ou l'heure) courante décalée du montant indiqué, formatée en texte. L'argument format est optionnel et vaut par défaut dd/MM/yyyy pour les fonctions de date, HH:mm:ss pour les fonctions d'heure.
| Fonction | Description |
|---|---|
addDays(amount) / addDays(amount, format) | Date courante + amount jours |
addMonths(amount) / addMonths(amount, format) | Date courante + amount mois |
addYears(amount) / addYears(amount, format) | Date courante + amount années |
addHours(amount) / addHours(amount, format) | Heure courante + amount heures |
addMinutes(amount) / addMinutes(amount, format) | Heure courante + amount minutes |
addSeconds(amount) / addSeconds(amount, format) | Heure courante + amount secondes |
amount peut être négatif pour reculer dans le temps (par exemple addDays(-7) pour il y a une semaine).
addDays(7) // → dans une semaine, ex. "24/08/2026"
addDays(-30, 'yyyy-MM-dd') // → il y a 30 jours, ex. "2026-07-18"
addMonths(1) // → même jour le mois prochain
addYears(-18) // → 18 ans avant aujourd'hui (ex. un seuil de majorité)
addHours(2, 'HH:mm') // → heure courante + 2 heures, ex. "16:32"
Ajouter une durée à une date/heure arbitraire
add(value, format, amount, unit) analyse value selon format, ajoute amount de unit, puis retourne le résultat formaté de la même façon. Utilisez cette fonction pour décaler une date/heure provenant d'une réponse, plutôt que la date/heure courante.
formatdoit correspondre exactement àvalue(mêmes règles que pourdate()/time()) et peut décrire une date, une heure, ou les deux.unitaccepte (indépendamment de la casse) :DAYS,MONTHS,YEARS,HOURS,MINUTES,SECONDS.- La fonction génère une erreur si
valuene peut pas être analysée avecformat, ou siunitne s'applique pas à la valeur analysée (par exemple ajouter desHOURSà une valeur ne contenant qu'une date, sans partie horaire).
add('01/01/2026', 'dd/MM/yyyy', 3, 'MONTHS') // → "01/04/2026"
add('23:50:00', 'HH:mm:ss', 20, 'MINUTES') // → "00:10:00"
add('01/01/2026 23:00', 'dd/MM/yyyy HH:mm', 2, 'HOURS') // → "02/01/2026 01:00"
Passer une unité non reconnue (autre que DAYS, MONTHS, YEARS, HOURS, MINUTES, SECONDS) ou une value qui ne correspond pas à format arrête le script avec une erreur. Validez les valeurs issues de réponses ouvertes avant d'appeler add(...) sur celles-ci.
Écart entre deux dates ou deux heures
Ces fonctions retournent l'écart entre deux dates (ou deux heures), toutes deux analysées avec le même format, sous la forme d'un nombre entier dans l'unité indiquée.
| Fonction | Description | Exemple |
|---|---|---|
daysBetween(startDate, endDate, format) | Nombre de jours complets entre startDate et endDate | daysBetween('01/01/2026', '10/01/2026', 'dd/MM/yyyy') → 9 |
monthsBetween(startDate, endDate, format) | Nombre de mois complets entre startDate et endDate | monthsBetween('01/01/2026', '15/03/2026', 'dd/MM/yyyy') → 2 |
yearsBetween(startDate, endDate, format) | Nombre d'années complètes entre startDate et endDate | yearsBetween('15/03/2005', '17/08/2026', 'dd/MM/yyyy') → 21 |
hoursBetween(startHour, endHour, format) | Nombre d'heures complètes entre startHour et endHour | hoursBetween('08:00:00', '17:30:00', 'HH:mm:ss') → 9 |
minutesBetween(startHour, endHour, format) | Nombre de minutes complètes entre startHour et endHour | minutesBetween('08:00:00', '08:45:00', 'HH:mm:ss') → 45 |
secondsBetween(startHour, endHour, format) | Nombre de secondes complètes entre startHour et endHour | secondsBetween('08:00:00', '08:00:30', 'HH:mm:ss') → 30 |
daysBetween('01/01/2026', '10/01/2026', 'dd/MM/yyyy') // → 9
monthsBetween('01/01/2026', '15/03/2026', 'dd/MM/yyyy') // → 2
yearsBetween('15/03/2005', '17/08/2026', 'dd/MM/yyyy') // → 21
hoursBetween('08:00:00', '17:30:00', 'HH:mm:ss') // → 9
minutesBetween('08:00:00', '08:45:00', 'HH:mm:ss') // → 45
secondsBetween('08:00:00', '08:00:30', 'HH:mm:ss') // → 30
daysBetween, monthsBetween et yearsBetween attendent des valeurs de date ; hoursBetween, minutesBetween et secondsBetween attendent des valeurs d'heure. Les deux valeurs doivent utiliser le même format. Si endDate/endHour est antérieure à startDate/startHour, le résultat est négatif.
Toutes les fonctions documentées ci-dessus qui analysent une value selon un format (day(value, format), month(value, format), year(value, format), hour(value, format), minute(value, format), second(value, format), date(value, format), time(value, format), add(...), et les fonctions *Between) génèrent une erreur si la valeur ne peut pas être analysée avec le format indiqué. Validez ou vérifiez les valeurs issues de réponses ouvertes avant de les appeler.
Exemples supplémentaires
Score numérique avec arrondi
var scoreA = number(getItemAnswer('Q3', 'I1'));
var scoreB = number(getItemAnswer('Q3', 'I2'));
var total = scoreA + scoreB;
var moyenne = round(total / 2);
moyenne
Conserver la valeur la plus élevée parmi plusieurs entrées
var v1 = number(getAnswer('Q4'));
var v2 = number(getAnswer('Q5'));
var v3 = number(getAnswer('Q6'));
max(max(v1, v2), v3)
Score pondéré
var note1 = number(getAnswer('Q_NOTE1'), 0);
var note2 = number(getAnswer('Q_NOTE2'), 0);
var note3 = number(getAnswer('Q_NOTE3'), 0);
// Pondération : 50% note1, 30% note2, 20% note3
var score = (note1 * 0.5) + (note2 * 0.3) + (note3 * 0.2);
round(score)
Message selon un seuil
var score = number(getAnswer('Q_SCORE'), 0);
if (score >= 80) {
'Excellent - ' + text(score) + '%';
} else if (score >= 60) {
'Bien - ' + text(score) + '%';
} else {
'En dessous de l\'objectif - ' + text(score) + '%';
}
Concaténation de plusieurs champs
var prenom = getFieldAnswer('Q_IDENTITE', 'F1');
var nom = getFieldAnswer('Q_IDENTITE', 'F2');
var ville = getFieldAnswer('Q_IDENTITE', 'F3');
prenom + ' ' + nom + ', ' + ville
// → "Jean Dupont, Paris"
Vérification de majorité à partir d'une date de naissance
Utilisez yearsBetween pour calculer l'âge directement, plutôt que de comparer des dates formatées sous forme de texte :
var dateNaissance = getFieldAnswer('Q_DATENAISSANCE', 'F1'); // ex. "2005-03-15"
if (dateNaissance == null) {
'N/A';
} else {
var age = yearsBetween(dateNaissance, date('yyyy-MM-dd'), 'yyyy-MM-dd');
if (age >= 18) {
'Majeur';
} else {
'Mineur';
}
}
Règles et limitations
Autorisé :
- Conditions
if/else - Opérateurs de comparaison (
==,!=,<,>,<=,>=) - Opérateurs logiques (
&&,||,!) - Opérateurs arithmétiques (
+,-,*,/,%) - Variables locales (
var x = ...) - Appels de fonctions
- Concaténation de texte (
+) - Accès aux propriétés (
.) - Littéraux (tableaux, objets)
Non autorisé :
- Boucles
while/for - Lambdas / fonctions anonymes
- Création d'objets avec
new - Accès aux classes Java
- Import de bibliothèques
- Modification des variables globales
Les scripts sont limités à 500 ms de temps d'exécution et s'exécutent dans un bac à sable isolé, sans accès au système de fichiers ou au réseau. Seules les fonctions documentées et les variables de questions sont disponibles.
Bonnes pratiques
- Initialisez d'abord une valeur de repli par défaut (par exemple
"N/A") - Convertissez explicitement les valeurs (
text(...),number(...),integer(...)) avant toute comparaison, en utilisant la variante avec valeur par défaut pour vous protéger des réponses manquantes - Vérifiez la valeur
nullavant utilisation, en particulier avecgetItemAnswer,getZoneAnsweretgetFieldAnswer, qui retournentnullpour les références manquantes ou invalides - Utilisez
hasAnswered(ref)ouexists(ref)pour vérifier qu'une réponse existe avant de la lire, en alternative à une vérification denull - Stockez les calculs répétés dans une variable plutôt que de les recalculer dans chaque branche
- Gardez des scripts courts et lisibles pour rester sous la limite de 500 ms
- Testez les cas limites (réponses vides, valeurs inattendues, réponses manquantes)
- Vérifiez toujours que le script retourne une valeur dans chaque branche