x

Основні розділи

  1. LimeSurvey Cloud проти LimeSurvey CE
  2. Короткий посібник із початку роботи - LimeSurvey 3.0+
  3. Встановлення - LimeSurvey CE
  4. Як створити хороше опитування (посібник)
  5. Початок роботи
  6. Адміністрування LimeSurvey
  7. Опитування - вступ
  8. Налаштування опитування
  9. Меню опитування
  10. Структура опитування
  11. Питання - вступ
  12. Групи питань - вступ
  13. Опитування - керування
  14. Параметри панелі інструментів опитування
  15. Багатомовне опитування
  16. ExpressionScript Engine - Короткий посібник
  17. Некатегоризовані та розширені функції
  18. Загальні поширені запитання
  19. Усунення несправностей
  20. Обхідні рішення
  21. Ліцензія
  22. Журнал змін версій
  23. Плагіни
 Actions

Expression Manager

From LimeSurvey Manual

Ця сторінка, можливо, перекладена машинним способом і може містити помилки. Показати англійський оригінал · Покращити цей переклад
This page is a translated version of the page Expression Manager and the translation is 100% complete.

Короткий посібник для початку роботи

Огляд

Під час налаштування опитувань вам зазвичай потрібно мати можливість визначити таке:

  1. Навігація/розгалуження - дозволяє відповідям респондента змінювати порядок, у якому ставляться питання
  2. Адаптація/підстановка - як сформулювати питання (наприклад, з посиланням на попередні відповіді або з відмінюванням речень залежно від кількості чи статі респондентів), або як створювати власні звіти (наприклад, оцінки чи персоналізовані поради).
  3. Перевірка - гарантує, що відповіді відповідають певним критеріям, наприклад мінімальним і максимальним значенням або заданому шаблону введення

Expression Manager (EM) надає інтуїтивно зрозумілий спосіб визначення логіки для кожної з цих функцій. Майже все, що можна записати як стандартне математичне рівняння, є допустимим виразом, навіть якщо ви викликаєте функції. Наразі EM надає доступ до 80 функцій і може бути легко розширений для підтримки більшої кількості. Він також дозволяє звертатися до ваших змінних за зрозумілими людині іменами (а не за іменами SGQA).

У наведених нижче розділах показано основні місця, де використовується Expression Manager

Релевантність (керування навігацією/розгалуженням)

