К статье
Практический материал

Разработка и Конфигурация · 9 мин

Как вывести вопрос пользователю в 1С

Разбираем, как вывести вопрос пользователю в 1С: процедуры Вопрос и ПоказатьВопрос, режимы диалога, обработка ответа, примеры кода для управляемых и обычных форм.

Интерактивный вопрос пользователю — базовый элемент любой бизнес-логики в 1С: подтверждение удаления документа, выбор варианта проведения, согласие на перезапись данных. В зависимости от режима работы конфигурации используются два подхода: устаревший модальный метод Вопрос() и современный асинхронный ПоказатьВопрос(). Выбор между ними определяется не вкусом разработчика, а режимом совместимости конфигурации и требованиями платформы.

Ключевое отличие в том, что ПоказатьВопрос не останавливает выполнение кода: ответ пользователя приходит позже, в отдельную процедуру-обработчик. Это меняет структуру алгоритма и часто становится источником ошибок у тех, кто переходит с обычных форм на управляемые. Ниже разобраны оба способа, типовые сценарии, ограничения и типичные ошибки.

Какой метод выбрать: Вопрос или ПоказатьВопрос

Метод Вопрос(ТекстВопроса, Кнопки, Таймаут, КнопкаПоУмолчанию, Заголовок) блокирует выполнение кода до ответа пользователя и возвращает значение типа КодВозвратаДиалога. Он удобен для линейной логики, но несовместим с веб-клиентом и отключён в конфигурациях, где в свойствах корня конфигурации установлен режим использования модальности «Не использовать».

Метод ПоказатьВопрос(ОписаниеОповещения, ТекстВопроса, Кнопки, Таймаут, КнопкаПоУмолчанию, Заголовок) работает асинхронно. Код после вызова выполняется сразу, а ответ пользователя приходит в процедуру, указанную в объекте ОписаниеОповещения. Именно этот вариант нужно использовать во всех современных разработках, включая тонкий клиент, веб-клиент и мобильную платформу.

Сравнение вариантов

Вопрос()

Модальный, блокирует код. Подходит только для обычных форм и конфигураций с разрешённой модальностью. Не работает в веб-клиенте.

ПоказатьВопрос()

Асинхронный, универсальный. Работает во всех клиентах, требует разделения логики на вызов и обработчик ответа.

Предупреждение / ПоказатьПредупреждение

Если выбор не нужен, а требуется только сообщить факт, вопрос заменяют предупреждением с одной кнопкой.

Как вывести вопрос через ПоказатьВопрос

Стандартный шаблон состоит из двух частей: вызова диалога и процедуры-обработчика. Обработчик должен существовать в том же модуле, где создаётся оповещение, иначе платформа выдаст ошибку «Процедура не обнаружена».

&НаКлиенте

Процедура УдалитьСтроку(Команда)

Оповещение = Новый ОписаниеОповещения("ПослеОтветаНаВопрос", ЭтотОбъект);

ПоказатьВопрос(Оповещение,

"Удалить выбранную строку?",

РежимДиалогаВопрос.ДаНет,

20,

КодВозвратаДиалога.Нет,

"Подтверждение удаления");

КонецПроцедуры

&НаКлиенте

Процедура ПослеОтветаНаВопрос(Результат, ДополнительныеПараметры) Экспорт

Если Результат = КодВозвратаДиалога.Да Тогда

// логика удаления

КонецЕсли;

КонецПроцедуры

Обратите внимание на слово Экспорт в заголовке обработчика: без него платформа не сможет вызвать процедуру из механизма оповещений. Имя процедуры передаётся строкой, поэтому опечатка в нём не выявляется при проверке модуля и проявится только в момент ответа пользователя.

Порядок действий
  1. 1
    Создайте клиентскую процедуру-обработчик с параметрами (Результат, ДополнительныеПараметры) и словом Экспорт
  2. 2
    В месте вызова создайте объект ОписаниеОповещения с именем обработчика
  3. 3
    Вызовите ПоказатьВопрос, передав оповещение, текст, режим кнопок и заголовок
  4. 4
    В обработчике сравните Результат со значениями КодВозвратаДиалога
  5. 5
    Проверьте сценарий в тонком и, если используется, в веб-клиенте

Настройка кнопок, таймаута и кнопки по умолчанию

Состав кнопок задаётся параметром Кнопки. Можно использовать готовые значения перечисления РежимДиалогаВопрос (ДаНет, ДаНетОтмена, ОК, ОКОтмена, ПовторитьОтмена и другие) либо собрать произвольный набор через СписокЗначений, где каждой кнопке назначается собственный текст и возвращаемое значение. Произвольные кнопки нужны, когда стандартные «Да/Нет» не отражают смысл выбора, например «Провести / Записать / Отмена».

Таймаут задаётся в секундах: если пользователь не ответил за это время, диалог закрывается, а обработчик получает значение КодВозвратаДиалога.Таймаут. Кнопка по умолчанию срабатывает при нажатии Enter. Для деструктивных действий (удаление, отмена проведения) кнопкой по умолчанию безопаснее назначать отказ — «Нет» или «Отмена», чтобы случайное нажатие Enter не подтвердило операцию.

Кнопки = Новый СписокЗначений;

Кнопки.Добавить("Провести", "Провести");

Кнопки.Добавить("Записать", "Только записать");

Кнопки.Добавить(КодВозвратаДиалога.Отмена, "Отмена");

ПоказатьВопрос(Оповещение, "Выберите действие с документом", Кнопки, , КодВозвратаДиалога.Отмена);

Как работает модальный метод Вопрос и когда он оправдан

