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

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

Как задать вопрос пользователю в команде 1С

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

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

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

Ниже разобраны оба подхода: современный асинхронный для управляемых форм и синхронный для обычных, а также режимы диалога, обработка ответа, типичные ошибки и ограничения.

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

Платформа 1С:Предприятие 8 предлагает два способа задать вопрос. Метод Вопрос(ТекстВопроса, Кнопки, Таймаут) — синхронный: код останавливается, ждёт ответа и возвращает значение типа КодВозвратаДиалога. Он работает в обычном приложении и в толстом клиенте с разрешёнными модальными вызовами.

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

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

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

Универсальный вариант для управляемых форм, тонкого и веб-клиента. Требует выделения обработчика ответа в отдельную процедуру.

Вопрос()

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

Общий модуль вопросов (БСП)

В конфигурациях на Библиотеке стандартных подсистем есть готовые процедуры для типовых подтверждений — стоит проверить их наличие до написания своего кода.

Задаём вопрос в управляемой форме через ПоказатьВопрос

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

Пример кода для команды формы, подтверждающей удаление помеченных объектов:

&НаКлиенте

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

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

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

НСтр("ru = 'Удалить помеченные объекты?'"),

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

20,

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

НСтр("ru = 'Подтверждение удаления'"));

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

&НаКлиенте

Процедура УдалитьПомеченныеЗавершение(Результат, ДопПараметры) Экспорт

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

УдалитьПомеченныеНаСервере();

КонецЕсли;

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

Обратите внимание: процедура-обработчик должна иметь директиву Экспорт и два параметра — результат диалога и дополнительные параметры (второй параметр может быть неопределён, если ничего не передавалось). Без Экспорт платформа не сможет вызвать обработчик.

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

Режимы диалога и коды возврата

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

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

Синхронный вопрос в обычных формах

В обычном приложении допустим прямой вызов, который сразу возвращает ответ:

Если Вопрос("Продолжить обработку?", РежимДиалогаВопрос.ДаНет, 30) = КодВозвратаДиалога.Нет Тогда

Возврат;

КонецЕсли;

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

Передача контекста в обработчик ответа

Частая ситуация: в обработчике ответа нужны данные из обработчика команды — ссылка на объект, выбранные строки таблицы, параметры запуска. Их передают через третий параметр конструктора ОписаниеОповещения как произвольное значение или структуру.

ДопПараметры = Новый Структура("СсылкаНаДокумент, ИмяОперации", Ссылка, "Проведение");

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

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

В обработчике структура доступна через второй параметр. Это избавляет от хранения промежуточных данных в реквизитах формы и делает код предсказуемым при повторных вызовах команды.

Типичные ошибки
01
Вызов Вопрос() в управляемой форме — ошибка времени выполнения о запрете модальных методов
02
Отсутствие слова Экспорт у процедуры-обработчика — оповещение не находит метод
03
Продолжение логики сразу после ПоказатьВопрос — код выполняется до ответа пользователя
04
Игнорирование кода возврата Таймаут — при бездействии пользователя ветка отказа не срабатывает
05
Обращение к реквизитам формы в обработчике после её закрытия — обращение к удалённому объекту

Проверка результата и тестирование

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

Отдельно проверьте поведение при таймауте и при нажатии Escape или закрытии окна диалога: в этих случаях результат может отличаться от ожидаемого, и деструктивное действие не должно запускаться «по умолчанию».

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

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

Открытие диалога
Норма

Диалог появляется с заданным текстом, заголовком и кнопками

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

Ошибка о модальном вызове или пустой текст вопроса

Обработка ответа
Норма

Действие выполняется только при нужном коде возврата

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

Действие срабатывает при любом ответе или до ответа

Таймаут
Норма

При бездействии действие не выполняется

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

По истечении таймаута операция запускается автоматически

FAQ

Почему ПоказатьВопрос не срабатывает на сервере?

Диалоги с пользователем доступны только в клиентском контексте. Вызов в серверной процедуре или в фоновом задании приведёт к ошибке. Разделите логику: вопрос на клиенте, затем вызов серверной процедуры из обработчика ответа.

Как сделать кнопки со своими надписями?

Передайте вместо РежимДиалогаВопрос список значений: значение элемента — желаемый код возврата (например, КодВозвратаДиалога.Да), представление — текст кнопки, например «Сохранить и закрыть».

Что вернёт диалог, если пользователь закрыл его крестиком?

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

Можно ли задать вопрос без остановки интерфейса в фоновом задании?

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

Есть ли готовые механизмы вопросов в типовых конфигурациях?

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

Итог

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

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