Деякі опитування використовують «логіку переходу» (Goto Logic): якщо ви відповідаєте на питання 1 варіантом C, то відбувається перехід до питання 5. Такий підхід дуже обмежений, оскільки його важко перевірити, а також він легко ламається під час зміни порядку питань. EM використовує булеве рівняння релевантності, щоб визначити всі умови, за яких питання може бути дійсним. Якщо питання релевантне, воно показується, інакше воно вважається нерелевантним (Not Applicable), а в базі даних зберігається значення NULL. Це схоже на те, що можна зробити за допомогою редактора умов, але EM дозволяє легко задавати набагато складніші та потужніші критерії (і використовувати ім'я змінної замість найменування SGQA).

Це зображення показує один зі способів перегляду логіки релевантності для опитування. Воно обчислює індекс маси тіла. Рівняння релевантності показано у квадратних дужках одразу після імені змінної (яке виділено зеленим). Отже, релевантність weight, weight_units, height і height_units дорівнює 1, що означає, що ці питання ставляться завжди. Однак релевантність для BMI - {!is_empty(height) and !is_empty(weight)}, що означає, що BMI буде обчислюватися, лише якщо респондент введе значення і для зросту, і для ваги (таким чином уникаючи ризику помилки ділення на нуль). Також питання Report показується, лише якщо респондент відповів на всі чотири основні питання (height, height_units, weight, weight_units).

Релевантність відображається та редагується в таких місцях:

Перегляд / редагування релевантності на рівні питання

Це рівняння обчислює індекс маси тіла (BMI). Питання ставиться, лише якщо людина спочатку вводить свій зріст і вагу.

Це екран редагування питання BMI.

Зверніть увагу, що під час введення рівняння релевантності фігурні дужки не використовуються.

Перегляд / редагування релевантності на рівні групи

Це зразок опитування для перепису населення. На першій сторінці запитується, скільки людей проживає разом з вами, і це значення зберігається у змінній «cohabs». Ця сторінка показується, лише якщо з вами проживає більше однієї особи (тобто вона показується для другої особи, що проживає з вами), а також лише якщо ви вказали, ким вам доводиться перша особа (p1_rel).

Як бачите, група також має критерії релевантності на рівні питань, тому кожне питання з'являється лише після того, як ви відповіли на попереднє (наприклад, {!is_empty(p1_sex)}). EM поєднує релевантність на рівні групи та питання за вас. Питання в групі ставляться, лише якщо група загалом релевантна. Після цього ставляться лише ті питання групи, які релевантні.

Ось екран редагування релевантності на рівні групи для цього питання:

Зверніть увагу, що під час введення рівняння релевантності фігурні дужки не використовуються.

Адаптація/підстановка (Tailoring/Piping)

EM дозволяє легко виконувати просту та складну умовну адаптацію ваших питань. Іноді потрібна проста підстановка, наприклад: «Ви сказали, що придбали [Product]. Що вам найбільше сподобалося в ньому?». Іноді потрібна умовна підстановка, наприклад: «[Mr./Mrs.] [LastName], чи погодилися б ви пройти наше опитування?». У такому разі потрібно використовувати «пан» або «пані» залежно від статі особи. В інших випадках потрібна ще складніша підстановка (наприклад, на основі математичного обчислення). EM підтримує кожен із цих типів адаптації/підстановки.

Умовні рівняння

Приклад з індексом маси тіла показує можливість обчислення BMI особи, навіть якщо вона вводить свій зріст і вагу в метричних або неметричних одиницях.

Тут weight_kg — це {if(weight_units == 'kg', weight, weight * .453592)}. Ця функція if() означає: якщо респондент ввів вагу в кілограмах, використовується це значення, інакше введене значення (у фунтах) множиться на .453592 для перетворення в кілограми. Змінна height_m використовує подібний підхід для обчислення зросту в метрах, навіть якщо зріст було введено в дюймах.

BMI обчислюється за формулою {weight_kg / (height_m * height_m)}.

Нарешті, звіт умовно адаптує повідомлення для респондента, повідомляючи, що саме він ввів. («Ви вказали, що ваш зріст 2 метри, а вага 70 кг.»)

Хоча це не дуже добре видно на зображенні вище, weight_status використовує вкладені оператори if() для віднесення людини до категорій від недостатньої ваги до тяжкого ожиріння. Рівняння цього виразу можна побачити в режимі «Показати логіку».

У вікні редагування цього питання можна побачити дві речі:

  1. Під час адаптації вирази необхідно брати у фігурні дужки
  2. Вирази можуть займати кілька рядків, якщо, як у цьому випадку, потрібно полегшити читання вкладеної умовної логіки.

Адаптовані питання, відповіді та звіти

Примітка: динамічна адаптація може не працювати, якщо варіанти відповідей відображаються у випадних списках на тій самій сторінці питання. Це пов’язано з тим, що адаптація вставляє тег <span>, який недопустимий усередині елементів списку вибору.

У цьому прикладі показано звіт BMI.

Ось вікно редагування того самого питання.

Як видно, усе, що знаходиться у фігурних дужках, розглядається як вираз, тому на попередньому зображенні підсвічується синтаксисом (кольором). Якщо ви зробили помилки (наприклад, неправильно написали або використали невизначені імена змінних чи функцій), EM покаже помилку, як у цьому прикладі: height_unit — невизначена змінна (насправді вона називається height_units), а rnd() — невизначена функція (правильна назва функції — round()). В обох випадках помилки обведені червоною рамкою, щоб їх було легше помітити та виправити.

Також видно, що можна швидко створювати складні звіти, наприклад таблицю введених значень або адаптовані поради.

Пам’ятайте, що під час адаптації всі вирази потрібно брати у фігурні дужки, щоб LimeSurvey знав, які частини питання є вільним текстом, а які слід обробляти через Expression Manager.

Перевірка

EM керує роботою більшості розширених параметрів питання. Вони визначають такі аспекти, як мінімальна/максимальна кількість відповідей; мінімальні/максимальні окремі значення; мінімальна/максимальна сума значень; а також перевірку відповідності введених значень заданим шаблонам рядків. Ви, як і раніше, вводите ці розширені параметри питання звичайним способом. Однак тепер будь-яке значення в цих полях вважається виразом, тому можна задавати критерії мінімуму/максимуму зі складними умовними залежностями від інших питань.

В усіх цих випадках, оскільки розширений параметр питання завжди вважається виразом, фігурні дужки під час його задання не використовуються.

На сторінці Приклади опитувань наведено багато робочих прикладів використання виразів для перевірки.

Вступ

LimeSurvey використовує новий модуль Expression Manager (EM), який дозволить LimeSurvey підтримувати складніше розгалуження, оцінювання, перевірку та адаптацію. Він замінить спосіб, у який LimeSurvey керує замінами, умовами та оцінюванням на внутрішньому рівні. Він також значно прискорить обробку, оскільки усуває більшість читань із бази даних під час виконання. EM розробив д-р Томас Вайт (TMSWhite).

Ця вікі-сторінка є основним довідником із синтаксису та функціональності Expression Manager.

Основні визначення

  1. Вираз: усе, що взято у фігурні дужки
    • За умови, що одразу після відкривної дужки або перед закривною фігурною дужкою немає пробілів
    • Вміст виразів обчислюється EM, тому він може містити математичні формули, функції та складну обробку рядків і дат.
  2. Адаптація: інколи її називають «piping», це процес умовної зміни тексту
    • Ви маєте доступ до всіх «полів заміни», дані учасника та дані відповідей.
    • Ви також отримуєте простіший доступ до питань, відповідей та їхніх властивостей.
  3. Рівняння релевантності: новий атрибут питання, що керує видимістю питання
    • Якщо є рівняння релевантності, питання показується лише тоді, коли воно набуває значення «істина».
    • Внутрішньо всі команди array_filter і array_filter_exclude перетворюються на релевантність на рівні підпитання
  4. Рівняння (тип питання): новий тип питання, що зберігає обчислення або звіти в базі даних
    • Він схожий на питання Boilerplate, але його вміст зберігається в базі даних, навіть якщо ввімкнено «Завжди ховати це запитання»
  5. Код запитання: це бажане ім’я змінної для EM
    • Це може бути описова назва, що вказує на призначення питання, що полегшує читання складної логіки
    • Допустимі коди питань НЕ повинні починатися з цифри, тому для нумерації питань за допомогою коду питання просто використовуйте «q1», «q1a» або «g1q2».
    • Саме це наразі стає іменем змінної під час експорту даних до SPSS або R, тож якщо ви виконуєте статистичний аналіз, ви, імовірно, уже зробили його унікальним.

Чи обов’язково мені використовувати EM?

Коротка відповідь: ні (але й так).

EM повністю зворотно сумісний з наявними опитуваннями. Тож якщо вас влаштовує використання умов та оцінювання в стилі, який LimeSurvey використовував у версіях <= 1.91+, ви можете й надалі так робити.

Проте EM повністю замінює спосіб, у який LimeSurvey внутрішньо працює з умовами. Хоча ви все ще можете використовувати редактор умов для створення та керування умовами, LimeSurvey 1.92 перетворить їх на еквівалентні рівняння релевантності. Під час оновлення LimeSurvey 1.92 автоматично перетворить усі наявні умови на рівняння релевантності.

Це дає змогу отримати найкраще з обох підходів: ви можете й надалі користуватися LimeSurvey так, як звикли, але бачитимете еквівалентне рівняння релевантності, тож зможете поступово переходити безпосередньо до рівнянь релевантності, коли вважатимете за потрібне.

Чи можна поєднувати Умови та Релевантність?

Так. Ви можете використовувати редактор умов для одних питань, а редактор релевантності — для інших. Умови автоматично перетворюються на релевантність під час збереження питання.

Зверніть увагу: ми виходимо з того, що якщо ви використовуєте редактор умов, то хочете, щоб ці умови перезаписали будь-яке рівняння релевантності, введене вручну. Тому, якщо у вас є наявні умови і ви хочете вручну змінити релевантність, спочатку видаліть умови для цього питання. А саме: скопіюйте згенероване рівняння релевантності до текстового редактора, за допомогою меню умов видаліть усі умови для цього питання (це також видалить релевантність), потім відредагуйте питання та вставте згенероване рівняння релевантності з текстового редактора назад у поле релевантності цього питання (і збережіть питання). Якщо буде достатній попит на видалення умов без видалення згенерованого рівняння релевантності, ми зможемо додати процес масового перетворення.

Як вибрати між Умовами та Релевантністю?

Ось перелік переваг і недоліків кожного підходу:

Підхід Переваги Недоліки
Умови 1. Зручний графічний інтерфейс для створення простих умов
2. Графічний інтерфейс добре задокументований і зрозумілий команді підтримки
1. Підтримуються лише прості порівняння, погано працює з умовами AND/OR
2. Каскадні умови працюють нестабільно
3. Повільно: інтенсивне використання бази даних може уповільнювати довгі опитування
4. Повідомлялося про проблеми з повторним завантаженням умов
5. Графічний інтерфейс погано масштабується, коли є десятки, сотні чи тисячі питань
6. Перенесення паперових опитувань може бути повільним, оскільки потрібно використовувати назви SGQA
7. Для складного розгалуження часто потрібен програміст, який напише спеціальну логіку
Релевантність 1. Підтримує дуже складну логіку, зокрема 80+ функцій та математичні/рядкові оператори
2. Чудова підтримка каскадної логіки
3. Швидко: немає додаткових звернень до бази даних, тому підтримуються опитування з 1000+ питань
4. Немає проблем із повторним завантаженням логіки, оскільки коди SGQA не потрібні
5. Підсвічування синтаксису масштабується до опитувань з 1000+ питань
6. Легко і швидко використовувати групам, які хочуть комп'ютеризувати наявні паперові опитування.
7. Легко підтримує напівструктуровані інтерв'ю та епідеміологічні опитування без залучення програмістів
1. Немає графічного інтерфейсу для простих умов: натомість використовуйте підсвічування синтаксису
2. Це нове, тому команди підтримки ще не опанували EM.

Підсумок такий: якщо вас влаштовує те, як працює LimeSurvey 1.91+, немає причин змінювати свій підхід.

Які ще переваги дає використання EM?

Ось інші причини, з яких вам може знадобитися EM.

  1. Обчислення — ви можете створити будь-яке обчислення, яке тільки можете уявити:
    • Вам доступні всі поширені математичні оператори та функції
    • Вам доступні понад 70 математичних функцій, функцій обробки дат і рядків
    • Розробникам досить легко додавати нові функції, якщо вони потрібні користувачам
  2. Збереження обчислень у базі даних
    • Тепер ви можете виконувати прості й складні обчислення та/або обчислювати бали за шкалою І зберігати їх у базі даних без використання JavaScript.
    • Для цього використовується тип питання «Рівняння».
  3. Оцінювання
    • Тепер ви можете створювати оцінювання або бали за шкалою з будь-якого типу питання, а не лише з того обмеженого набору, який підтримувався раніше
    • Ви можете використовувати тейлоринг, щоб показувати поточні або загальні бали оцінювання в будь-якому потрібному місці — навіть на тій самій сторінці
    • Ви маєте більше контролю над звітами, що генеруються на основі цих балів оцінювання
    • Ви можете зберігати бали оцінювання в базі даних без використання JavaScript
    • Ви можете приховувати бали оцінювання без використання JavaScript чи CSS
  4. Поля підстановки
    • Використовуйте код питання, щоб вставляти значення з відповідей на попередні питання — так легше читати та перевіряти.
  5. Тейлоринг — ви можете умовно показувати текст залежно від інших значень
    • Використовуйте відповідне звертання до респондента, наприклад (напр. «Вітаємо, [пане/пані] Смит»)
    • Формуйте граматично правильні речення, коли важливі однина/множина: (напр. «У вас 1 дитина» і «У вас 2 дітей»)
    • Правильно відмінюйте дієслова та іменники залежно від статі й числа респондента.
  6. Нові атрибути змінних — для тейлорингу вам доступні такі:
    • (без суфікса) — псевдонім для qcode.code
    • .code — вибраний код відповіді на питання, якщо воно релевантне (інакше порожньо), або текстове значення, якщо це питання без кодів
    • .NAOK — те саме, що .code, але може бути частиною обчислень або списків, навіть якщо питання нерелевантне
    • .value — значення оцінки для питання, якщо воно релевантне (інакше порожньо), або текстове значення, якщо це питання без кодів — доступне, якщо для опитування ввімкнено оцінювання, інакше завжди дорівнює нулю
    • .valueNAOK — те саме, що .value, але може бути частиною обчислень або списків, навіть якщо питання нерелевантне
    • .shown — відповідь у тому вигляді, в якому її бачить користувач
    • .qid — ідентифікатор питання
    • .gid — ідентифікатор групи
    • .sgqa — значення SGQA для питання
    • .jsName — правильна назва змінної JavaScript для питання, незалежно від того, визначено її на цій чи на іншій сторінці
    • .qseq — порядковий номер питання (починаючи з 0)
    • .gseq — порядковий номер групи (починаючи з 0)
    • .mandatory — чи є питання обов'язковим (Y/N)
    • .question — текст питання
    • .relevance — рівняння релевантності для питання
    • .grelevance — рівняння релевантності для групи
    • .relevanceStatus — чи є питання наразі релевантним (булеве значення (може відрізнятися в PHP і JS))
    • .type — тип питання (однолітерний код)
  7. Динамічні зміни на сторінці
    • Уся релевантність, обчислення та тейлоринг працюють динамічно на сторінці — тож зміни значень миттєво оновлюють сторінку
    • Отже, питання динамічно з'являються/зникають залежно від того, чи вони релевантні
    • Питання також динамічно адаптуються на основі відповідей на сторінці, тому ви можете бачити поточні підсумки, адаптовані речення та індивідуальні звіти.
  8. Новий екран введення даних
    • Окрім поточної системи введення даних, ви можете просто використовувати режим «Опитування все в одному».
    • Він підтримує релевантність і тейлоринг на сторінці, тож оператори введення даних можуть швидко переходити між полями і вводитимуть лише релевантні відповіді
    • Це може бути критично, якщо вашій особі, що вводить дані, потрібно бачити тейлоринг, який також є динамічним.
  9. Усуває потребу в більшості власного коду JavaScript
    • EM легко підтримує складні обчислення, підрахунок балів, тейлоринг та умовну логіку.
    • Для деяких речей усе ще знадобиться JavaScript (наприклад, власні макети та умовне приховування піделементів питання), але ваш JavaScript може використовувати функції EM, щоб ви могли отримувати доступ до питань за їхнім Qcode замість SGQA, а також до будь-яких властивостей питання, перелічених вище.

Які ще корисні нові можливості надає EM?

Незалежно від того, чи ви продовжуєте користуватися редактором умов, чи складаєте рівняння релевантності вручну, ви отримуєте такі додаткові переваги:

  1. Ви можете створювати складніші критерії перевірки
    • Усі розширені атрибути питання (наприклад, max_answers, min_num_value_n, max_num_value) можуть використовувати вирази. Тому критерії мінімуму/максимуму можна легко змінювати залежно від попередніх відповідей, навіть якщо вони розміщені на тій самій сторінці.
    • EM також обробляє всю перевірку на основі регулярних виразів, тому ви можете надійно поєднувати атрибути питання на основі preg і рівнянь.
  2. Легка зміна порядку (або видалення) питань і груп
    • До версії 1.92 не можна було змінювати порядок питань чи груп, якщо LimeSurvey вважав, що така зміна може порушити умови, в яких вони використовувалися. Так само не можна було видалити питання, від яких залежали інші питання.
    • Завдяки підсвічуванню синтаксису в EM легко побачити й перевірити, чи не використовуєте ви питання до того, як їх оголошено. Тому тепер ви можете змінювати порядок або видаляти питання і групи будь-коли. EM оновить усе підсвічування синтаксису, щоб показати потенційні помилки.
    • Вигляд зміни порядку питань було вдосконалено для такої перевірки. Тепер він показує рівняння релевантності питання та персоналізацію, тож ви одразу бачите, чи не стали якісь змінні рожевими (це означає, що їх використано до оголошення).
  3. Покажчик навігації за питаннями/групами завжди доступний і точний
    • До версії 1.92 ці покажчики були недоступні за наявності складних умов
    • З EM ми можемо гарантувати їхню точність.
    • Респонденти можуть навіть повернутися до попереднього питання, змінити відповідь, а потім перейти вперед (або надіслати анкету)
      • Під час переходу вперед EM повторно перевірить усі проміжні питання/групи.
      • Якщо якісь питання стають нерелевантними, у базі даних для них буде записано NULL, щоб ваші дані були внутрішньо узгодженими
      • Якщо якісь питання стають релевантними або вперше не проходять правила обов'язковості чи перевірки, EM зупиниться на цій сторінці й змусить користувача відповісти на ці питання, перш ніж перейти до кінцевого пункту призначення.
  4. Автоматичне перетворення умов на релевантність
    • Під час оновлення бази даних для всіх наявних опитувань з умовами буде створено рівняння релевантності
    • Щоразу, коли ви імпортуєте опитування, за потреби створюватимуться рівняння релевантності
    • Щоразу, коли ви додаєте, видаляєте або змінюєте умови, EM створюватиме відповідне рівняння релевантності.
  5. Зручне підсвічування синтаксису
    • Коли EM показує рівняння релевантності, він показує Qcode, навіть якщо ви ввели код SGQA, оскільки ми вважаємо, що так легше читати.
    • Усі змінні виділено кольором, щоб показати, чи їх оголошено до чи після поточного питання (або до чи після поточної групи). Це дає змогу швидко виявити й виправити випадки, коли ви намагаєтеся використати змінні в релевантності (зокрема array_filter), персоналізації або рівняннях перевірки до їх оголошення.
    • Крім того, якщо навести вказівник миші на змінну, виділену кольором, ви побачите найважливіші метадані про це питання. Це зокрема № послідовності групи, № послідовності питання, Qcode, текст питання та всі доступні варіанти відповідей (якщо це тип питання з переліченими варіантами відповідей).
      • Список варіантів відповідей використовує такий синтаксис: 'answers':{key:val, ... }.
      • key має синтаксис 'scale~code', де scale — це шкала відповіді (наприклад, для подвійної шкали), а code — код відповіді.
      • val має синтаксис 'value~shown', де value — це значення оцінки (якщо використовується оцінювання, інакше code) (наприклад, Qcode.value), а shown — це значення, яке бачить респондент (наприклад, Qcode.shown)
      • Це означає, що багато опитувань можуть використовувати обчислення без режиму оцінювання. Якщо ваші перелічені варіанти відповідей унікальні, не десяткові й невід'ємні, ви можете просто виконувати обчислення зі значеннями Qcode.code.
  6. Легкий перегляд усієї логіки та вмісту опитування
    • З'явилася нова функція «Показати логіку опитування», яка дозволяє побачити все про опитування (або групу чи питання) на одній сторінці
    • Вона показує деталі на рівні групи, питання, підпитання та відповіді для вибраної області (опитування, група чи питання)
    • Вона також показує релевантність, релевантність на рівні підпитань (для array_filter і array_filter_exclude), згенероване рівняння перевірки (для preg та будь-яких правил перевірки, як-от мінімум/максимум суми/кількості значень) і всі непорожні атрибути питання.
    • Усе підсвічено за синтаксисом, щоб ви могли бачити потенційні синтаксичні помилки (наприклад, незбалансовані дужки або використання змінних до їх оголошення)
    • Підсвічування синтаксису забезпечує швидку навігацію та редагування опитування.
      • Якщо клацнути назву змінної, відкриється вікно (або вкладка) браузера, яке показує це питання та дозволяє його редагувати.
      • Якщо клацнути назву групи, відкриється вікно (або вкладка) браузера з виглядом зміни порядку груп, щоб ви могли легко переміщувати питання.
      • Усі атрибути питання також підсвічуються за синтаксисом. Це дає змогу задавати й бачити вирази в розширених параметрах питання (наприклад, базувати мінімум/максимум кількості/суми значень на виразі)
    • Автор EM використовував подібний вигляд (трохи чистіший), щоб його співпрацюючі епідеміологи та інституційна комісія з етики могли перевіряти й затверджувати опитування з тисячами питань у сильно розгалужених і персоналізованих структурованих інтерв'ю

Початок роботи

Найкращий спосіб почати роботу з EM:

  • Встановіть останню стабільну версію з http://www.limesurvey.org/en/download
  • Імпортуйте та вивчіть зразки опитувань.
  • Ознайомтеся з прикладами використання та інструкціями і покроковими прикладами.
  • Вивчіть документацію EM (ця сторінка)
  • Перегляньте вбудований набір тестів EM
    • У будь-якому опитуванні в розділі «Інструменти» виберіть параметр EM
    • Розділ «Доступні функції» містить перелік понад 70 функцій і їхній синтаксис
    • Модульні тести окремих виразів
      • показують приклади використання всіх функцій і операторів EM, а також результати в PHP і JavaScript
      • зверніть увагу, що є кілька функцій, які дають різні результати у версіях PHP і JavaScript, тож ця сторінка допоможе вам спланувати логіку EM відповідно.

Яку функціональність розширює/замінює Expression Manager? (LimeSurvey <= 1.91+)

Умови => Релевантність

Умови керували тим, які питання видимі. Загальний синтаксис був SGQA оператор Значення, наприклад 111X2X3 == "Y". Умови можна було поєднувати через AND або OR, але змішування AND і OR було складним. Самі умови зберігалися в окремій таблиці, і значна частина коду LimeSurvey була присвячена керуванню умовами. Через інтенсивний доступ до бази даних обробка великої кількості умов могла спричиняти помітні проблеми з продуктивністю. Крім того, коли до питань або груп було призначено умови, часто не дозволялося змінювати їхній порядок або видаляти їх.

Оцінювання => Рівняння та мікроперсоналізація

Оцінювання дозволяло користувачам створювати шкальні бали із сукупності питань. Однак вони не могли динамічно змінюватися на поточній сторінці, а їхні значення не зберігалися в базі даних.

Підстановки => Мікроперсоналізація

Користувачі могли персоналізувати деякі повідомлення та питання на основі попередніх відповідей. Наприклад, питання могло бути таким: {TOKEN:FIRSTNAME}, ви сказали, що {SPORT.shown} — ваш улюблений вид спорту. Однак без складного JavaScript було неможливо виконувати умовну персоналізацію (наприклад, казати «пан» або «пані» залежно від статі особи), а також відмінювати іменники чи змінювати дієслова за формами. Автори могли створювати опитування, що здавалися персоналізованими, але це вимагало окремих питань для кожної комбінації та складних умов для вибору питань, які слід показувати.

Перевірка

Питання можна було перевіряти за допомогою регулярних виразів або мінімальних/максимальних значень, або дозволити відповіді слугувати мінімальним чи максимальним значенням. Однак без складного JavaScript перевірки не могли базуватися на обчисленнях інших змінних.

Рівняння

Рівняння не підтримувалися без складного JavaScript.

Тип питання «Рівняння»

Рівняння (наприклад, остаточний бал оцінювання) не можна було зберегти в базі даних без складного JavaScript.

Як Expression Manager замінить/розширить цю функціональність?

Expression Manager — це новий основний модуль LimeSurvey, який значно полегшує підтримку складної функціональності, що раніше вимагала власного JavaScript. Він також замінює спосіб, у який LimeSurvey наразі керує умовами та оцінюванням.

Нова термінологія щодо Expression Manager (EM)

EM «мислить» свою функціональність такими термінами:

  • Розгалуження на основі релевантності — якщо питання релевантне, то його ставлять, інакше ні (тобто роблять невидимим і позначають як NULL у базі даних). З'явилося нове поле «Релевантність» для всіх типів питань, а також для кожної групи (тож ви можете застосувати набір умов до цілої групи, не копіюючи ту саму умову до кожного питання, та/або поєднувати умовну логіку на рівні груп і питань).
  • Персоналізація — коли ви знаєте, які питання слід ставити, персоналізація (іноді її називають piping) визначає, як саме ставити питання. Це дає змогу підтримувати не лише просту підстановку (як-от {TOKEN:FIRSTNAME}), а й змінювати дієслова та відмінювати іменники залежно від статі чи кількості ваших респондентів. Вона також дозволяє змінювати повідомлення, яке ви показуєте респонденту, залежно від того, чи відповів він (або як відповів) на інші питання.
  • Рівняння — EM додає новий тип питання під назвою «Рівняння», який зберігає результат виразу. Результати цих рівнянь обчислюються та записуються в базу даних, навіть якщо ви приховуєте їх на сторінці. Тому вони корисні для прихованих обчислень балів, навігації на основі складних рівнянь, оцінювання та звітів, які мають створюватися й бути легко доступними в базі даних.

Релевантність і каскадна релевантність

Кожен тип питання тепер має параметр «Релевантність», який керує тим, чи показується питання. EM обробляє кожне рівняння релевантності в тому порядку, у якому вони мають з'являтися в опитуванні. Якщо вираз істинний (або відсутній — для підтримки старих опитувань), питання буде показано. Якщо воно не релевантне, питання буде приховано, а значення в базі даних стане NULL. Якщо в групі немає релевантних питань, усю групу буде пропущено.

Крім того, якщо будь-яка зі змінних у виразі нерелевантна, вираз завжди дає значення «хибність». Це забезпечує каскадну релевантність, тож вам не потрібно писати дуже довгі рівняння релевантності для кожного питання.

Припустімо, у вас є 5 питань Q1–Q5, і ви хочете показувати Q2 лише якщо була дана відповідь на Q1, Q3 — якщо була дана відповідь на Q2 тощо. Рівняння релевантності можуть бути такими:

Код запитання Релевантність Питання
Q1 1 Як вас звати?
Q2 Q1 {Q1}, скільки вам років?
Q3 Q2 Отже, вам {Q2} років. Ви одружені?
Q4 Q3 == "Y" {Q1}, як довго ви одружені?
Q5 Q4 Скільки у вас дітей, {Q1}?

Обчислення релевантності також працюють у JavaScript — тож ви можете розмістити всі наведені вище питання на одній сторінці, і все працюватиме як очікується. Фактично EM повністю замінює спосіб, у який EM обробляє формати опитування «усе на одній сторінці», «по групах» і «по одному питанню». Тепер усі вони використовують той самий механізм навігації, тому працюють однаково незалежно від стилю опитування.

Поки ви перебуваєте на тій самій сторінці, усі введені вами дані залишатимуться на місці, просто прихованими. Тож якщо ви введете якусь інформацію, потім виберете варіант, що робить її нерелевантною, а потім знову зробите її релевантною, ваші відповіді залишаться доступними. Однак щойно ви перейдете на іншу сторінку, усі нерелевантні відповіді буде втрачено задля цілісності набору даних.

Релевантність на рівні групи

Expression Manager також підтримує релевантність на рівні групи. Це спрощує реалізацію циклів. Припустімо, ви хочете зібрати інформацію щодо до 10 об'єктів (наприклад, продуктів або членів домогосподарства), при цьому спочатку визначаєте, для скількох об'єктів потрібні додаткові питання (наприклад, запитавши, скільки людей мешкає в домогосподарстві, або попросивши респондентів відзначити в довгому списку продукти, які їм подобаються). Дізнавшись, для скількох об'єктів потрібні додаткові питання, ви можете використати релевантність на рівні групи, наприклад {count >= 1}, {count >=2}, ... {count >= 10} для кожної з 10 груп додаткових питань. Усередині кожної групи можна застосувати умовну логіку на рівні питання (наприклад, додаткові питання залежно від статі чи віку кожної особи). Рівняння релевантності на рівні питання та групи поєднуються через логічне І, щоб визначити, що саме слід показувати.

Адаптація тексту / Piping

Усе, що знаходиться у фігурних дужках, тепер розглядається як вираз (за одним винятком, описаним нижче). Вирази мають доступ до всіх LimeReplacementFields, до всіх змінних (через кілька псевдонімів), до всіх типових операторів рівнянь (математичних, логічних і порівняння) та до десятків функцій (які навіть працюють динамічно на стороні клієнта).

За допомогою цих рівнянь ви можете, наприклад:

  1. Умовно показувати респондентам адаптовані повідомлення на основі попередніх відповідей
  2. Створювати оцінювання та показувати його результати (або умовно переходити чи показувати повідомлення на основі цих результатів) без використання самого модуля оцінювання
  3. Відмінювати іменники та змінювати дієслова за формами у питаннях, відповідях і звітах.
  4. Показувати підсумки відповідей перед сторінкою «Показати ваші відповіді» наприкінці опитування

Рівняння

Існує новий тип питання під назвою «Рівняння». Він схожий на питання Boilerplate, але зберігає в базі даних значення того, що відображається. Тому, якщо текст питання типу «Рівняння» містить обчислення оцінювання, це значення буде збережено в базі даних у змінній, яку можна відображати в публічній або приватній статистиці.

Це вирішує поширений запит щодо збереження балів оцінювання в базі даних.

Синтаксис

Усе, що міститься у фігурних дужках, тепер вважається виразом (за одним винятком: на початку й наприкінці не повинно бути пробілів — це потрібно для того, щоб Expression Manager не намагався обробляти вбудований 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',
               ''
             )
           )
         )
       )
     )
   )
 )
)}
Expression Manager підтримує такий синтаксис:
  • Усі стандартні математичні оператори (наприклад, +,-,*,/,!)
  • Усі стандартні оператори порівняння (наприклад, <,<=,==,!=,>,>=, а також еквіваленти: lt,le,eq,ne,gt,ge)
  • Круглі дужки (для групування підвиразів)
  • Умовні оператори (наприклад, &&,| | та їхні еквіваленти: and,or)
  • Рядки в одинарних і подвійних лапках (у кожному з яких можна вкладати рядки з лапками іншого типу)
  • Оператор «кома» (дозволяє мати список виразів і повертати лише останній результат)
  • Оператор присвоєння (=)
  • Попередньо визначені змінні (для посилання на питання, атрибути питань і відповіді) — наприклад, усі коди SGQA
  • Попередньо визначені функції (їх уже понад 70, і додавати нові легко)

