ExpressionScript - Презентація
From LimeSurvey Manual
Вступ
LimeSurvey використовує Expression Script (Скрипт виразів), який дає змогу LimeSurvey підтримувати складніше розгалуження, оцінювання, перевірку та адаптацію тексту. Він замінює спосіб, у який LimeSurvey керує замінами, умовами та оцінюванням на серверній частині. Він також значно прискорює обробку, оскільки усуває більшість зчитувань з бази даних під час виконання. Expression Script розробив д-р Томас Вайт (TMSWhite).
Ключові визначення
- Вираз: усе, що взято у фігурні дужки:
- Якщо одразу після відкривної дужки або перед закривною фігурною дужкою немає пробілів.
- Вміст виразу обчислюється EM, тому він може містити математичні формули, функції, а також складну обробку рядків і дат.
- Адаптація тексту (Tailoring): іноді її називають «piping». Це процес умовної зміни тексту:
- Ви маєте доступ до всіх «полів заміни», даних учасника та даних відповідей.
- Ви також маєте простіший доступ до питань, відповідей та їхніх властивостей.
- Рівняння релевантності: новий атрибут питання, що керує видимістю питання:
- Якщо існує рівняння релевантності, питання показується лише тоді, коли релевантність має значення «істина».
- Внутрішньо всі команди array_filter та array_filter_exclude стають релевантністю на рівні підпитань.
- SGQA (як змінні називали раніше):
- Означає Survey-Group-Question-Answer (опитування-група-питання-відповідь)
- Імена змінних SGQA виглядають як 123X5X382X971 і можуть мати суфікси підпитань.
- Ці імена змінних прив'язані до кодів S/Q/G/A у базі даних, тому їх часто потрібно змінювати
- Рівняння (тип питання): новий тип питання, який зберігає обчислення або звіти в базі даних:
- Він подібний до питання типу «Текстовий блок», але його вміст зберігається в базі даних, навіть якщо вибрано «Завжди ховати це запитання».
- Код запитання: це бажане ім'я змінної для EM:
- Це може бути описова назва, що вказує на призначення питання, що полегшує читання складної логіки.
- Дійсні коди питань НЕ повинні починатися з цифри, тому для нумерації питань за допомогою коду просто використовуйте «q1», «q1a» або «g1q2».
- Саме це стає іменем змінної під час експорту даних до SPSS або R. Тому, якщо ви проводите статистичний аналіз, потрібно створювати лише унікальні коди питань.
Чи обов'язково мені використовувати Expression Script?
Коротка відповідь: «ні». Проте це значною мірою залежить від складності опитування, яке ви хочете створити.
Наприклад, редактор умов охоплює деякі базові вирази, які можна застосувати до питань вашого опитування. Однак редактор умов обмежений. Саме тому використовується Expression Script - він розширює сферу можливостей налаштування.
Чи можна поєднувати умови та рівняння релевантності?
Так. Ви можете використовувати редактор умов для одних питань і рівняння релевантності для інших.
Ви не можете одночасно налаштувати умови та вирази в одному питанні! Щойно умову налаштовано, вона замінює будь-який вираз, записаний у полі рівняння релевантності. Крім того, поле рівняння релевантності більше не можна редагувати вручну.
Однак є спосіб використати і вирази, і умови в межах одного питання. Як зазначено вище, умова замінює поле рівняння релевантності. Після цього перегляньте щойно створене рівняння та скопіюйте його в текстовий редактор. Видаліть щойно створену умову в редакторі умов, а потім відредагуйте питання, додавши вирази на основі умови з файлу текстового редактора разом з рештою виразів, які ви хочете використати.
Як вибрати між умовами та релевантністю?
Нижче наведено переваги та недоліки кожного підходу:
| Підхід | Переваги | Недоліки |
|---|---|---|
| Умови | 1. Зручний графічний інтерфейс для створення простих умов. 2. Графічний інтерфейс добре задокументований і зрозумілий службі підтримки |
1. Підтримує лише прості порівняння і погано працює з умовами «І» та «АБО». 2. Каскадні умови працюють непередбачувано 3. Повільно - інтенсивне використання бази даних - може уповільнювати довгі опитування. 4. Є повідомлення про проблеми з перезавантаженням умов. 5. Графічний інтерфейс погано масштабується, коли є десятки, сотні чи тисячі питань. 6. Перенесення паперових опитувань може бути повільним, оскільки потрібно використовувати імена SGQA. 7. Часто потрібен програміст, щоб написати код для складного розгалуження. |
| Релевантність | 1. Підтримує дуже складну логіку, зокрема понад 80 функцій та математичних/рядкових операторів. 2. Чудова підтримка каскадної логіки. 3. Швидко - без додаткових звернень до бази даних, підтримує опитування з понад 1000 питань. 4. Немає проблем із перезавантаженням логіки, оскільки коди SGQA не потрібні. 5. Підсвічування синтаксису масштабується на опитування з понад 1000 питань. 6. Простий і швидкий у використанні для груп, які хочуть автоматизувати наявні паперові опитування. 7. Легко підтримує напівструктуровані інтерв'ю та епідеміологічні опитування без залучення програміста. |
1. Немає графічного інтерфейсу для простих умов - натомість використовується підсвічування синтаксису. |
- Рекомендуємо використовувати те, що краще відповідає вашим потребам.
- Докладніше про можливості EM читайте за цим посиланням.
Початок роботи
Найкращий спосіб розпочати роботу з EM:
- Установіть останню стабільну версію з https://www.limesurvey.org/en/download.
- Імпортуйте та вивчіть кілька прикладів опитувань.
- Ознайомтеся з сценаріями використання та практичними посібниками, а також із покроковими прикладами.
- Ознайомтеся з документацією EM (ця сторінка)
- Модульні тести окремих виразів (для досвідчених)
- показують приклади використання всіх функцій та операторів EM, а також результати в PHP і JavaScript;
- зверніть увагу, що кілька функцій дають різні результати у версіях PHP і JavaScript, тому ця сторінка допоможе вам спланувати логіку EM відповідним чином.
- Модульні тести окремих виразів (для досвідчених)
Термінологія
Ці терміни зазвичай використовують для опису можливостей EM:
- Розгалуження на основі релевантності - якщо питання релевантне, його ставлять, інакше ні (наприклад, роблять невидимим і позначають як NULL у базі даних). Поля релевантності можна знайти на панелі редагування питання, а також на панелі редагування групи питань. Останнє використовується, щоб застосувати набір умов до цілої групи без копіювання тієї самої умови до кожного питання та/або поєднати логіку умов на рівні групи та питання).
- Адаптація тексту (Tailoring) - коли ви знаєте, які питання потрібно ставити, адаптація (іноді її називають piping) визначає, як саме питання має бути поставлене. Це дає змогу підтримувати не лише просту підстановку (як-от {TOKEN:FIRSTNAME}), а й відмінювання дієслів та іменників залежно від статі чи числа ваших респондентів. Вона також дає змогу змінювати повідомлення для респондента залежно від того, чи відповів він (або як відповів) на інші питання.
- Рівняння - EM додає новий тип питання під назвою Рівняння, який зберігає результат виразу. Результати рівнянь обчислюються й записуються в базу даних, навіть якщо ви приховуєте їх на сторінці. Тому їх використовують для прихованих обчислень балів, навігації на основі складних рівнянь, оцінювання та звітів, які будуть створені й збережені в базі даних.
Релевантність і каскадна релевантність
Кожен тип питання тепер має параметр релевантності, який визначає, чи відображається питання. EM обробляє кожне рівняння релевантності в тому порядку, в якому вони з'являються в опитуванні. Якщо вираз істинний (або відсутній - для підтримки застарілих опитувань), питання буде відображено. Якщо воно не релевантне, питання буде приховано, а значення в базі даних буде встановлено в NULL. Якщо в групі немає релевантних питань, вся група буде пропущена.
Крім того, якщо будь-яка зі змінних у виразі нерелевантна, вираз завжди повертає «хибність». Це забезпечує каскадну релевантність, тож вам не потрібно писати дуже довгі рівняння релевантності для кожного питання.
Припустімо, у вас є п'ять питань Q1-Q5, і ви хочете показувати Q2 лише якщо відповіли на Q1, Q3 - якщо відповіли на Q2 тощо. Рівняння релевантності можуть бути такими:
| Код питання | Релевантність | Питання |
|---|---|---|
| Q1 | 1 | Як вас звати? |
| Q2 | Q1 | {Q1}, скільки вам років? |
| Q3 | Q2 | Отже, вам {Q2} років. Ви одружені? |
| Q4 | Q3 == "Y" | {Q1}, як довго ви одружені? |
| Q5 | Q4 | Скільки у вас дітей, {Q1}? |
Релевантність на рівні групи
ExpressionScript також підтримує релевантність на рівні групи. Це полегшує реалізацію циклів. Припустімо, ви хочете зібрати інформацію щодо до 10 об'єктів (наприклад, продуктів або членів домогосподарства), де спочатку визначаєте, скількох об'єктів потрібно стосуватися уточнювальні питання (наприклад, запитавши, скільки людей живе в домогосподарстві, або попросивши відзначити, які продукти їм подобаються, з довгого списку). Дізнавшись, скількох об'єктів стосуватимуться уточнювальні питання, ви можете використати релевантність на рівні групи, як-от {count >= 1}, {count >=2}, ... {count >= 10} для кожної з 10 груп уточнювальних питань. У кожній групі можна мати умовну логіку на рівні питання (наприклад, уточнювальні питання залежно від статі чи віку для кожного об'єкта). Рівняння релевантності на рівні питання та групи поєднуються через «І», щоб визначити, що слід показати.
Щоб переглянути такий приклад, імпортуйте таке опитування: приклад опитування для перепису.
На знімку екрана нижче видно, що група Person 1 відображається (або є релевантною), якщо респондент проживає принаймні з ще одним співмешканцем:

Адаптація тексту/Piping
Усе, що знаходиться у фігурних дужках, тепер розглядається як вираз (за одним винятком, описаним нижче). Вирази мають доступ до всіх LimeReplacementFields і змінних (через кілька псевдонімів), до всіх типових операторів рівнянь (математичних, логічних і порівняння), а також до десятків функцій (які навіть працюють динамічно на стороні клієнта).
Використовуючи ці рівняння, ви можете, наприклад:
- Умовно показувати респондентам адаптовані повідомлення на основі попередніх відповідей;
- Створювати оцінювання та показувати його результати (або умовно розгалужувати опитування чи показувати повідомлення на основі цих результатів), не використовуючи сам модуль оцінювання;
- Відмінювати дієслова та іменники у питаннях, відповідях і звітах;
- Показувати підсумки відповідей перед сторінкою «Показати ваші відповіді» в кінці опитування.
Рівняння
Існує новий тип питання під назвою Рівняння. Розглядайте його як тип питання «Відображення тексту», з тією різницею, що він зберігає в базі даних значення того, що відображається. Тож якщо текст питання типу «Рівняння» містить обчислення оцінювання, це значення буде збережено в базі даних у змінній, яку можна відобразити в публічній або приватній статистиці.
Синтаксис
Усе, що міститься у фігурних дужках, тепер вважається виразом (за одним винятком: не повинно бути пробілів на початку та в кінці — це потрібно, щоб ExpressionScript не намагався обробляти вбудований JavaScript).
Зверніть увагу, що вирази можуть займати кілька рядків, якщо після відкривної фігурної дужки або перед закривною немає пробілів. Це особливо корисно для вкладених операторів «if()», як у цьому прикладі:
{if(is_empty(PFTotals),
'',
if(PFTotals >= -5 && PFTotals <= -4,
'Very Soft',
if(PFTotals >= -3 && PFTotals <= -2,
'Soft',
if(PFTotals == -1,
'Somewhat Soft',
if(PFTotals == 0,
'Moderate',
if(PFTotals == 1,
'Somewhat Hard',
if(PFTotals >= 2 && PFTotals <= 3,
'Hard',
if(PFTotals >= 4 && PFTotals <= 5,
'Very Hard',
''
)
)
)
)
)
)
)
)}
ExpressionScript підтримує такий синтаксис:
- Усі стандартні математичні оператори (напр. +,-,*,/,!);
- Усі стандартні оператори порівняння (напр. <,<=,==,!=,>,>=, а також їхні еквіваленти: lt, le, eq, ne, gt, ge);
- Круглі дужки (щоб групувати підвирази);
- Умовні оператори (напр. &&,| | та їхні еквіваленти: and, or);
- Рядки в одинарних і подвійних лапках (кожен з яких може містити вбудовані рядки з лапками іншого типу);
- Оператор «кома» (дозволяє мати список виразів і повертати лише фінальний результат);
- Оператор присвоєння (=);
- Попередньо визначені змінні (для посилання на питання, атрибути питань і відповіді) — напр. коди SGQA;
- Попередньо визначені функції (їх уже понад 80, і легко додати нові).
Оператори
Синтаксис EM дотримується звичайного пріоритету операторів:
| Рівень | Оператор(и) | Опис |
|---|---|---|
| 1 | () | круглі дужки для групування або виклику функцій |
| 2 | ! - + | унарні оператори: НЕ, заперечення, унарний плюс |
| 3 | * / | множення, ділення |
| 4 | + - | додавання, віднімання |
| 5 | < <= > >= lt le gt ge | порівняння «більше/менше» |
| 6 | == != eq ne | порівняння на рівність |
| 7 | and | логічне І |
| 8 | or | логічне АБО |
| 9 | = | оператор присвоєння |
| 10 | , | оператор «кома» |
Застереження щодо невідповідності числа й рядка та алфавітного/числового порівняння
Коли ви порівнюєте значення за допомогою операторів «більше/менше» або рівності, звертайте увагу на невідповідності типів. Значення, введене користувачем (або надане через код відповіді), можна використовувати як число, якщо це явно число.
Якщо взяти одне зі значень у ", відбудеться текстове/рядкове порівняння. Якщо ви хочете порівнювати як числа, ніколи не беріть число в ".
Наприклад, Q0.NAOK > "50" істинне, якщо Q0.NAOK — числове питання зі значенням 9. Це тому, що оператор > вважатиме порівняння алфавітним, а не числовим.
Щоб гарантувати порівняння цілих чисел, можна використати intval(Q0.NAOK) > 50. Пам’ятайте: якщо Q0.NAOK не є числом (порожнє значення або рядок), то intval(Q0.NAOK) === 0. Для порівняння рядків ("A" < "B") використовуйте безпосередньо strcmp: strcmp(Q0.NAOK,"B") або strcmp(Q0.NAOK,"A5").
Застереження щодо використання оператора присвоєння (=)
Уникайте використання операторів присвоєння, окрім випадків крайньої потреби, оскільки вони можуть спричинити неочікувані побічні ефекти. Наприклад, якщо змінити значення попередньої відповіді, каскадна релевантність і логіка перевірки між цим питанням і поточним не перераховуються, тож ви можете отримати внутрішньо суперечливі дані (наприклад, питання, які залишаються з відповіддю, але мали б бути обнулені, або питання, які пропущені, але мали б отримати відповідь). Загалом, якщо ви хочете присвоїти значення змінній, слід створити питання типу «Рівняння» і використати вираз для встановлення його значення. Однак іноді цей оператор справді потрібен, тому ми зробили його доступним.
Щоб застерегти вас щодо цього оператора, у рівняннях синтаксису він показаний червоним шрифтом (щоб ви не плутали його з «==»).
Використання оператора присвоєння
Основні причини, з яких вам може знадобитися оператор присвоєння:
- Потрібно встановити значення за умовчанням через рівняння для питання, яке не приймає значень за умовчанням (наприклад, список із перемикачами, де інтерфейс дозволяє вибрати один із варіантів відповіді, але не дозволяє ввести рівняння). Однак будьте обережні, адже LimeSurvey не зможе перевірити, чи ваше рівняння генерує одну з допустимих відповідей для цього питання;
- Потрібно примусово змінити відповідь на попереднє питання на основі пізнішої відповіді;
- тощо...
Для цієї мети можна використовувати всю систему Expression Manager. Краще використовувати для цього Рівняння.
Деякі приклади:
- Встановити відповідь на питання типу «Короткий текст» малими літерами :
{QCODE=strtolower(QCODE.NAOK)}; - Встановити відповідь за умовчанням для питання типу «масив» на початку опитування :
{Q1_SQ1=(is_empty(Q1_SQ1.NAOK),"A99",Q1_SQ1.NAOK)}; - Встановити відповідь за умовчанням для питання типу «масив текстів» на початку опитування :
{Q1_SQY1_SQX1 = (is_empty(Q1_SQY1_SQX1.NAOK),"Inserted answer", Q1_SQY1_SQX1.NAOK)}; - Встановити відповідь за умовою :
{QCODE=if(YesNo="Y","A1","")}.
Безпека XSS
Коли XSS увімкнено, деякі частини системи Expression Manager використовувати не можна:
- початок HTML-тегу у виразі, а його завершення в іншому виразі;
- використання складного виразу в URL.
Приклади та способи обходу:
{if( 1 ,"<strong>","")}information{if( 1 ,"</strong>","")}не працює при увімкненому XSS-захисті, тут можна використати{if(1,"<strong>information</strong>","information")};<a href="/script.php?value={if(QCODE == "Y","yes","no")}">next</a>, тут можна використати питання типу «Рівняння», оскільки використання повного коду питання допускається:<a href="/script.php?value={EQUATION.NAOK}">next</a>.
Доступ до змінних
ExpressionScript надає доступ лише для читання до будь-яких змінних, які вам можуть знадобитися. Для зворотної сумісності доступні такі змінні:
- TOKEN:xxx - значення токена (наприклад, TOKEN:FIRSTNAME, TOKEN:ATTRIBUTE_5) (лише для неанонімних опитувань, див. анонімне опитування).
- Усі значення {XXX}, що використовуються шаблонами.
- У тексті питання можна використовувати {QID}, що замінюється на ідентифікатор питання, та {SGQ}, що замінюється на SGQA питання.
- {SAVEDID} для ID поточної відповіді
Крім того, ExpressionScript дозволяє посилатися на змінні за кодом запитання (стовпець 'title' у таблиці питань у базі даних). Це також мітка змінної, яка використовується під час експорту даних до SPSS, R або SAS. Наприклад, якщо у вас є питання про ім'я, вік і стать, ви можете назвати ці змінні name, age і gender замість 12345X13X22, 12345X13X23 і 12345X13X24. Це полегшує читання рівнянь і перевірку логіки для кожного, а також дає змогу переставляти питання місцями без необхідності стежити за номерами груп чи питань.
Важливо: безпечніше посилатися на змінні, що містяться на попередніх сторінках або в попередніх питаннях.
Крім того, ExpressionScript дозволяє отримати доступ до багатьох властивостей питання:
| Синтаксис | Значення | Приклад | Результат прикладу |
|---|---|---|---|
| Qcode | псевдонім для Qcode.code | {implode(',',name,gender)} | 'Tom','M' |
| Qcode.code | вибраний код відповіді на питання, якщо воно релевантне (інакше порожньо), або текстове значення, якщо питання не має кодованих відповідей | {implode(',',name.code,gender.code)} | 'Tom','M' |
| Qcode.NAOK | те саме, що й Qcode - див. обговорення NAOK | {gender.NAOK} | 'M' |
| Qcode.value | значення оцінки для питання, якщо воно релевантне (інакше порожньо), або текстове значення, якщо питання не має кодованих відповідей | {gender.value} | '1' |
| Qcode.valueNAOK | те саме, що й Qcode.value - див. обговорення NAOK | {gender.valueNAOK} | '1' |
| Qcode.shown | відображуване значення для питання | {implode(',',name.shown,gender.shown)} | 'Tom','Male' |
| Qcode.question | текст питання | {gender.question} | 'What is your gender?' |
| Qcode.mandatory | чи є питання обов'язковим (Y/N) | {gender.mandatory} | 'N' |
| Qcode.qid | внутрішній номер питання (не порядковий номер) | {gender.qid} | 337 |
| Qcode.type | тип питання | {gender.type} | 'G' |
| Qcode.jsName | правильна назва питання в javascript, незалежно від того, оголошене воно на цій сторінці чи ні | {gender.jsName} | 'java1827X3X337' |
| Qcode.gid | внутрішній номер групи (не порядковий номер) | {gender.gid} | 3 |
| Qcode.qseq | порядковий номер питання, починаючи з 0 | {gender.qseq} | 5 |
| Qcode.gseq | порядковий номер групи, починаючи з 0 | {gender.gseq} | 1 |
| Qcode.relevanceStatus | чи є питання наразі релевантним (0 або 1) | {gender.relevanceStatus} | 1 |
| Qcode.relevance | рівняння релевантності на рівні питання | {gender.relevance} | '!is_empty(name)' |
| Qcode.grelevance | рівняння релевантності на рівні групи | {gender.grelevance} | 'num_children >= 5' |
| Qcode.sgqa | значення SGQA для цього питання | {gender.sgqa} | '1827X3X337' |
Проблема з HTML редактором
Якщо ви використовуєте HTML редактор, деякі символи замінюються на HTML-сутності.
- & на &
- < на <
- > на >
Якщо ви використовуєте HTML редактор, потрібно використовувати:
- and замість &
- lt замість <
- le замість <=
- gt замість >
- ge замість >=
Рекомендується очищати вираз від HTML-коду, що з'являється всередині виразу. Якщо ви використовуєте HTML редактор LimeSurvey, натисніть кнопку «Джерело» (у верхній лівій частині редактора) та видаліть усі символи, не пов'язані з вашим виразом (наприклад,
,
тощо).
Іменування змінних Qcode
Нижче наведено подробиці того, як формувати Qcode (і отримувати доступ до деяких властивостей) залежно від типу питання. Загалом Qcode формуються так:
QuestionCode . '_' . SubQuestionID . '_' . ScaleId
Для коментаря та іншого відповідні коди питань мають вигляд QuestionCode_comment та QuestionCode_other.
| Тип | Опис | Код | Підпитання | Варіанти відповідей | Шкали | Код відповіді | Показана відповідь | Релевантність |
|---|---|---|---|---|---|---|---|---|
| 5 | Вибір із 5 варіантів, радіокнопки | Q1 | 1-5 | {Q1} | {Q1.shown} | {Q1==3} | ||
| B | Масив (вибір із 10 пунктів), радіокнопки | Q2 | L1-L6 | 1-10 | {Q2_L2} | {Q2_L2.shown} | {Q2_L2==7} | |
| A | Масив (вибір із 5 пунктів), радіокнопки | Q3 | 1-5 | 1-5 | {Q3_1} | {Q3_1.shown} | {Q3_1>=3} | |
| 1 | Масив (гнучкі мітки), подвійна шкала | Q4 | sq1-sq5 | 0:a1-a3 | 1:b1-b3 | {Q4_sq1_0} | {Q4_sq1_1.shown} | {Q4_sq1_1=='b2'} |
| H | Масив (гнучкий) - формат стовпців | Q5 | 1-5 | s,m,t | {Q5_1} | {Q5_1.shown} | {Q5_1=='s'} | |
| F | Масив (гнучкий) - формат рядків | Q6 | F1-F5 | 1-5 | {Q6_F3} | {Q6_F3.shown} | {Q6_F3==4} | |
| E | Табличне запитання (Підвищення/Той самий рівень/Зниження), радіокнопки | Q7 | 1-7 | I,S,D | {Q7_4} | {Q7_4.shown} | {Q7_4=='D'} | |
| : | Масив (множинні гнучкі) від 1 до 10 | Q8 | ls1,todo,ls2 | min,max,avg | {Q8_ls1_max} | {Q8_ls2_avg.shown} | {Q8_ls2_min==7} | |
| ; | Масив (множинні гнучкі) текст | Q9 | hp,st,sw | 1st,2nd,3rd | {Q9_hp_3rd} | {Q9_hp_3rd.shown} | {Q9_hp_3rd=='Peter'} | |
| C | Масив (Так/Невизначено/Ні), радіокнопки | Q10 | 1-5 | Y,N,U | {Q10_1} | {Q10_1.shown} | {Q10_3=='Y'} | |
| X | Питання-заготовка (Boilerplate) | Q11 | {Q11.shown} | |||||
| D | Дата | Q12 | {Q12} | {Q12.shown} | ||||
| * | Рівняння | Q13 | {Q13} | {Q13.shown} | {Q13>5} | |||
| ~124~ | Завантаження файлу (записує кількість завантажених файлів) | Q14 | {Q14} | {Q14>0} | ||||
| G | Список «Стать», що розкривається | Q15 | M,F | {Q15} | {Q15.shown} | {Q15=='M'} | ||
| U | Величезний довільний текст | Q16 | {Q16} | {Q16.shown} | {strlen(Q16)>100} | |||
| I | Питання «Мова» | Q17 | {Q17} | {Q17.shown} | {Q17=='en'} | |||
| ! | Список - випадаючий | Q18 | 1-5 | {Q18} | {Q18.shown} | {Q18==3} | ||
| L | Список, що розкривається/радіокнопки | Q19 | A-Z | {Q19} | {Q19.shown} | {Q19=='X'} | ||
| O | Список з коментарями, що розкривається/радіокнопки + текстова область | Q20 | A-F | {Q20},{Q20comment} | {Q20.shown} | {Q20=='B'} | ||
| T | Довгий довільний текст | Q21 | {Q21} | {Q21.shown} | {strstr(Q21,'hello')>0} | |||
| M | Множинний вибір, прапорці | Q22 | A-F, other | {Q22_E}, {Q22_other} | {Q22_E.shown}, {Q22_other.shown} | {Q22_E=='Y'} | ||
| P | Множинний вибір з коментарями, прапорець + текст | Q23 | A-F | {Q23_D}, {Q23_Dcomment} | {Q23_D.shown} | {!is_empty(Q23)} | ||
| K | Множинне числове питання | Q24 | self,mom,dad | {Q24_self} | {Q24_self.shown} | {Q24_self>30} | ||
| Q | Кілька коротких текстів | Q25 | A-F | {Q25_B} | {Q25_B.shown} | {substr(Q25_B,1,1)=='Q'} | ||
| N | Числове питання | Q26 | {Q26} | {Q26.shown} | {Q26 > 30} | |||
| R | Рейтинг | Q27 | 1-4 | {Q27_1} | {Q27_1.shown} | {Q27_1==3} | ||
| S | Короткий довільний текст | Q28 | {Q28} | {Q28.shown} | {Q28=='mine'} | |||
| Y | Так/Ні, радіокнопки | Q29 | {Q29} | {Q29.shown} | {Q29=='Y'} |
Використання NAOK
NAOK --> «Не застосовується» (NA) допустимо (OK)
Використання NAOK означає, що всі або деякі змінні нерелевантні (тобто «Не застосовується» (NA) допустимо (OK)).
Наприклад: count(Q1_SQ1,Q1_SQ2,Q1_SQ3,Q1_SQ4) завжди повертає порожній рядок, якщо одне з підпитань Q1 відфільтроване. Щоб підрахувати кількість позначених підпитань у такому питанні, можна використати count(Q1_SQ1.NAOK,Q1_SQ2.NAOK,Q1_SQ3.NAOK,Q1_SQ4.NAOK). Якщо підпитання приховане, EM повертає порожній рядок.
Без NAOK, якщо одне питання або одне підпитання приховане, EM завжди повертає порожній рядок (що рівнозначно поверненню false).
Суфікс .shown завжди використовує систему NAOK (порожній рядок, якщо приховано), але якщо вам потрібен код відповіді, завжди варто додавати .NAOK після коду питання (за винятком випадків, коли він вам потрібен і ви розумієте, що робите).
Додаткову інформацію наведено в підрозділі «Перевизначення каскадних умов».
Зарезервовані змінні «this», «self» та «that»
Досить часто потрібно оцінити всі частини питання, наприклад, підрахувати, скільки підпитань отримали відповідь, або підсумувати бали. В інших випадках потрібно обробити лише певні рядки чи стовпці питання (наприклад, отримати суми по рядках чи стовпцях і зберегти їх у базі даних). Ці зарезервовані змінні роблять цей процес відносно простим.
Змінна «this»
Змінна «this» використовується виключно в опціях «Рівняння перевірки питання» та «Рівняння для перевірки додаткового запитання» (остання недоступна з графічного інтерфейсу). Вона розгортається в імена змінних кожної з комірок цих питань. Отже, якщо ви хочете переконатися, що кожне значення більше трьох, слід встановити для «Рівняння для перевірки додаткового запитання» значення (this > 3).
Змінна «self»
Змінні «self» та «that» є потужнішими й слугують макросами, які розгортаються перед обробкою рівнянь. Варіанти синтаксису для змінної «self»:
- self
- self.суфікс
- self.підселектор
- self.підселектор.суфікс
- suffix — це будь-який зі звичайних суфіксів qcode (наприклад, NAOK, value, shown)
- sub-selector може бути одним із таких:
- comments - лише підпитання, які є коментарями (наприклад, множинний вибір з коментарями та список з коментарями);
- nocomments - лише підпитання, які не є коментарями;
- sq_X - де X — ідентифікатор рядка або стовпця. Вибираються лише підпитання, що відповідають шаблону X. Зверніть увагу: пошук виконується за повним ідентифікатором коду, тому sq_X збігається з підпитаннями nX, X, Xn і включає їх (наприклад, якщо ви використовуєте sq_1, будуть включені підпитання a1, 1a, 1, 11 або 001). Будьте уважні з типом питання з подвійною шкалою, де коди підпитань мають вигляд QCODE_SQCODE_1 і QCODE_SQCODE_1, та з типом питання «рейтинг», де коди підпитань мають вигляд QCODE_1, QCODE_2 ....
Приклади:
- Чи була дана відповідь на якусь частину питання? -> {count(self.NAOK)>0}
- Яка оцінка за це питання? -> {sum(self.value)}
Ви також можете використовувати їх для отримання підсумків за рядками та стовпцями. Припустімо, у вас є масив чисел із рядками A-E і стовпцями 1-5.
- Який загальний підсумок? -> {sum(self.NAOK)}
- Яка сума в рядку B? -> {sum(self.sq_B.NAOK)}
- Яка сума в стовпці 3? -> {sum(self.sq_3.NAOK)}
Змінна "that"
Змінна "that" подібна до змінної "self", але дає змогу посилатися на інші питання. Її синтаксис:
- that.qname
- that.qname.suffix
- that.qname.sub-selector
- that.qname.sub-selector.suffix
qname — це назва питання без жодних розширень підпитань. Отже, створімо питання 'q1', де 'q' також представляє його qname.
Приклади:
- Чи була дана відповідь на якусь частину питання q1? -> {count(that.q1.NAOK)>0}
- Яка оцінка за питання q2? -> {sum(that.q2.NAOK)}
- Який загальний підсумок для q3? -> {sum(that.q3.NAOK)}
- Яка сума в рядку C питання q4? -> {sum(that.q4.sq_C.NAOK)}
- Яка сума в стовпці 2 питання q4? -> {sum(that.q4.sq_2.NAOK)}
Змінні "self" і "that" можна використовувати в будь-якій релевантності, перевірці або персоналізації.
Єдине застереження: коли ви використовуєте функцію Show logic file, вона показуватиме розгорнуте значення "self" і "that". Це дає змогу побачити фактичне рівняння, яке буде згенеровано, щоб ви (і EM) могли перевірити, чи існують змінні. Це може збивати з пантелику, оскільки ви можете побачити досить довгі рівняння. Проте, якщо ви відредагуєте питання, то побачите початкове рівняння з використанням "self" та/або "that".
- хочете явно називати кожну змінну, використану в рівнянні, або
- використовуєте змінні, які не мають підпитань (наприклад, питання з однією відповіддю). У таких випадках додавати до змінної префікс "that" надмірно, і ви ризикуєте отримати неочікувані результати.
Доступ до функцій
ExpressionScript надає доступ до математичних, рядкових і користувацьких функцій, як показано нижче. Для цих функцій є еквіваленти в PHP та JavaScript, тому вони працюють однаково на стороні сервера (PHP) і на стороні клієнта (JavaScript). Додавати нові функції легко.
Реалізовані функції
Наразі доступні такі функції:
| Функція | Значення | Синтаксис |
|---|---|---|
| abs | Абсолютна величина | number abs(number) |
| acos | Арккосинус | number acos(number) |
| addslashes | Екранувати рядок за допомогою зворотних скісних рисок | string addslashes(string) |
| asin | Арксинус | number asin(number) |
| atan | Арктангенс | number atan(number) |
| atan2 | Арктангенс двох змінних | number atan2(number, number) |
| ceil | Округлити дроби вгору | number ceil(number) |
| checkdate | Повертає true(1), якщо це допустима дата за григоріанським календарем | bool checkdate(month,day,year) |
| convert_value | Перетворити числове значення за допомогою вхідної та вихідної таблиць числових значень | number convert_value(fValue, iStrict, sTranslateFromList, sTranslateToList) |
| cos | Косинус | number cos(number) |
| count | Підрахувати кількість питань у списку, на які є відповідь (непорожніх) | number count(arg1, arg12, ..., argN) |
| countif | Підрахувати кількість питань у списку з відповідями, що дорівнюють першому аргументу | number countif(matches, arg1, arg2, ... argN) |
| countifop | Підрахувати кількість питань у списку з відповідями, які відповідають критерію (arg op value) | number countifop(op, value, arg1, arg2, ... argN) |
| date | Форматувати місцеву дату / час | string date(format [, timestamp=time()]) |
| exp | Розрахувати експоненту e | number exp(number) |
| fixnum | Відображати числа з комою як роздільником дробової частини, якщо потрібно | string fixnum(number) |
| floor | Округлити дроби вниз | number floor(number) |
| gmdate | Форматувати дату / час GMT | string gmdate(format [, timestamp=time()]) |
| html_entity_decode | Перетворити всі HTML-сутності на відповідні символи (завжди використовує ENT_QUOTES та UTF-8) | string html_entity_decode(string) |
| htmlentities | Перетворити всі відповідні символи на HTML-сутності (завжди використовує ENT_QUOTES та UTF-8) | string htmlentities(string) |
| expr_mgr_htmlspecialchars | Перетворити спеціальні символи на HTML-сутності (завжди використовує ENT_QUOTES та UTF-8) | string htmlspecialchars(string) |
| expr_mgr_htmlspecialchars_decode | Перетворити спеціальні HTML-сутності назад на символи (завжди використовує ENT_QUOTES та UTF-8) | string htmlspecialchars_decode(string) |
| idate | Форматувати місцевий час / дату як ціле число | string idate(string [, timestamp=time()]) |
| if | if у стилі Excel: if(test,result_if_true,result_if_false) | if(test,result_if_true,result_if_false) |
| implode | З'єднати елементи масиву в рядок | string implode(glue,arg1,arg2,...,argN) |
| intval | Отримати значення ціллого числа змінної | int intval(number [, base=10]) |
| is_empty | Визначити, чи вважається змінна порожньою | bool is_empty(var) |
| is_float | Дізнатися чи тип змінної є числом з плаваючою комою | bool is_float(var) |
| is_int | Дізнатися чи тип змінної є цілим числом | bool is_int(var) |
| is_nan | Дізнатися чи значення не є числом | bool is_nan(var) |
| is_null | Дізнатися чи змінна є порожньою (нульовою) | bool is_null(var) |
| is_numeric | Дізнатися чи змінна є числом або числовим рядком | bool is_numeric(var) |
| is_string | Дізнатися чи тип змінної є рядком | bool is_string(var) |
| join (New in 2.0 build 130129) | З'єднати елементи в новий рядок | join(arg1, arg2, ... argN) |
| list | Повернути список непорожніх значень, розділених комами | string list(arg1, arg2, ... argN) |
| listifop (New in 3.16.1 ) | Повернути список вказаної властивості питання (retProp), розділений роздільником 'glue', для питань зі списку, які відповідають критерію (cmpProp op value) | string listifop(cmpProp, op, value, retProp, glue, sgqa1, sgqa2, ... sgqaN) |
| ltrim | Видалити пропуски (або інші символи) на початку рядка | string ltrim(string [, charlist]) |
| max | Знайти найбільше значення | number max(arg1, arg2, ... argN) |
| min | Знайти найменше значення | number min(arg1, arg2, ... argN) |
| mktime | Отримати штамп часу UNIX для дати (кожен із 6 аргументів необов'язковий) | number mktime([hour [, minute [, second [, month [, day [, year ]]]]]]) |
| modulo-function | Функція модуля ще не підтримується. Натомість можна використати функцію floor() | floor(x/y)==(x/y) |
| nl2br | Вставляє HTML-розриви рядків перед усіма символами нового рядка в рядку | string nl2br(string) |
| number_format | Форматувати число до тисячних | string number_format(number) |
| pi | Отримати значення числа Пі | number pi() |
| pow | Експоненціальний вираз | number pow(base, exp) |
| quoted_printable_decode | Перетворити рядок quoted-printable на 8-бітний рядок | string quoted_printable_decode(string) |
| quoted_printable_encode | Перетворити 8-бітний рядок на рядок quoted-printable | string quoted_printable_encode(string) |
| quotemeta | Поставити лапки для метасимволів | string quotemeta(string) |
| rand | Згенерувати випадкове ціле число, див. цей приклад | int rand() OR int rand(min, max) |
| regexMatch | порівняти рядок із регулярним виразом | bool regexMatch(pattern,input) |
| round | Округлення числа до додаткової точності | number round(val [, precision]) |
| rtrim | Видалити пропуски (або інші символи) в кінці рядка | string rtrim(string [, charlist]) |
| sin | Синус | number sin(arg) |
| sprintf | Повернути відформатований рядок | string sprintf(format, arg1, arg2, ... argN) |
| sqrt | Квадратний корінь | number sqrt(arg) |
| stddev | Обчислити вибіркове стандартне відхилення для списку чисел | number stddev(arg1, arg2, ... argN) |
| str_pad | Доповнити рядок іншим рядком до заданої довжини | string str_pad(input, pad_length [, pad_string]) |
| str_repeat | Повторити рядок | string str_repeat(input, multiplier) |
| str_replace | Замінити всі входження шуканого рядка рядком заміни | string str_replace(search, replace, subject) |
| strcasecmp | Бінарне безпечне порівняння рядків без урахування регістру | int strcasecmp(str1, str2) |
| strcmp | Бінарне безпечне порівняння рядків | int strcmp(str1, str2) |
| strip_tags | Зняти HTML та PHP теги з рядка | string strip_tags(str, allowable_tags) |
| stripos | Знайти позицію першого входження рядка Unicode без урахування регістру (відлік починається з 0, повертає false, якщо не знайдено) | int stripos(haystack, needle [, offset=0]) |
| stripslashes | Зняти лапки рядка з лапками | string stripslashes(string) |
| stristr | Без урахування регістру strstr (Case-insensitive strstr) | string stristr(haystack, needle [, before_needle=false]) |
| strlen | Отримати довжину рядка | int strlen(string) |
| strpos | Знайти позицію першого входження рядка Unicode (відлік починається з 0, повертає false, якщо не знайдено) | int strpos(haystack, needle [ offset=0]) |
| strrev | Перевернути рядок | string strrev(string) |
| strstr | Знайти перший випадок рядка | string strstr(haystack, needle[, before_needle=false]) |
| strtolower | Перетворити рядок на нижній регістр | string strtolower(string) |
| strtotime | Перетворити майже будь-який англійський текстовий опис дати й часу на штамп часу Unix | int strtotime(string) |
| strtoupper | Перетворити рядок на верхній регістр | string strtoupper(string) |
| substr | Повернути частину рядка Unicode | string substr(string, start [, length]) |
| sum | Обчислити суму значень масиву | number sum(arg1, arg2, ... argN) |
| sumifop | Підсумувати значення питань у списку з відповідями, які відповідають критерію (arg op value) | number sumifop(op, value, arg1, arg2, ... argN) |
| tan | Тангенс | number tan(arg) |
| time | Повертати поточний штамп дати/часу UNIX | number time() |
| trim | Видалити пропуски (або інші символи) на початку й в кінці рядка | string trim(string [, charlist]) |
| ucwords | Перетворити перший символ кожного слова в рядку на верхній регістр | string ucwords(string) |
| unique | Повертати істину, якщо усі непорожні відповіді є унікальними | boolean unique(arg1, ..., argN) |
<span id="Create_new_expression_functions_with_plugin_ (New in 4.0.0 )">
Створення нових функцій виразів за допомогою плагіна (New in 4.0.0 )
Якщо вам потрібна нова функція, якої немає в ядрі, ви можете створити її за допомогою плагіна. Така нова функція створюється за допомогою події expressionManagerStart.
ExpressionScript знає, які змінні є локальними
Щоб правильно сформувати JavaScript для сторінки, EM має знати, які змінні задано на цій сторінці та який у них JavaScript ID (наприклад, для document.getElementById(x)). Він також має знати, які змінні задано на інших сторінках (щоб гарантувати, що потрібні поля <input type='hidden' value='x'> присутні та заповнені).
Каскадні умови
Якщо будь-яка зі змінних нерелевантна, усе рівняння буде нерелевантним (false). Наприклад, у наведеній нижче таблиці N/A означає, що одна зі змінних не була релевантною:
| Оператор | Приклад | a | b | Результат |
|---|---|---|---|---|
| + (unary) | +a | N/A | false | |
| ! | !a | N/A | false | |
| == (or eq) | a == b | N/A | 5 | false |
| == (or eq) | a == b | N/A | 0 | false |
| == (or eq) | a == b | N/A | N/A | false |
| != (or ne) | a != b | N/A | 5 | false |
| != (or ne) | a != b | N/A | N/A | false |
| != (or ne) | a != b | N/A | 0 | false |
| > (or gt) | a > b | N/A | 5 | false |
| >= (or ge) | a >= b | N/A | 5 | false |
| < (or lt) | a < b | N/A | 5 | false |
| <= (or le) | a <= b | N/A | 5 | false |
| and | a and b | N/A | 5 | false |
| and | a and b | N/A | N/A | false |
| or | a or b | N/A | N/A | false |
| or | a or b | N/A | 5 | false |
| + | a + b | N/A | 5 | false |
| * | a * b | N/A | 5 | false |
| / | a / b | 5 | N/A | false |
| () | (a) | N/A | false | |
| (exp) | (a && b) | N/A | 5 | false |
| (exp) op (exp) | (b + b) > (a && b) | N/A | 5 | false |
| function | sum(a,b,b) | N/A | 5 | false |
| function | max(a,b) | N/A | 5 | false |
| function | min(a,b) | N/A | 5 | false |
| function | implode(', ',a,b,a,b) | N/A | 5 | false |
| function | if(a,a,b) | N/A | 5 | false |
| function | is_empty(a) | N/A | false | |
| function | is_empty(a) | 0 (or blank) | true | |
| function | !is_empty(a) | N/A | false |
Перевизначення каскадних умов
Припустімо, ви хочете показати поточну суму всіх релевантних відповідей. Ви можете спробувати використати рівняння {sum(q1,q2,q3,...,qN)}. Однак внутрішньо воно перетворюється на LEMif(LEManyNA("q1","q2","q3",...,"qN"),"",sum(LEMval("q1"),LEMval("q2"),LEMval("q3"),...,LEMval("qN"))). Тож якщо будь-яке зі значень q1-qN нерелевантне, рівняння завжди повертатиме false. У цьому випадку sum() показуватиме "0", доки не буде надано відповіді на всі питання.
Щоб цього уникнути, до кожної змінної можна додати суфікс ".NAOK" (означає, що «Not Applicable» — це нормально). У такому разі спрацьовує така поведінка. Припустімо, у вас є змінна q1.NAOK:
- q1 не додається до виразу LEManyNA()
- LEMval('q1') і далі перевірятиме, чи відповідь релевантна, і повертатиме "", якщо ні (тобто окремі нерелевантні відповіді буде проігноровано, але вони не зроблять недійсним увесь вираз).
Отже, розв’язком проблеми поточної суми є використання рівняння sum(q1.NAOK,q2.NAOK,q3.NAOK,...,qN.NAOK).
Використання суфікса .NAOK також дає змогу авторам створювати опитування з кількома можливими шляхами, які згодом сходяться на спільних шляхах. Наприклад, респонденти відповідають на опитування так, що їхні відповіді виходять за межі звичайного діапазону. Автор може попередити їх, що результати можуть бути недійсними, і запитати, чи вони справді хочуть продовжити опитування. Якщо вони відповідають «Так», решту питань буде показано. Умова для «решти питань» перевірятиме, чи початкові відповіді були в межах звичайного діапазону, АБО чи респондент відповів «Так» на питання, яке релевантне лише тоді, коли відповіді були поза звичайним діапазоном.
Як ExpressionScript підтримує умовне мікротейлорінг?
Ось приклад мікротейлорінгу (де Question Type=='expr' означає рівняння):
| Код питання | Релевантність | Тип питання | Питання |
|---|---|---|---|
| name | 1 | text | Як вас звати? |
| age | 1 | text | Скільки вам років? |
| badage | !is_empty(age) | expr | {(age<16) or (age>80)} |
| agestop | badage | message | Вибачте, {name}, ви надто {if( (age<16),'young',if( (age>80),'old','middle-aged') ) } для цього тесту. |
| kids | !badage | yesno | Чи є у вас діти? |
| parents | 1 | expr | {!badage && kids=='Y'} |
| numKids | parents | text | Скільки у вас дітей? |
| kid1 | parents && numKids >= 1 | text | Скільки років вашій першій дитині? |
| kid2 | parents && numKids >= 2 | text | Скільки років вашій другій дитині? |
| kid3 | parents && numKids >= 3 | text | Скільки років вашій третій дитині? |
| kid4 | parents && numKids >= 4 | text | Скільки років вашій четвертій дитині? |
| kid5 | parents && numKids >= 5 | text | Скільки років вашій п’ятій дитині? |
| sumage | 1 | expr | {sum(kid1.NAOK,kid2.NAOK,kid3.NAOK,kid4.NAOK,kid5.NAOK)} |
| report | parents | text | {name}, ви вказали, що вам {age} і що у вас {numKids} дітей. Сума віку ваших перших {min(numKids,5)} дітей становить {sumage} |
Щоб завантажити наведений вище приклад опитування, натисніть на таке посилання: Приклад опитування про кількість дітей.
Усі ці питання можуть бути на одній сторінці (наприклад, в одній групі), і буде показано лише релевантні питання. Крім того, під час введення віку дітей вираз sum() в останньому питанні динамічно оновлюватиметься.
ExpressionScript забезпечує цю функціональність, обгортаючи кожен вираз в іменований елемент <span>. Щоразу, коли значення змінюється, він повторно обчислює вираз, який має відображатися в цьому елементі <span>, і оновлює відображення. На одній сторінці може бути десятки або навіть сотні таких виразів.
Підсвічування синтаксису
Щоб допомогти під час введення та перевірки виразів, EM пропонує підсвічування синтаксису з такими можливостями:
Типи та значення підсвічування синтаксису
| Колір | Зразок | Значення | Підказка | Коментарі |
|---|---|---|---|---|
| бежевий фон | Sample | усе рівняння | немає | Усе у фігурних дужках, що розпізнається як рівняння (тобто немає пробілів на початку чи в кінці), буде виділено бежевим фоном, щоб відрізняти його від навколишнього тексту |
| жирний червоний текст | Sample | Помилка | Пояснення помилки | Може бути невідома змінна або помилка у функції. Опитування не працює, а питання, що залежать від відповідного виразу, не буде показано респондентам. |
| синій текст | Sample | назва функції | значення та допустимий синтаксис | Позначає назви функцій або те, що має бути функціями, оскільки далі йде відкрита дужка. Вони відображаються жирним синім текстом. Підказки показують значення та допустимий синтаксис функції. |
| сірий текст | Sample | рядок | немає | Рядки в одинарних і подвійних лапках відображаються сірим текстом. |
| блакитний текст | Sample | змінна, задана на цій самій сторінці, | [name]: питання; значення; answerList із кодами для кожного значення | Будь-яка змінна, задана на тій самій сторінці, що й питання, яке ви зараз редагуєте, відображається блакитним текстом (її можна оновлювати в JavaScript). Підказка показує її назву, саме питання та поточне значення (або порожнє, якщо не задано). Якщо тип питання передбачає відповіді з переліченого набору значень, показується відповідність кодів значенням, що відображаються. |
| зелений текст | Sample | змінна, задана на попередній сторінці | [name]: питання; значення; answerList із кодами для кожного значення | Будь-яка змінна, задана на попередній сторінці, відображається жирним зеленим текстом. Підказка показує її назву, саме питання та поточне значення (або порожнє, якщо не задано). Якщо тип питання передбачає відповіді з переліченого набору значень, показується відповідність кодів значенням, що відображаються. |
| жирний рожевий текст | Sample | змінна, задана на наступній сторінці загалом: порожня на початку опитування, але може бути заповнена за допомогою індексу або кнопки «Назад» | [name або код SGQA]: питання; значення; answerList із кодами для кожного значення | Будь-яка змінна, задана на наступній сторінці, відображається жирним рожевим текстом. Підказка показує її назву, саме питання та поточне значення (або порожнє, якщо не задано). Якщо тип питання передбачає відповіді з переліченого набору значень, показується відповідність кодів значенням, що відображаються. |
| жирний бежевий текст | Sample | значення заміни Lime | значення | Рядки заміни Lime (як-от {TOKEN:xxx}, {PRIVACY_MESSAGE}) відображаються жирним бежевим текстом. |
| червоний текст | Sample | оператор присвоєння (=) | попередження | Якщо ви використовуєте оператор присвоєння (=), його буде показано червоним текстом. Це допомагає запобігти випадковому перевизначенню значень, коли ви насправді хотіли перевірити, чи a == b, а не задати значення a = b. |
| звичайний чорний текст | Sample | розділові знаки | немає | Усі інші розділові знаки у виразі відображаються звичайним чорним текстом. |
| текст у червоній рамці | жирна червона лінія оточує помилку | синтаксична помилка | опис помилки | Будь-які виявлені синтаксичні помилки показуються в червоних рамках. Підказка показує помилку. Приклади: незакриті дужки, використання невизначених функцій, передавання функціям неправильної кількості аргументів, погано структуровані вирази (наприклад, відсутні оператори між змінними), спроба присвоїти нове значення змінній лише для читання, спроба присвоїти значення не змінним або використання синтаксису, що не підтримується. Зауважте, що система виявлення синтаксичних помилок може повідомити лише про одну помилку у виразі, навіть якщо їх кілька; проте якщо виявлено будь-які помилки, буде показано принаймні одну. |
Додаткові матеріали
Приклади опитувань ExpressionScript
Сценарії використання та інструкції
Покрокові приклади
Довідник для розробників