Редактор анкет
- Новости
- Вход
- Документы
- Создание опроса
- Добавление
- Добавление вопроса
- Добавление вопроса с мультивыбором
- Ротация ответов
- Добавление своего варианта ответа
- Редактирование связанных вопросов
- Добавление табличного вопроса
- Условия видимости
- Тестирование опроса
- Редактирование квот
- Добавление сотрудников органицации
- Управление интервьюерами в опросе
- Использование мобильного устройства
- Прохождение он-лайн опроса
- Контроль интервью
- Выгрузка массива
- Контроль интервьюеров
- Сохранение прерванных интервью
- Продолжение прерванных интервью
- Справочники
- Управление пользователями
- Редактор
- Версии опроса
- Информирование
- Режим интервьюера
- Использование пользовательских кодов вопроса
- Кан-бан
- Статусы опросов
- Список опросов
- Просмотр результатов
- Контроль результатов
- Вычисляемый текст
- PEXL
- Redirects / HOOKs
Новости
Обновление дашборда: детализированные графики
Дата выхода: 31 марта 2026
Что нового
Stacked-графики
В столбчатых графиках теперь доступен режим детализации — stacked. Каждый столбец разбивается на цветные сегменты по вопросу детализации, что позволяет видеть не только общий результат, но и его структуру в одном графике.
Режим работает как для вертикальных, так и для горизонтальных столбчатых графиков. Включается в настройках блока дашборда.
Итоговые значения над столбцами
В столбчатых графиках с детализацией теперь отображается суммарное значение над каждым столбцом. Это позволяет быстро оценить общий результат, не складывая сегменты вручную.
Работает как для вертикальных, так и для горизонтальных столбчатых графиков.
Упорядоченная легенда
Элементы легенды теперь отображаются в стабильном, предсказуемом порядке — одинаковом при каждом открытии графика.
Вход
Для входа в систему необходимо пройти авторизацию
Документы
Общие документы
Краткое описание
ПЭВМ_Социометр_Краткое_описание_ПЭВМ.pdf
Описание функционала
ПЭВМ_Социометр_Описание_функционала_ПЭВМ.pdf
Руководство пользователя
ПЭВМ_Социометр_Руководство_пользователя.pdf
Создание опроса
Создать и протестировать опрос
Добавление
Добавить новый |
|
Назвать |
|
Открыть существующий |
Добавление вопроса
Добавление приветствия с комментарием для интервьюера. |
|
Добавление вопроса |
Добавление вопроса с мультивыбором
1. Необходимо добавить вопрос и ответы к нему |
|
2. Включить мультивыбор. |
|
Ротация ответов
Включение ротации обеспечивает случайный порядок вариантов ответов для каждого интервью
Включение ротации для всех ответов |
|
Исключение ответа из ротации |
Добавление своего варианта ответа
Свой ответ - ответ сформулированный респондентом
Открыть свойство ответа |
|
Установить тип |
|
|
|
Редактирование связанных вопросов
Связанный вопрос - вопрос, варианты ответа которого, зависят от ответов вопроса-селектора
Выбор вопроса-селектора |
|
Выбор возможных вариантов ответа |
|
|
При ответе "Рыбки" в вопросе Q4 будут доступны ответы A7 и A8 в вопросе Q5 |
|
Просмотр установленных связей |
|
Печать карточки |
Добавление табличного вопроса
Настройка ротации строк |
|
Включение ротации столбцов |
|
Установка условий видимости строки |
|
Установка условий видимости столбцаУсловия видимости столбцов применяются для всех строк таблицы |
Условия видимости
На вопрос |
|
На вариант ответа |
|
На строку таблицы |
|
На столбец таблицы |
|
В свойства секцииПредварительно секцию требуется создать ! |
Тестирование опроса
Запуск просмотра |
|
Установка закладки |
|
Переход на установленную закладку |
Редактирование квот
Типы квот
Базовая - Для опроса устанавливается общее количество интервью
Разрешить редактирование |
|
Установить кол-во интервью и сохранить |
Общая - для опроса устанавливается требуемое количество ответов по квотным вопросам
Индивидуальная - то-же что и базовая, но требуемое количество интервью устанавливается индивидуально для каждого интервьюера
Добавление сотрудников органицации
Добавить в свою организацию |
|
Установка логина/пароля и периода активности (актуально для временных сотрудников ) |
|
Управление интервьюерами в опросе
Если интервьюеров еще нет в сотрудниках организации - их необходимо добавить
Разблокировка внесения изменений на закладке "Интервьюеры" |
|
Добавить |
|
Сохранить изменения |
|
Установить требуемое кол-во интервью |
|
Равномерно распределить остаток несобранных интервью между всеми интервьюерами |
|
Выключить интервьюера из опросаИнтервью от этого интервьюера больше не принимаются, все принятые - сохраняются, непринятые интервью возвращаются в общий пул и готовы для распределения по остальным интервьюерам. |
|
Заморозить интервьюераВыключить интервьюера из автоматического распределения. |
Использование мобильного устройства
Описание находится в соотв. разделе. ссылка
Прохождение он-лайн опроса
Для прохождения онлайн опроса необходимо добавить как минимум одного интервьюера с назначенной ролью web-inter в опрос, получить ссылку на опрос и передать ее любым способом респонденту.
Получение единой ссылки на опросПо этой ссылке может быть сформировано неопределенное количество интервью |
|
Выбрать создание индивидуальных ссылокПо ссылке такого типа может быть сформировано настраиваемое количество интервью |
|
Позволяет интервьюеру принимать интервью используя браузер.Требуется on-line! |
|
Создать 5 различных ссылок на опрос |
|
Ссылки можно копировать индивидуально или экспортировать весь массив в таблицу |
При выгрузке массива интервью ссылка на каждое будет находится в соответствующем столбце таблицы.
Контроль интервью
Переключение на страницу "Результаты" |
|
| Для просмотра интервью целиком его можно открыть | |
| Просмотр одиночного интервью | |
Выгрузка массива
Контроль интервьюеров
Посмотреть местонахождение всех интервьюеров опроса |
|
Посмотреть маршрут выбранного интервьюера |
|
Написать интервьюеру сообщение |
|
Дать команду мобильному устройству интервьюера |
|
Пример получения статуса |
Сохранение прерванных интервью
При прохождении интервью возможно сохранение прерванных анкет
Работает как для web-интервью, так и для мобильного приложения
Включение |
|
Поиск незаконченных интервью |
|
Выгрузка результатов |
Продолжение прерванных интервью
Продолжение прерванного интервью происходит при переходе по web-ссылке созданной в процессе прохождения анкеты.
Включение в свойствах опроса |
|
Получение ссылки в приложении |
|
При on-line прохождении |
|
Справочники
Управление пользователями
Просмотр
| Общий список | |
| Заблокированные |
Экспорт
| Экспорт | |
| Скопировать в буфер обмена |
Импорт
| Импорт | |
| Вставить таблицу из буфера обмена | |
| Формат таблицы |
Найти интервьюеров на карте
| Всех | |
| Фильтры по времени |
Редактор
Навигация
Общий список |
|
Результаты |
|
Фильтр по статусам |
|
Групповая выгрузка отчетов |
Свойства опроса
Открытие |
|
Редактирование |
|
Просмотр имеющихся версий и смена активной. |
Вопросы анкеты
Свойства вариантов ответов
-
- Автозаполняемое поле - Выбранный вариант ответа устанавливается автоматически. Как правило применяется для вычисляемых значений
- Взять ответ из предыдущего интервью - Значение ответа берется только в первом интервью в серии. Например ответ на вопрос "В каком городе происходит опрос" как правило требуется отвечать только один раз в серии интервью.
- Нецелевое интервью - При выборе этого ответа все интервью маркируется как нецелевое (окончания интервью не происходит !). Для прекращения интервью необходимо сделать явный переход на окончание анкеты.
- Ответ исключение - При выборе этого ответа выбор с остальных вариантов ответа в текущем вопросе принудительно снимается ( актуально только для множественных вопросов )
- Код пользователя - При установке одинаковых пользовательских кодов для ответов в разных опросах возможно создание одного отчета по нескольким опросам. см
- Открытый ответ - Респондент дает свой вариант ответа. Может иметь типы:
- Текст
- Большой текст ( в приложении открывается многострочное поле для ввода )
- Число
- Календарь
- Дата
- Время
- Дата/Время
- Шкала
- Рейтинг
Ответы
Редактирование ответов
Не забудьте открыть вопрос на редактирование !
-
Добавление варианта ответа
-
Свойства ответа
-
- Автозаполняемое поле - Выбранный вариант ответа устанавливается автоматически. Как правило применяется для вычисляемых значений. В качестве значения может использоваться вычисляемый текст ( @@Q1.A - первый ответ на вопрос Q1 )
- Взять ответ из предыдущего интервью - Значение ответа берется только в первом интервью в серии. Например ответ на вопрос "В каком городе происходит опрос" как правило требуется отвечать только один раз в серииинтервью.
- Нецелевое интервью - При выборе этого ответа все интервью маркируется как нецелевое (окончания интервью не происходит !). Для прекращения интервью необходимо сделать явный переход на окончание анкеты.
- Ответ исключение - При выборе этого ответа выбор с остальных вариантов ответа в текущем вопросе принудительно снимается (актуально только для множественных вопросов)см.
- Код пользователя - При установке одинаковых пользовательских кодов для ответов в разных опросах возможно создание одного отчета по нескольким опросам. см. гупповую выгрузку отчетов
-
Свой вариант ответа
-
- Установка варианта ответа значение которого определяется во время интервью.
- Для разных типов данных в процессе интервью будет показан соответствующий виджет.
Для ответа типа РЕЙТИНГ
Возможно установка специального типа виджета позволяющего принимать нулевые значения
В интервью выгляди следующим образом :
-
Редактирование перехода на другой вопрос.
Доступно для ответов типа одиночный выбор и для исключительных вариантов ответа в вопросах с мультивыбором.
При редактировании ответа возможно сразу установить переход на другой вопрос анкеты
Переходы
Типы
Безусловный
При получении ответа
Создание
Удаление
Навигация
Результаты
Список собранных анкет |
|
Развернуть способы просмотра |
|
Разворачивать каждое интервью |
|
Координаты принятого интервью |
|
Координаты IP адреса принятого интервьюТочность может быть низкой, зависит от поставщика услуги геопривязки и/или использования интервьюером VPN. |
|
Сводная таблица |
|
Выгрузка отчетов |
|
Подключение внешних систем BI |
Квоты
Вычисляемый текст
Секции
Группы вопросов могут объединятся в секции. Это полезно делать для вопросов связанных одной темой ( например вопросы для респондентов проживающих в определенном районе городе )
Создание |
|
Просмотр имеющихся и навигация |
|
Версии опроса
Информирование
Уведомления рассылаются по всем установленным у пользователя каналам информирования при возникновении одного из событий.
Каналы информирования
-
Telegram
-
E-mail
События
-
Изменения статуса опроса
-
Создание новой версии опроса
Настройка
Привязать Telegram в своем профиле |
|
Включить информирование в свойствах опроса |
Режим интервьюера
Предназначен для временного выключения отображения некоторых вариантов ответа. Используется при показе анкеты респонденту.
Включить в свойствах вопроса |
|
Включить в свойствах вариантов ответа |
|
В приложении |
Использование пользовательских кодов вопроса
UserCode - Код вопроса определяемый пользователем
| Включение и редактирование | |
Кан-бан
Табличное представление опросов при котором:
-
Опросы распределяются по столбцам таблицы в зависимости от текущего статуса.
-
Для каждого столбца настраивается набор статусов опросов отбираемых в этот столбец.
-
При перетаскивании опроса в столбец ему устанавливается статус столбца (или статус по умолчанию, если их несколько).
-
Каждый опрос в один момент времени может находится только в одном столбце
-
Каждый статус может иметь владельца(ов). Если владелец статуса установлен - только он может его назначить опросу.
Для каждого столбца настраивается набор статусов опросов отбираемых в этот столбец
Общий вид доски |
|
Настройка столбцов |
|
Смена статусов возможна как напрямую, так и перетаскиванием опроса в целевой столбец |
|
Переключение между досками и создание новых |
|
После поступления интервью происходит автоматическое обновление счетчиков |
Статусы опросов
Общие положения:
Статус опроса определяет текущее положение опроса в его жизненном цикле.
Каждая организация может иметь свой собственный набор статусов.
Каждый статус может иметь владельца(ов).
Если владелец установлен, только он может назначить этот статус опросу.
Таким образом, можно назначать например круг ответственных за запуск опроса в работу.
Каждый статус опроса привязан к одному из системных статусов.
Просмотр существующих |
|
Редактирование |
|
Список опросов
Общий вид
Общий вид |
|
Фильт по статусам и префиксам |
|
Теги опроса |
|
Облако тегов |
|
Счетчик анкет |
|
Переход в результаты и дашборды опроса |
Просмотр результатов
Просмотр и прослушивание интервью
Список интервью |
|
Выделить столбец для удобства контроля и автоперематываться на него. |
|
Прослушивание |
|
Прослушать предыдущий/следующий ответ в текущем интервью |
|
Прослушать текущий ответ в предыдущем/следующем интервью |
|
Перемотка вперед-назад и скорость воспроизведения |
|
Скачать аудио-запись |
Контроль
Интервью проверено, идет в зачет. |
|
Вопрос требует дальнейшего изучения |
|
Брак. Интервью, помечается нецелевым, в квоте не участвует. |
|
Поиск интервью по результату проверки |
Дашборды
| Список дашбордов опроса | |
| Редактирование свойств дашборда | |
| Ссылка публичного доступа к дашборду ( без авторизации ). Действует только в разрешенный период. | |
| Добавление нового графика на дашборд | |
| Выбор типа графика |
Контроль результатов
4к34к
ваыва
Вычисляемый текст
При необходимости подставить в текст вопроса, ответа, комментария, строки таблицы. столбца таблицы имеющиеся в текущем интервью ответы на вопросы можно использовать Вычисляемый текст. Вычисляемый текст всегда начинается с символов "@@", после которого идет код вопроса/ответа
@@Q5 |
Текст Вопроса Q5 |
@@Q5.A2 |
Текст Ответа 2 на вопрос 5 |
@@Q3.R5 |
Текст в строке 5 табличного вопроса 3 |
@@Q3.R5.A4 |
Текст в ответе 4 строки 5 табличного вопроса 3 |
Коды вопросов/ответов можно набирать на клавиатуре, а можно пользоваться окном подсказки, открывающимся при вводе "@@"
PEXL
Синтаксис PEXL
PEXL (Poll Expression Language) — язык выражений для доступа к данным интервью, сравнения значений, логических условий, работы с переменными, параметрами, тегами ответов, подсчётами и псевдослучайными значениями.
Документ описывает синтаксис, реально поддерживаемый грамматикой pexl.g, парсером pexl.js и тестами проекта.
1. Общая модель выражений
Выражение PEXL вычисляется в контексте объекта interview и возвращает одно значение:
-
true/falseдля логических и сравнительных выражений; - строку;
- число;
-
null, если значение не найдено; - иногда объект вопроса или ответа как внутреннее промежуточное значение, но в типовых пользовательских выражениях обычно используются строка, число или булево значение.
Примеры:
Q1
Q1 == "Q one"
Q1.A3 == "A three"
Q5.A >= 22
PARAM("PARAM1") == "PAR1"
$X = RAND(1, 10)
2. Лексические элементы
2.1. Пробелы
Пробельные символы допускаются между токенами и игнорируются.
Примеры:
Q1.A3=="A three"
Q1.A3 == "A three"
Q1 . A3
Практически использовать стоит обычную читаемую запись без разрыва внутри ссылок вида Q1.A3.
2.2. Числа
Поддерживаются только целые числа:
0
1
22
100500
Формально: последовательность цифр \d+.
Отрицательные, дробные и экспоненциальные числа синтаксисом не предусмотрены.
2.3. Строки
Поддерживаются строковые литералы в двойных кавычках:
"Hello"
"A three"
"06bf20de-9658-4afd-9e7b-d712697ccdc7"
Также лексер распознаёт литералы в одинарных кавычках, но в грамматике языка они не используются как допустимые значения выражений. Поэтому в корректном PEXL следует использовать двойные кавычки.
2.4. Ключевые слова и служебные токены
Поддерживаются следующие ключевые слова и служебные конструкции:
-
AND -
OR -
NOT -
PARAM -
VAR -
QUUID -
ATUUID -
AQUUID -
TATUUID -
TAQUUID -
CQUUID -
CRUUID -
RAND -
COUNT -
Q -
R -
A -
T.<TAG_NAME>
2.5. Операторы и знаки пунктуации
-
== -
!= -
< -
> -
<= -
>= -
= -
( -
) -
. -
,
3. Базовая грамматика выражений
На верхнем уровне PEXL поддерживает два больших класса выражений:
- вычисление/сравнение значения;
- присваивание переменной.
Упрощённо:
STMT ::= STMT == STMT
| STMT != IVALUE
| STMT < IVALUE
| STMT > IVALUE
| STMT <= IVALUE
| STMT >= IVALUE
| STMT AND STMT
| STMT OR STMT
| NOT STMT
| ( STMT )
| IVALUE
| ASSIGN_VALUE
Где IVALUE — это обычное вычисляемое значение, а ASSIGN_VALUE — присваивание переменной.
4. Приоритет операторов
Согласно грамматике проекта, используются такие приоритеты:
-
NOT— самый высокий; - сравнения:
==,!=,<,<=,>,>=; -
OR; -
AND; -
=(присваивание).
Важно: приоритеты в
pexl.gзаданы не совсем так, как в большинстве языков программирования. Для сложных выражений рекомендуется всегда явно ставить скобки.
Примеры безопасной записи:
Q1.A3 AND (NOT Q2.A1)
(Q1.A3 == "A three") AND (Q2.A1 == "A one")
($X = RAND(1, 10)) AND ($X >= 1)
5. Допустимые виды значений (IVALUE)
IVALUE может быть одним из следующих типов:
- значение вопроса;
- значение ответа;
- текст ответа;
- значение тега ответа;
- количество ответов;
- значение параметра;
- значение переменной;
- доступ по UUID;
- результат
RAND; - числовой литерал;
- строковый литерал.
Подробно — ниже.
6. Ссылки на вопросы
6.1. Вопрос Qx
Форма:
Q<number>
Примеры:
Q1
Q2
Q10
Семантика:
- возвращает вопрос по
questionCode; - в сравнении используется
question.question— текст вопроса; - в булевом контексте истинно, если вопрос найден.
Примеры:
Q1
Q1 == "Q one"
NOT Q123
6.2. Строка табличного вопроса Qx.Ry
Форма:
Q<number>.R<number>
Примеры:
Q3.R1
Q3.R2
Семантика:
- возвращает вопрос-строку таблицы;
- в сравнении используется текст вопроса этой строки.
Примеры:
Q3.R1 == "Q three R one"
Q3.R2
7. Ссылки на ответы
7.1. Конкретный ответ Qx.Ay
Форма:
Q<number>.A<number>
Пример:
Q1.A3
Семантика:
- ищет ответ с кодом
Ayу вопросаQx; - возвращает объект ответа;
- при сравнении используется
answerText; - если
answerTextвыглядит как целое число, при некоторых сравнениях он будет приведён к числу.
Примеры:
Q1.A3 == "A three"
Q7.A3 == 22
7.2. Конкретный ответ в строке таблицы Qx.Ry.Az
Форма:
Q<number>.R<number>.A<number>
Пример:
Q3.R1.A3
Примеры использования:
Q3.R1.A3 == "A three"
Q3.R2.A1
8. Текст ответа
8.1. Первый/основной текст ответа вопроса Qx.A
Форма:
Q<number>.A
Пример:
Q5.A
Семантика:
- возвращает
answerTextпервого подходящего ответа вопроса; - если текст числовой, в ряде операций используется как число.
Примеры:
Q1.A == "A three"
Q5.A == 22
Q5.A >= 22
8.2. Текст ответа строки таблицы Qx.Ry.A
Форма:
Q<number>.R<number>.A
Пример:
Q3.R2.A
Примеры:
Q3.R2.A == "33"
Q3.R1.A == "A three"
9. Теги ответов
Тег кодируется как специальный токен вида:
T.<TAG_NAME>
Допустимые символы имени тега: буквы, цифры, _, -.
Примеры:
T.A_TAG_INT
T.A_TAG_STR
T.score-1
9.1. Тег конкретного ответа Qx.Ay.T.TAG
Форма:
Q<number>.A<number>.T.<TAG>
Q<number>.R<number>.A<number>.T.<TAG>
Примеры:
Q1.A3.T.A_TAG_INT
Q3.R1.A3.T.A_TAG_STR
Семантика:
- возвращает значение тега из
answerTags[tag]; - если значение тега числовое, оно приводится к числу;
- если тега нет, возвращается
null.
Примеры:
Q1.A3.T.A_TAG_INT == 55
Q1.A3.T.A_TAG_STR == "Tag value"
9.2. Тег первого/основного ответа вопроса Qx.A.T.TAG
Форма:
Q<number>.A.T.<TAG>
Q<number>.R<number>.A.T.<TAG>
Примеры:
Q1.A.T.A_TAG_INT
Q3.R1.A.T.A_TAG_STR
Семантика:
- перебирает ответы вопроса и возвращает первый найденный тег с таким именем;
- если тег нигде не найден, возвращает
null.
Примеры:
Q1.A.T.A_TAG_INT == 55
Q1.A.T.A_TAG_STR == "Tag value"
10. Подсчёт количества ответов
10.1. Количество ответов вопроса Qx.COUNT
Форма:
Q<number>.COUNT
Пример:
Q2.COUNT
Семантика:
- возвращает число ответов вопроса;
- в циклическом контексте результат зависит от
loopType.
Примеры:
Q2.COUNT == 4
Q6.COUNT == 6
10.2. Количество ответов строки таблицы Qx.Ry.COUNT
Форма:
Q<number>.R<number>.COUNT
Пример:
Q3.R1.COUNT
10.3. Количество заполненных строк таблицы Qx.R.COUNT
Форма:
Q<number>.R.COUNT
Пример:
Q3.R.COUNT == 3
Семантика:
- считает количество дочерних вопросов, чьи коды начинаются с
Qx.R.
11. Доступ по UUID
11.1. Вопрос по UUID: QUUID("...")
Форма:
QUUID("<question_uuid>")
Семантика:
- ищет вопрос по
questionId; - в сравнении используется текст вопроса.
Примеры:
QUUID("06bf20de-9658-4afd-9e7b-d712697ccdc7")
QUUID("06bf20de-9658-4afd-9e7b-d712697ccdc7") == "Q one"
11.2. Конкретный ответ по UUID: ATUUID("...")
Форма:
ATUUID("<answer_template_uuid>")
Семантика:
- ищет ответ по
templateAnswerId; - в сравнении используется
answerText.
Примеры:
ATUUID("a2101b08-b18e-4137-abb0-5eb2e44d751e")
ATUUID("a2101b08-b18e-4137-abb0-5eb2e44d751e") == "A three"
11.3. Текст ответа по UUID: AQUUID("...")
Форма:
AQUUID("<question_uuid>")
Семантика:
- возвращает текст первого/основного ответа вопроса по UUID вопроса;
- для числовых строк поддерживаются числовые сравнения.
Примеры:
AQUUID("06bf20de-9658-4afd-9e7b-d712697ccdc7") == "A three"
AQUUID("c82d8380-cae4-43c1-93be-3cf5a06449f3") >= 22
11.4. Тег конкретного ответа по UUID: TATUUID("answerUuid", "TAG")
Форма:
TATUUID("<answer_template_uuid>", "<TAG>")
Примеры:
TATUUID("a2101b08-b18e-4137-abb0-5eb2e44d751e", "A_TAG_INT") == 55
TATUUID("a2101b08-b18e-4137-abb0-5eb2e44d751e", "A_TAG_STR") == "Tag value"
11.5. Тег первого/основного ответа вопроса по UUID: TAQUUID("questionUuid", "TAG")
Форма:
TAQUUID("<question_uuid>", "<TAG>")
Примеры:
TAQUUID("06bf20de-9658-4afd-9e7b-d712697ccdc7", "A_TAG_INT") == 55
TAQUUID("06bf20de-9658-4afd-9e7b-d712697ccdc7", "A_TAG_STR") == "Tag value"
11.6. Количество ответов вопроса по UUID: CQUUID("...")
Форма:
CQUUID("<question_uuid>")
Примеры:
CQUUID("06bfcccc-9658-4afd-9e7b-d712697ccdc7") == 6
11.7. Количество строк таблицы по UUID: CRUUID("...")
Форма:
CRUUID("<table_uuid>")
Примеры:
CRUUID("7a33bdab-d53b-4958-a293-60e3fded8aa8") == 3
12. Параметры интервью
Форма:
PARAM("<name>")
Примеры:
PARAM("PARAM1")
PARAM("PARAM1") == "PAR1"
PARAM("PARAM1") == PARAM("param2")
Семантика:
- читает
interview.params[name]; - регистр имени зависит от того, как значения реально хранятся в объекте
params.
13. Переменные
PEXL поддерживает две формы обращения к переменным.
13.1. Переменная вида $NAME
Форма:
$<name>
Допустимые символы имени: буквы, цифры, _, -.
Примеры:
$VAR1
$var2
$MY-VAR
Чтение:
$VAR1 == "VAL1"
Присваивание:
$VAR3 = "Test3"
$N = 22
$X = Q1
$Y = Q3.R1.A3
$R = RAND(1, 10)
13.2. Переменная вида VAR("NAME")
Форма:
VAR("<name>")
Примеры:
VAR("VAR1")
VAR("var2") == "val2"
VAR("VAR4") = "Test4"
VAR("VAR_QQ") = Q1
Семантика у $NAME и VAR("NAME") общая:
- чтение идёт из
interview.vars[name]; - запись идёт в
interview.vars[name].
13.3. Что можно присваивать переменной
Правая часть присваивания может быть:
- строкой;
- числом;
- вопросом
Q.../QUUID(...)— в переменную попадёт текст вопроса; - ответом
Q...A.../ATUUID(...)— в переменную попадётanswerText; -
COUNT-значением; - tag-значением;
-
Qx.A/Qx.Ry.A/AQUUID(...); - другой переменной;
-
RAND(...).
Примеры:
$VAR3 = "Test3"
$VAR_Q = Q1
$VAR_Q = Q3.R1.A3
$MY = $VAR3
VAR("VAR4") = "Test4"
VAR("VAR_QQ") = Q1
14. Псевдослучайные значения
14.1. Короткая форма RAND(n)
Форма:
RAND(<max>)
Семантика:
- возвращает целое число в диапазоне от
1доnвключительно.
Пример:
RAND(5)
14.2. Полная форма RAND(min, max)
Форма:
RAND(<min>, <max>)
Семантика:
- возвращает целое число в диапазоне
[min, max]включительно; - если аргументы переданы в обратном порядке, фактически используются
Math.minиMath.max.
Примеры:
RAND(3, 7)
RAND(42, 42)
$X = RAND(1, 100)
RAND(10, 20) >= 10 AND RAND(10, 20) <= 20
Особенность реализации:
- генератор детерминированно инициализируется от
interview.id; - для одного и того же
interview.idрезультат воспроизводим между запусками; - если
interview.idотсутствует, используется резервный seed.
Совместимость с конвертерами:
-
RAND(...)корректно проходит черезconvert2UUID(выражение → UUID-форма для хранения в БД) иconvert2QA(UUID-форма → читаемая форма для отображения); - внутри
RAND(...)нет ничего, что нужно конвертировать в UUID, поэтому литерал просто пробрасывается без изменений; - допускается использование
RANDв любых выражениях, которые сохраняются в poll-объекте: условиях ветвления, присваиваниях переменным и т.д.
15. Операторы сравнения
Поддерживаются:
-
== -
!= -
< -
> -
<= -
>=
Примеры:
Q1 == "Q one"
Q1.A3 == "A three"
Q5.A != 20
Q5.A < 123
Q5.A <= 22
Q5.A > 21
Q5.A >= 22
15.1. Правила сравнения
Реализация сравнения устроена так:
- Левая часть должна быть truthy, иначе результат выражения будет ложным.
- Если и левое, и правое значения распознаются как целые числа, сравнение выполняется как числовое.
- Иначе сравнение выполняется как обычное JS-сравнение значений/строк.
Примеры числового сравнения:
Q7.A3 == 22
Q7.A3 < Q7.A4
Q5.A >= 22
Примеры строкового сравнения:
Q7.A1 == "AAAA"
Q7.A1 < Q7.A2
15.2. Сравнение значения слева и справа
С обеих сторон могут стоять не только литералы, но и выражения:
Q7.A1 == Q7.A1
"BBBB" == Q7.A2
22 == Q7.A3
PARAM("PARAM1") == PARAM("param2")
16. Логические операторы
16.1. AND
Форма:
<expr> AND <expr>
Примеры:
Q1.A3 == "A three" AND Q2.A1 == "A one"
Q1 == "Q one" AND Q3.R1 == "Q three R one"
Семантика: логическое И.
16.2. OR
Форма:
<expr> OR <expr>
Пример:
Q1 == "Q one" OR Q1 == "Wrong Q"
16.3. NOT
Форма:
NOT <expr>
Примеры:
NOT Q1
NOT Q123
NOT Q1.A3 == "A three"
Q1.A3 AND NOT Q2222.A1 AND Q5555.A2
16.4. Скобки
Форма:
( <expr> )
Примеры:
Q1 AND (Q1 == "Q one" OR Q1 == "Wrong Q")
Q1.A3 AND (Q2.A1 == "A one" OR Q1111.A111 == "Wrong Q")
Q1.A3 AND (NOT Q2222.A1) AND Q5555.A2
17. Поведение при отсутствии данных
Если вопрос, ответ, тег или переменная не найдены, обычно возвращается null.
Типичные последствия:
- просто выражение
Q123в булевом контексте считается ложным; -
NOT Q123даётtrue; - сравнение вида
Q111.A == "..."не обязано возвращать строгоfalse, потому что промежуточно может участвоватьnull.
Из тестов следует, что при проектировании выражений лучше явно учитывать возможность отсутствия значения.
18. Контекст циклов
Синтаксис выражения не меняется, но семантика поиска вопроса/ответа может зависеть от options, переданных в execute(...).
Поддерживаются режимы:
- без цикла;
-
loopType: "DOWHILE"; -
loopType: "FOREACH"; -
loopType: "NONE".
18.1. DOWHILE
Требует:
{ loopType: "DOWHILE", loopPass: <number> }
В этом режиме конструкции вроде:
-
Qx -
Qx.Ay -
Qx.A -
QUUID(...) -
ATUUID(...) -
AQUUID(...) -
CQUUID(...)
ищут данные внутри соответствующей итерации loopPass, а при необходимости могут использовать значения вне цикла как fallback.
Примеры выражений:
Q2 == "Q two 2"
Q2.A1 == "A one. LoopPass2"
Q2.A == "A one. LoopPass2"
QUUID("10264445-3949-41b3-8b87-4cc20bf6c5c0") == "Q two 2"
ATUUID("4a8e4bd6-7500-4195-a731-158780787d21") == "A two. LoopPass2"
18.2. FOREACH
Требует:
{ loopType: "FOREACH", iterationTemplateAnswerId: "<uuid>" }
В этом режиме поиск значения выполняется в контексте конкретной итерации iterationTemplateAnswerId.
Примеры:
Q6 == "Q Loop"
Q6.A1 == "A six one"
Q6.A == "A six one 2"
AQUUID("06bfcccc-9658-4afd-9e7b-d712697ccdc7") == "A six one 2"
Q6.COUNT == 3
18.3. Ошибки конфигурации цикла
Реализация execute() выбрасывает ошибку, если:
- указан
loopPassилиiterationTemplateAnswerId, но не указанloopType; -
loopType: "FOREACH"безiterationTemplateAnswerId; -
loopType: "DOWHILE"безloopPass; - указан неизвестный
loopType.
19. Полный каталог синтаксических форм
Ниже перечислены все поддерживаемые формы пользовательских выражений.
19.1. Литералы
123
"text"
19.2. Вопросы и ответы
Q1
Q3.R1
Q1.A3
Q3.R1.A3
Q1.A
Q3.R2.A
19.3. Теги
Q1.A3.T.A_TAG_INT
Q3.R1.A3.T.A_TAG_STR
Q1.A.T.A_TAG_INT
Q3.R1.A.T.A_TAG_STR
19.4. Подсчёты
Q2.COUNT
Q3.R1.COUNT
Q3.R.COUNT
19.5. UUID-функции
QUUID("question-uuid")
ATUUID("answer-uuid")
AQUUID("question-uuid")
TATUUID("answer-uuid", "TAG")
TAQUUID("question-uuid", "TAG")
CQUUID("question-uuid")
CRUUID("table-uuid")
19.6. Параметры и переменные
PARAM("PARAM1")
$VAR1
VAR("VAR1")
19.7. Присваивания
$X = "abc"
$X = 10
$X = Q1
$X = Q1.A3
$X = Q1.A
$X = Q1.A3.T.A_TAG_INT
$X = Q2.COUNT
$X = AQUUID("question-uuid")
$X = TAQUUID("question-uuid", "TAG")
$X = RAND(1, 10)
VAR("X") = "abc"
VAR("X") = Q1
VAR("X") = Q1.A3
19.8. RAND
RAND(5)
RAND(1, 10)
19.9. Логика и сравнения
Q1 == "Q one"
Q1.A3 != "Wrong"
Q5.A < 100
Q5.A <= 22
Q5.A > 10
Q5.A >= 22
NOT Q123
Q1 AND Q2
Q1 OR Q2
(Q1 AND Q2) OR Q3
20. Практические рекомендации
-
Используйте двойные кавычки для строк.
-
Для сложной логики всегда ставьте скобки.
-
Если значение может отсутствовать, учитывайте возможность
null. -
Для числовых сравнений используйте числовые литералы:
Q5.A >= 22
- Для читаемости разделяйте длинные выражения пробелами:
Q1.A3 == "A three" AND Q2.A1 == "A one"
21. Примеры полных выражений
Простые проверки
Q1
Q1.A3
NOT Q123
Сравнение вопросов и ответов
Q1 == "Q one"
Q1.A3 == "A three"
Q3.R1 == "Q three R one"
Q3.R1.A3 == "A three"
Работа с числовыми ответами
Q5.A == 22
Q5.A != 20
Q5.A < 123
Q5.A >= 22
Теги
Q1.A3.T.A_TAG_INT == 55
Q1.A.T.A_TAG_STR == "Tag value"
TATUUID("a2101b08-b18e-4137-abb0-5eb2e44d751e", "A_TAG_INT") == 55
TAQUUID("06bf20de-9658-4afd-9e7b-d712697ccdc7", "A_TAG_STR") == "Tag value"
Параметры и переменные
PARAM("PARAM1") == "PAR1"
$VAR1 == "VAL1"
VAR("VAR1") == "VAL1"
$TMP = Q1.A
VAR("N") = RAND(1, 100)
Сложная логика
Q1.A3 AND (Q2.A1 == "A one" OR Q1111.A111 == "Wrong Q")
Q1 AND (Q1 == "Q one" OR Q1 == "Wrong Q")
Q1.A3 AND NOT Q2222.A1 AND Q5555.A2
22. Краткая формальная сводка
Вопрос:
Qn
Qn.Rm
Ответ:
Qn.Am
Qn.Rm.Ak
Текст ответа:
Qn.A
Qn.Rm.A
Теги:
Qn.Am.T.TAG
Qn.Rm.Ak.T.TAG
Qn.A.T.TAG
Qn.Rm.A.T.TAG
Подсчёты:
Qn.COUNT
Qn.Rm.COUNT
Qn.R.COUNT
UUID:
QUUID("uuid")
ATUUID("uuid")
AQUUID("uuid")
TATUUID("uuid", "TAG")
TAQUUID("uuid", "TAG")
CQUUID("uuid")
CRUUID("uuid")
Параметры:
PARAM("name")
Переменные:
$NAME
VAR("NAME")
Присваивание:
$NAME = <value>
VAR("NAME") = <value>
RAND:
RAND(n)
RAND(min, max)
Логика:
expr AND expr
expr OR expr
NOT expr
(expr)
Сравнения:
expr == expr
expr != expr
expr < expr
expr > expr
expr <= expr
expr >= expr
23. Источник истины
Этот документ составлен по фактической реализации проекта:
-
pexl.g— исходная грамматика основного парсера; -
pexl.js— сгенерированный парсер и лексер; -
test_pexl.js— набор тестов, фиксирующий поддерживаемое поведение основного парсера; -
convert2UUID.g/convert2UUID.js— грамматика и парсер преобразования выражений с алиасами (Q1.A1) в UUID-форму для хранения в БД; -
convert2QA.g/convert2QA.js— грамматика и парсер обратного преобразования (UUID-форма → читаемые алиасы) для отображения; -
test_convert2UUID.js,test_convert2QA.js— тесты конвертеров.
Грамматики pexl.g, convert2UUID.g, convert2QA.g должны держаться в синхроне по набору поддерживаемых токенов и продакшнов: если в одной из них появляется новый оператор (например, RAND), его обязательно нужно добавить и в две другие, иначе сохранение/отображение выражений ломается.
Если реализация и документ когда-либо разойдутся, источником истины следует считать код и тесты.
Redirects / HOOKs
WEB интервью: Redirect/HK и входные параметры
Для чего это нужно
В WEB интервью ссылка для перехода (Redirect) и ссылка для хука (HK/hooks) могут автоматически получать значения из входной ссылки интервью.
Это позволяет:
- передавать
visit_id,project_id,sourceи другие параметры дальше; - одинаково обрабатывать обычные завершения и случаи дублей;
- не прописывать руками отдельные URL под каждый запуск.
Как это работает
1) Входные параметры берутся из URL запуска интервью
Пример входной ссылки:
https://app.example.com/?poll_id=1001&visit_id=abc123&project_id=prj55&source=telegram
Из неё система запоминает параметры (poll_id, visit_id, project_id, source и т.д.).
2) В Redirect/HK используются плейсхолдеры
В настройках URL можно писать параметры в виде:
$имя_параметра$
При выполнении Redirect/HK эти плейсхолдеры заменяются фактическими значениями.
Пример шаблона:
https://target.example.com/result/$project_id$?visit=$visit_id$&src=$source$
Результат:
https://target.example.com/result/prj55?visit=abc123&src=telegram
Важные правила
- Подстановка работает для всех параметров, которые пришли во входной ссылке.
- Подстановка работает и для:
- обычных Redirect/HK;
- сценария дубля (DOUBLE).
- Если параметр отсутствует, вместо него подставляется пустое значение.
- Спецсимволы в значениях кодируются автоматически (безопасно для URL).
Рекомендации по настройке
- Используйте понятные имена параметров:
visit_id,project_id,source,respondent_id. - В шаблоне проверяйте точное совпадение имён:
$visit_id$и$visitId$— это разные ключи. - Перед боевым запуском прогоните тестовую ссылку и проверьте конечный Redirect URL.