Оператори

Синтаксис EM дотримується звичайного пріоритету операторів:

Рівень Оператор(и) Опис
1 () круглі дужки для групування або виклику функцій
2 ! - + унарні оператори: заперечення, зміна знака, унарний плюс
3 * / множення, ділення
4 + - додавання, віднімання
5 < <= > >= lt le gt ge порівняння за величиною
6 == != eq ne порівняння на рівність
7 and логічне І
8 or логічне АБО
9 = оператор присвоєння
10 , оператор «кома»

Попередження щодо оператора плюс (+)

Для узгодженості між JavaScript і PHP оператор плюс (+) виконує додавання, якщо обидва операнди числові, і конкатенацію, якщо обидві частини є нечисловими рядками. Проте ми рекомендуємо використовувати функцію join() для конкатенації та функцію sum() для додавання, оскільки так ваш намір буде зрозумілішим, а також це дозволяє уникнути несподіваних результатів, якщо ви очікували рядки, а отримали числа (або навпаки).

Попередження щодо невідповідності числа й рядка та алфавітного порівняння

Коли ви порівнюєте значення за величиною або на рівність, зверніть увагу на невідповідність типів. Значення, введене користувачем, або вибраний код відповіді можна використовувати як число, якщо це явно число. Якщо взяти одне зі значень у ", порівняння буде виконано як текстове (алфавітне). Якщо ви хочете порівнювати числа, ніколи не беріть число в лапки ".