В конфигурациях с обычными формами или с включённым свойством «Режим использования модальности — Использовать» допустим классический вызов:

Ответ = Вопрос("Перезаписать существующий файл?", РежимДиалогаВопрос.ДаНет, 30, КодВозвратаДиалога.Нет);

Если Ответ = КодВозвратаДиалога.Да Тогда

// перезапись файла

КонецЕсли;

Такой код проще читается, потому что логика линейна: вопрос, ответ, действие в одной процедуре. Однако платформа при включённой проверке конфигурации помечает модальные вызовы как ошибки, если модальность запрещена, а в веб-клиенте модальные окна блокируются браузером. Поэтому даже в старых конфигурациях при доработке имеет смысл сразу писать через ПоказатьВопрос, чтобы не переписывать код при переходе на такси.

Передача контекста в обработчик через ДополнительныеПараметры

Частая задача — передать в обработчик данные, известные в момент вызова: ссылку на документ, номер строки, выбранный вариант. Для этого в конструктор ОписаниеОповещения третьим параметром передаётся произвольное значение, обычно структура:

Параметры = Новый Структура;

Параметры.Вставить("ДокументСсылка", ТекущийДокумент);

Параметры.Вставить("НомерСтроки", Элементы.Товары.ТекущаяСтрока);

Оповещение = Новый ОписаниеОповещения("ПослеОтветаНаВопрос", ЭтотОбъект, Параметры);

ПоказатьВопрос(Оповещение, "Удалить строку?", РежимДиалогаВопрос.ДаНет);

В обработчике эти данные доступны через параметр ДополнительныеПараметры. Без такой передачи пришлось бы хранить контекст в реквизитах формы, что загромождает модуль и повышает риск ошибок при параллельных вызовах нескольких вопросов.

Типичные ошибки и ограничения

Типичные ошибки
01
Код после ПоказатьВопрос ожидает ответа — но он выполняется сразу, до реакции пользователя. Всю зависимую логику нужно переносить в обработчик
02
Обработчик объявлен без Экспорт — платформа не находит процедуру, диалог закрывается с ошибкой
03
Опечатка в имени обработчика строкой — не ловится проверкой модуля, проявляется только в рантайме
04
Вызов вопроса на сервере — диалоги доступны только в клиентском контексте, в &НаСервере ПоказатьВопрос недоступен
05
Не обработан КодВозвратаДиалога.Таймаут — при заданном таймауте бездействие пользователя ведёт себя непредсказуемо
06
Кнопка по умолчанию подтверждает опасное действие — случайный Enter удаляет данные

Отдельно стоит помнить про серверный контекст: интерактивные диалоги нельзя вызвать в процедурах с директивой &НаСервере, в фоновых заданиях и на внешнем соединении. Если бизнес-логика исполняется на сервере, вопрос нужно задавать на клиенте до серверного вызова, передавая ответ параметром.

Ещё одно ограничение — вложенные вопросы. Если из обработчика первого вопроса задаётся второй, цепочка оповещений быстро становится трудночитаемой. При трёх и более последовательных вопросах лучше заменить диалоги одной формой выбора с несколькими полями.

Контрольные точки

Как проверить результат

Поведение диалога
Норма

Окно вопроса появляется, код после вызова не ждёт ответа

Тревожный признак

Выполнение зависло или логика сработала до ответа

Обработчик
Норма

После нажатия кнопки отрабатывает нужная ветка по КодВозвратаДиалога

Тревожный признак

Ошибка «Процедура не обнаружена» или ничего не происходит

Веб-клиент
Норма

Диалог открывается и в тонком, и в веб-клиенте

Тревожный признак

В веб-клиенте диалог не появляется — используется модальный вызов

FAQ: частые вопросы о выводе вопроса в 1С

Чем ПоказатьВопрос отличается от Вопрос?

Вопрос — модальный метод: он приостанавливает выполнение кода и возвращает ответ как результат функции. ПоказатьВопрос асинхронный: ответ приходит в отдельную процедуру через описание оповещения. Второй вариант работает во всех клиентах и является рекомендуемым.

Как сделать свои надписи на кнопках вместо «Да» и «Нет»?

Передайте в параметр Кнопки объект СписокЗначений, где значение элемента — возвращаемый код, а представление — текст кнопки. В обработчике сравнивайте результат с этими значениями.

Почему платформа пишет «Использование модальных окон запрещено»?

В свойствах конфигурации установлен режим использования модальности «Не использовать». Замените вызов Вопрос на ПоказатьВопрос с обработчиком оповещения — менять глобальную настройку конфигурации ради одного диалога не следует.

Можно ли задать вопрос из серверной процедуры?

Нет. Диалоги доступны только на клиенте. Задайте вопрос в клиентской процедуре до обращения к серверу и передайте выбор пользователя параметром в серверный вызов.

Как обработать закрытие вопроса по таймауту?

При истечении таймаута обработчик получает КодВозвратаДиалога.Таймаут. Добавьте явную ветку для этого значения — обычно его приравнивают к отказу или к кнопке по умолчанию.

Как передать данные в процедуру обработки ответа?

Через третий параметр конструктора ОписаниеОповещения — обычно туда помещают структуру с нужными значениями. В обработчике она доступна как параметр ДополнительныеПараметры.

Итог

Что важно запомнить

В современных конфигурациях вопрос выводится через ПоказатьВопрос с описанием оповещения: вся логика, зависящая от ответа, переносится в экспортный обработчик. Модальный Вопрос допустим только при разрешённой модальности. Для опасных действий кнопкой по умолчанию назначайте отказ и всегда обрабатывайте таймаут.