Наприклад, 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").

Застереження щодо використання оператора присвоєння (=)

Зверніть увагу: слід уникати операторів присвоєння, якщо в цьому немає крайньої потреби, оскільки вони можуть спричинити несподівані побічні ефекти. Наприклад, якщо ви змінюєте значення попередньої відповіді, каскадна логіка релевантності та перевірки між цим питанням і поточним питанням не перераховується, тож ви можете отримати внутрішньо суперечливі дані (наприклад, питання, що залишилися з відповіддю, хоча мали б мати значення NULL, або питання, які пропущено, хоча на них слід було відповісти). Загалом, якщо потрібно присвоїти значення змінній, слід створити питання типу «Рівняння» і за допомогою виразу встановити його значення. Проте іноді цей оператор справді потрібен, тому ми зробили його доступним.

Щоб застерегти вас щодо цього оператора, у рівняннях із синтаксисом він показується червоним шрифтом (щоб ви не плутали його з «==»).

Використання оператора присвоєння

Основні причини, з яких може знадобитися присвоєння:

  • Потрібно встановити значення за умовчанням для питання, яке не приймає значення за умовчанням через рівняння (наприклад, список із перемикачами, де інтерфейс дозволяє вибрати один із варіантів відповідей, але не дає змоги ввести рівняння). Однак будьте обережні: LimeSurvey не зможе перевірити, що ваше рівняння видає одну з допустимих відповідей для цього питання.
  • Потрібно примусово змінити відповідь на попереднє питання на основі пізнішої відповіді
  • Потрібна складна квота: використання одного прихованого питання з одиничним вибором для квоти та встановлення його значення через присвоєння
  • тощо

Для цього можна використовувати всю систему Expression Manager.

  Присвоєння виконується лише в PHP. Воно не оновлює жодних значень на тій самій сторінці, а лише коли користувач переходить кнопками «Далі», «Назад», «Зберегти» тощо.


  Якщо для цього ви не використовуєте тип питання «Рівняння»: присвоєння виконується лише після завершення логіки поточної сторінки. Рекомендований спосіб — завжди використовувати питання типу «Рівняння».


Кілька прикладів:

  • Встановити відповідь на питання з коротким текстом у нижньому регістрі: {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>

Доступ до змінних

Expression Manager надає доступ лише для читання до будь-яких змінних, які можуть знадобитися. Для зворотної сумісності він надає доступ до такого:

  • TOKEN:xxx - значення TOKEN (наприклад, TOKEN:FIRSTNAME, TOKEN:ATTRIBUTE_5) (лише для НЕанонімних опитувань).
  • QCODE.shown - відображуване значення відповіді (наприклад, «Так») за допомогою Expression Manager.
  • Усі значення {XXX}, що використовуються шаблонами.
  • У тексті питання можна використовувати {QID}, яке замінюється на ідентифікатор питання, та {SGQ}, яке замінюється на SGQA питання.

Крім того, Expression Manager дає змогу посилатися на змінні за кодом питання (стовпець 'title' у таблиці питань у базі даних). Це також мітка змінної, яка використовується під час експорту даних до SPSS, R або SAS. Наприклад, якщо у вас є питання про ім’я, вік і стать, ви можете назвати ці змінні name, age і gender замість 12345X13X22, 12345X13X23 і 12345X13X24. Це полегшує всім читання рівнянь і перевірку логіки, а також дає змогу переставляти питання, не відстежуючи номери груп або питань.

Важливо: безпечно посилатися лише на змінні, що містяться на попередніх сторінках або в попередніх питаннях.

Крім того, Expression Manager дає змогу отримати доступ до багатьох властивостей питання:


Синтаксис Значення Приклад Результат прикладу
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} 'Яка ваша стать?'
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 редактором

  Цю проблему виправлено після версії 2.05 build 140803


Якщо ви використовуєте HTML редактор, деякі символи замінюються на HTML-сутності.

  • & на &amp;
  • < на &lt;
  • > на &gt;

Якщо ви використовуєте HTML редактор, потрібно використовувати:

  • and замість &
  • lt замість <
  • le замість <=
  • gt замість >
  • ge замість >=

Іменування змінних Qcode

Нижче наведено подробиці того, як побудувати Qcode (та отримати доступ до деяких властивостей) залежно від типу питання. Загалом Qcode будуються так:

 QuestionCode . '_' . SubQuestionCode . '_' . ScaleId

Код підпитання та ідентифікатор шкали потрібно використовувати чи ні залежно від типу питання - див. таблицю нижче. Для comment і other коди питань - 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'}

Зарезервовані змінні 'this', 'self' та 'that'

Досить часто потрібно оцінити всі частини питання, наприклад, підрахувати, на скільки підпитань надано відповідь, або підсумувати бали. Іноді потрібно обробити лише певні рядки чи стовпці питання (наприклад, отримати суми за рядками чи стовпцями та зберегти їх у базі даних). Ці зарезервовані змінні роблять цей процес відносно простим.

Змінна 'this' використовується виключно в додаткових параметрах питання «Рівняння перевірки всього питання» та «Рівняння перевірки підпитання». Вона розгортається в імена змінних кожної з комірок у цих питаннях. Отже, якщо ви хочете переконатися, що кожне значення більше за три, задайте для «Рівняння перевірки підпитання» значення (this > 3).

Змінні 'self' і 'that' потужніші та працюють як макроси, що розгортаються перед обробкою рівнянь. Доступні варіанти синтаксису:

  • self
  • self.suffix
  • self.sub-selector
  • self.sub-selector.suffix

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 ....
  • nosq_X - де X - ідентифікатор рядка або стовпця. Вибираються лише підпитання, що не відповідають шаблону X. Зверніть увагу: пошук виконується за повним кодовим ідентифікатором, після чого nosq_X збігається з підпитаннями, але не включає підпитання nX, X, Xn

Приклади:

  • Чи надано відповідь на будь-яку частину питання? {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' схожа на змінну 'self', але дає змогу посилатися на інші питання. Її синтаксис:

  • that.qname
  • that.qname.suffix
  • that.qname.sub-selector
  • that.qname.sub-selector.suffix

qname - це назва питання без жодних розширень підпитань. Наприклад, якщо ви створили питання 'q1', то це і є його 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' можна використовувати в будь-якій релевантності, перевірці або адаптації тексту.

Єдине застереження: коли ви використовуєте функцію Показати файл логіки, вона показуватиме розгорнуте значення 'self' і 'that'. Це дає змогу побачити реальне рівняння, яке буде згенеровано, щоб ви (та Expression Manager) могли перевірити існування змінних. Це може збивати з пантелику, оскільки ви можете побачити досить довгі рівняння. Однак, якщо ви відредагуєте питання, то побачите початкове рівняння з використанням 'self' та/або 'that'

Також зауважте, що не слід використовувати ці змінні, якщо (а) ви хочете явно вказати кожну змінну, що використовується в рівнянні, або (б) використовуєте змінні без підпитань (наприклад, питання з однією відповіддю). У таких випадках додавати до змінної префікс 'that' зайве, і ви ризикуєте отримати неочікувані результати.

Використання NAOK

NAOK --> "Not Applicable" (NA) is alright (OK) — «Неактуально» (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). Якщо підпитання приховане, Expression Manager повертає порожній рядок.

Без NAOK: якщо одне питання або одне підпитання приховане, Expression Manager завжди повертає порожній рядок, що рівнозначно значенню false.

Суфікс .shown завжди використовує систему NAOK (порожній рядок, якщо питання приховане), але якщо вам потрібен код відповіді, завжди краще додавати .NAOK після коду запитання. Окрім випадків, коли він вам потрібен саме так і ви розумієте, що робите.

Інший приклад та додаткову інформацію наведено в розділі Перевизначення каскадних умов

Доступ до функцій

Expression Manager надає доступ до математичних, рядкових і користувацьких функцій, як показано нижче. Для цих функцій існують еквіваленти в 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 Округлити дроби (up) number ceil(number)
checkdate Повертає істину (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 Округлити дроби (down) 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 (Updated in 3.0.2 ) if(test,result_if_true[,result_if_false = ""]) у стилі Excel 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)
log Логарифм числа за заданою основою або натуральний логарифм. number log(number,base=e)
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)

Функції, які заплановані або розглядаються

Інші функції, які заплановані (або розглядаються), але ще не реалізовані, наведено нижче. Деякі з них потрібні для зворотної сумісності з іншим інструментом для опитувань.

Синтаксис Значення Коментарі
e() повертає значення e
formatDate(X,PAT) повертає рядкове значення дати X, відформатованої за шаблоном формату дати Java PAT
formatNumber(X,PAT) повертає рядкове значення числа X, відформатованого за шаблоном формату чисел Java PAT
getAnsOption(X) Основний плагін ExpressionAnswerOptions
getAnsOption(X,Y) Основний плагін ExpressionAnswerOptions
getRelevance(X) повертає рівняння релевантності для питання X
getStartTime() повертає дату, що відповідає системному часу початку опитування респондента
getType(X) повертає рядкову назву типу даних, напр. *NA*, якщо isNA()
gotoFirst() переходить до першого набору релевантних питань — це порушує звичайний хід роботи системи
gotoNext() переходить до наступного набору релевантних питань — це порушує звичайний хід роботи системи
gotoPrevious() переходить до попереднього набору релевантних питань — це порушує звичайний хід роботи системи
isAsked(X) повертає true, якщо відповідь не є ні *NA*, ні *INVALID*, ні *UNASKED*
isInvalid(X) повертає true, якщо відповідь має тип *INVALID*
isNA(X) повертає true, якщо відповідь має тип *NA*
isNotUnderstood(X) повертає true, якщо відповідь має тип *HUH*
isRefused(X) повертає true, якщо відповідь має тип *REFUSED*
isSpecial(X) повертає true, якщо відповідь має тип *UNASKED*, *NA*, *REFUSED*, *INVALID*, *UNKNOWN* або *HUH*
isUnknown(X) повертає true, якщо відповідь має тип *UNKNOWN*
jumpTo(X) переходить до групи, що містить питання із зазначеною назвою — це порушує звичайний хід роботи системи
jumpToFirstUnasked() переходить до першого непоставленого питання оминаючи попередні питання з відповідями це порушує звичайний хід роботи системи
lastIndexOf(X,Y) повертає останній індекс (з нуля) рядка Y у рядку X. Повертає -1, якщо Y не міститься в X
list(X,...) рядок, що містить список додатних значень, розділених комами, де останні два розділено словом «і»
mean(X,...) повертає середнє значення списку значень
numAnsOptions(X) повертає кількість варіантів відповідей питання X
orlist(X,...) рядок, що містить список додатних значень, розділених комами, де останні два розділено словом «або»
parseDate(X,PAT) повертає значення дати з рядка X, розібраного за шаблоном формату дати Java PAT
parseNumber(X,PAT) повертає числове значення з рядка X, розібраного за шаблоном формату чисел Java PAT
showAllResponsesExcept( questionList,attributeList,attributeTitleList) »; attributeList = список атрибутів, розділений символом «|» (як-от question#, title, text, type — щоб ви могли вирішити, що показувати); attributeTitleList = список заголовків таблиці, розділений символом «|», щоб можна було локалізувати звіт.
showTheseResponses( questionList,attributeList,attributeTitleList) »; attributeList = список атрибутів, розділений символом «|» (як-от question#, title, text, type — щоб ви могли вирішити, що показувати); attributeTitleList = список заголовків таблиці, розділений символом «|», щоб можна було локалізувати звіт.

Expression Manager знає, які змінні є локальними

Щоб правильно побудувати JavaScript для сторінки, Expression Manager має знати, які змінні встановлюються на сторінці та який у них 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

  1. q1 не додається до виразу LEManyNA()
  2. LEMval('q1') і надалі перевірятиме, чи відповідь релевантна, і повертатиме '', якщо ні (тобто окремі нерелевантні відповіді ігноруватимуться, але не зроблять недійсним увесь вираз).

Отже, розв'язання проблеми поточної суми — використати рівняння sum(q1.NAOK,q2.NAOK,q3.NAOK,...,qN.NAOK).

Використання суфікса .NAOK також дає змогу авторам створювати опитування з кількома можливими шляхами, які пізніше сходяться на спільних шляхах. Наприклад, припустімо, що респонденти відповідають на опитування так, що це виходить за межі звичайного діапазону відповідей. Автор може попередити респондентів, що вони можуть не отримати достовірних результатів, і запитати, чи справді вони хочуть продовжити опитування. Якщо вони відповідають «Так», решта питань буде показана. Умова для «решти питань» перевірятиме, чи початкові відповіді були в межах звичайного діапазону, АБО чи респондент відповів «Так» на питання, яке релевантне лише тоді, коли відповіді виходили за межі діапазону.

Як Expression Manager підтримує умовне мікроадаптування (micro-tailoring)?

Ось приклад мікроадаптування (де Question Type=='expr' означає рівняння):

Код питання Релевантність Тип питання Питання
name 1 text What is your name?
age 1 text How old are you?
badage !is_empty(age) expr {(age<16) or (age>80)}
agestop badage message Sorry, {name}, you are too {if( (age<16),'young',if( (age>80),'old','middle-aged') ) } for this test.
kids !badage yesno Do you have children?
parents 1 expr {!badage && kids=='Y'}
numKids parents text How many children do you have?
kid1 parents && numKids >= 1 text How old is your first child?
kid2 parents && numKids >= 2 text How old is your second child?
kid3 parents && numKids >= 3 text How old is your third child?
kid4 parents && numKids >= 4 text How old is your fourth child?
kid5 parents && numKids >= 5 text How old is your fifth child?
sumage 1 expr {sum(kid1.NAOK,kid2.NAOK,kid3.NAOK,kid4.NAOK,kid5.NAOK)}
report parents yesno {name}, you said you are {age} and that you have {numKids}. The sum of ages of your first {min(numKids,5)} kids is {sumage}

Усі ці питання можуть бути на одній сторінці (наприклад, в одній групі), і відображатимуться лише релевантні питання. Більше того, коли ви вводите вік дітей, вираз sum() в останньому питанні динамічно оновлюватиметься на сторінці.

Expression Manager забезпечує цю функціональність, обгортаючи кожен вираз в іменований елемент <span>. Щоразу, коли значення змінюється, він перераховує вираз, який має відображатися в цьому елементі <span>, і заново формує відображення. На одній сторінці може бути десятки або навіть сотні таких адаптованих виразів, і сторінка оновить їх усі за одне перемалювання екрана.

Відповідність функціональності LimeSurvey 1.91+ та Expression Manager

Стара функція Нова функція Коментарі
Умови Релевантність Ви можете використовувати дуже складні умовні рівняння та мати доступ до ширшого діапазону змінних
Оцінювання Рівняння Будь-які бали оцінювання можна переструктурувати в рівняння. Це гарантує запис балу в базу даних і дає змогу бачити динамічні зміни значення балу на поточній сторінці
Заміни Expression Manager Основний рушій приймає вхідний рядок і розглядає все в фігурних дужках як вираз, тому він обробляє всі історичні типи замін. Щоб не зіпсувати вбудований JavaScript, Expression Manager обробляє вміст між фігурними дужками лише за умови, що (a) у фігурних дужках немає пробілів на початку чи в кінці — наприклад, {expr} є виразом, але { expr}, {expr } і { expr } не є виразами. Крім того, Expression Manager не обробляє вміст усередині власних рядків (наприклад, {list('hi','there {braces}')} генерує «hi there {braces}»). Він також ігнорує екрановані фігурні дужки (наприклад, \{this is not an expression\})
Перевірка Expression Manager План полягає в тому, щоб взяти поточні атрибути питання min/max і обробляти їх за допомогою Expression Manager. Так самі значення min/max можуть бути виразами

Підсвічування синтаксису

Щоб допомогти у введенні та перевірці виразів, EM пропонує підсвічування синтаксису з такими можливостями:

Типи та значення підсвічування синтаксису

Колір Приклад Значення Підказка Коментарі
жовтувато-коричневий фон Sample усе рівняння немає Усе, що розміщено у фігурних дужках і розпізнається як рівняння (тобто немає пробілів на початку чи в кінці), позначається жовтувато-коричневим фоном, щоб відрізнити його від навколишнього тексту
жирний червоний текст Sample Помилка Пояснення помилки Може бути невідома змінна або помилка у функції тощо. Опитування може повністю не працювати, але це не показується публічним користувачам.
синій текст Sample назва функції значення та допустимий синтаксис назви функцій, або те, що має бути функціями, оскільки далі йде відкрита дужка, відображаються жирним синім текстом. Підказки показують значення та допустимий синтаксис функції.
сірий текст Sample рядок немає рядки в одинарних і подвійних лапках відображаються сірим текстом
блакитний текст Sample змінна, задана на цій самій сторінці, [ім'я або код SGQA]: питання; значення; список відповідей із кодами для кожного значення Будь-яка змінна, задана на тій самій сторінці, що й поточне питання, відображається блакитним текстом, що означає, що її можна оновлювати в JavaScript. Підказка показує її ім'я, саме питання та поточне значення (або порожньо, якщо не задано). Якщо тип питання передбачає відповіді з переліку значень, показується відповідність кодів значенням, що відображаються.
зелений текст Sample змінна, задана на попередній сторінці [ім'я або код SGQA]: питання; значення; список відповідей із кодами для кожного значення Будь-яка змінна, задана на попередній сторінці, відображається жирним зеленим текстом. Підказка показує її ім'я, саме питання та поточне значення (або порожньо, якщо не задано). Якщо тип питання передбачає відповіді з переліку значень, показується відповідність кодів значенням, що відображаються.
жирний рожевий текст Sample змінна, задана на наступній сторінці як правило: порожня на початку опитування, але може бути заповнена через індекс або перехід назад [ім'я або код SGQA]: питання; значення; список відповідей із кодами для кожного значення Будь-яка змінна, задана на наступній сторінці, відображається жирним рожевим текстом. Підказка показує її ім'я, саме питання та поточне значення (або порожньо, якщо не задано). Якщо тип питання передбачає відповіді з переліку значень, показується відповідність кодів значенням, що відображаються.
жирний коричневий текст Sample значення заміни LimeSurvey значення Рядки заміни Lime (як-от {TOKEN:xxx}, {PRIVACY_MESSAGE}) відображаються жирним коричневим текстом.
червоний текст Sample оператор присвоєння (=) попередження Якщо ви використовуєте оператор присвоєння (=), він відображається червоним текстом. Це допомагає запобігти випадковому перепризначенню значень, коли ви насправді хотіли перевірити, чи a == b, а не встановити значення a = b.
звичайний чорний текст Sample розділові знаки немає Усі інші розділові знаки у виразі відображаються звичайним чорним текстом.
текст у червоній рамці жирна червона лінія оточує помилку синтаксична помилка опис помилки Будь-які виявлені синтаксичні помилки позначаються червоною рамкою навколо помилки. Підказка показує саму помилку. Приклади: незакриті дужки, використання невизначених функцій, передавання неправильної кількості аргументів у функції, погано структуровані вирази (наприклад, пропущені оператори між змінними), спроба присвоїти нове значення змінній лише для читання, спроба присвоїти значення не змінним або використання синтаксису, що не підтримується. Зауважте, що система виявлення синтаксичних помилок може повідомити лише про одну помилку у виразі, навіть якщо їх кілька; проте, якщо помилки виявлено, буде показано щонайменше одну.

Додаткові матеріали

Зразки опитувань Expression Manager

Сценарії використання та інструкції

Покрокові приклади

Статистичні функції Expression Manager

Довідник для розробників

Дорожня карта/Статус/Список завдань