Разработка и Конфигурация · 12 мин
ПоказатьВопрос в 1С: как работает метод и как его правильно использовать
Как работает метод ПоказатьВопрос в 1С: синтаксис, режимы диалога, обработка ответа через ОписаниеОповещения, примеры кода, типичные ошибки и отличия от Вопрос().
Метод ПоказатьВопрос в 1С:Предприятии выводит пользователю модальное окно с вопросом и набором кнопок («Да», «Нет», «Отмена» и другие), а ответ возвращается асинхронно — через процедуру обработчика оповещения. Именно асинхронная модель отличает его от устаревшей функции Вопрос(): выполнение кода не блокируется, а продолжается в отдельном обработчике после выбора пользователя.
Метод применяется везде, где программе нужно подтверждение действия: перед удалением документа, закрытием формы с несохранёнными данными, запуском длительной обработки или перезаписью файла. В типовых конфигурациях (БП, УТ, ERP, ЗУП) ПоказатьВопрос — стандартный способ интерактивного взаимодействия, а в режиме совместимости с интерфейсом «Такси» синхронные вызовы Вопрос() вообще запрещены настройками конфигуратора.
Ниже разобраны синтаксис метода, доступные режимы диалога, структура обработчика ответа, типичные ошибки при переходе с синхронного кода и готовые примеры для управляемых форм.
Что делает метод ПоказатьВопрос и когда его применять
Метод открывает стандартное окно вопроса с заданным текстом, набором кнопок и, при необходимости, таймаутом автоматического закрытия. Пользователь видит модальный диалог поверх активной формы и обязан сделать выбор, прежде чем продолжить работу с программой.
Типичные сценарии использования:
- подтверждение удаления или пометки удаления объекта;
- запрос перед перезаписью существующего файла или документа;
- предупреждение о несохранённых изменениях при закрытии формы;
- выбор варианта действия («Продолжить», «Пропустить», «Прервать») в длительной обработке;
- подтверждение отправки данных во внешние сервисы.
Использовать вопрос стоит только тогда, когда без решения пользователя продолжать нельзя. Если действие безопасно и обратимо, лишний диалог раздражает и замедляет работу — в таких случаях лучше вывести информационное сообщение через ПоказатьПредупреждение или просто выполнить операцию.
Синтаксис и параметры метода
Общая форма вызова выглядит так:
ПоказатьВопрос(ОписаниеОповещения, ТекстВопроса, Кнопки, Таймаут, КнопкаПоУмолчанию, Заголовок, КнопкаТаймаута);
Назначение параметров:
- ОписаниеОповещения — обязательный параметр. Объект, указывающий, какая процедура получит ответ пользователя;
- ТекстВопроса — строка, отображаемая в диалоге. Поддерживает многострочный текст;
- Кнопки — режим диалога: РежимДиалогаВопрос.ДаНет, ДаНетОтмена, ОК, ОКОтмена, ПовторитьОтмена, ПрерватьПовторитьПропустить или произвольный СписокЗначений;
- Таймаут — число секунд, через которые диалог закроется сам. 0 — ждать бесконечно;
- КнопкаПоУмолчанию — кнопка, срабатывающая по Enter;
- Заголовок — текст заголовка окна;
- КнопкаТаймаута — значение, которое вернётся при автоматическом закрытии.
Минимальный рабочий вызов требует только два первых параметра — остальные имеют значения по умолчанию. Однако в прикладном коде почти всегда задают и кнопку по умолчанию: без неё Enter может активировать деструктивный вариант ответа.
Какие режимы диалога доступны
Набор кнопок определяется системным перечислением РежимДиалогаВопрос. Выбор режима влияет и на то, какие значения может вернуть диалог:
| Режим | Кнопки | Возвращаемые значения | Когда использовать |
|---|---|---|---|
| ДаНет | Да, Нет | КодВозвратаДиалога.Да / Нет | Стандартное подтверждение действия |
| ДаНетОтмена | Да, Нет, Отмена | Да / Нет / Отмена | Когда «Нет» и «Отмена» — разные сценарии |
| ОК | ОК | ОК | Фактически предупреждение, а не вопрос |
| ОКОтмена | ОК, Отмена | ОК / Отмена | Согласие с условиями операции |
| ПовторитьОтмена | Повторить, Отмена | Повторить / Отмена | Ошибка операции с возможностью повтора |
| ПрерватьПовторитьПропустить | Прервать, Повторить, Пропустить | Прервать / Повторить / Пропустить | Пакетная обработка с ошибками |
Если стандартных режимов не хватает, в параметр «Кнопки» можно передать СписокЗначений с произвольными надписями. Значением элемента списка выступает любое значение, которое потом вернётся в обработчик, — это удобно для нестандартных сценариев вроде «Сохранить в файл / Отправить по почте / Пропустить».
Как обработать ответ пользователя через ОписаниеОповещения
Ключевой принцип: ПоказатьВопрос завершает работу сразу, не дожидаясь ответа. Весь код, который должен выполниться после выбора пользователя, переносится в отдельную процедуру-обработчик. Типовой каркас для управляемой формы:
&НаКлиенте
Процедура УдалитьДокумент(Команда)
Оповещение = Новый ОписаниеОповещения("УдалитьДокументЗавершение", ЭтотОбъект);
ПоказатьВопрос(Оповещение,
"Документ будет помечен на удаление. Продолжить?",
РежимДиалогаВопрос.ДаНет,
20,
КодВозвратаДиалога.Нет,
"Подтверждение удаления");
КонецПроцедуры
&НаКлиенте
Процедура УдалитьДокументЗавершение(Результат, ДополнительныеПараметры) Экспорт
Если Результат = КодВозвратаДиалога.Да Тогда
УдалитьДокументНаСервере();
ОповеститьОбИзменении(Объект.Ссылка);
КонецЕсли;
КонецПроцедуры
Обратите внимание на детали. Процедура-обработчик обязательно объявляется с ключевым словом Экспорт, иначе платформа не сможет её вызвать. Первый параметр обработчика — результат диалога, второй — произвольная структура дополнительных параметров, которую можно передать третьим аргументом в конструктор ОписаниеОповещения.
Если в обработчик нужно передать контекст (например, ссылку на обрабатываемый объект или имя файла), используйте дополнительные параметры:
ДопПараметры = Новый Структура("СсылкаНаДокумент", Объект.Ссылка);
Оповещение = Новый ОписаниеОповещения("УдалитьЗавершение", ЭтотОбъект, ДопПараметры);
- 1Создайте процедуру-обработчик с параметрами (Результат, ДополнительныеПараметры) и словом Экспорт
- 2В основной процедуре сформируйте ОписаниеОповещения с именем обработчика
- 3Вызовите ПоказатьВопрос с текстом, режимом кнопок и безопасной кнопкой по умолчанию
- 4В обработчике сравните Результат с КодВозвратаДиалога и выполните нужную ветку логики
- 5Проверьте сценарии: выбор каждой кнопки, закрытие по таймауту, нажатие Esc
Отличия от устаревшей функции Вопрос()
Функция Вопрос() работает синхронно: она останавливает выполнение кода и возвращает ответ прямо в точку вызова. Такой стиль проще для чтения, но блокирует интерфейс и главное — не поддерживается в веб-клиенте и запрещён в большинстве современных конфигураций.
ПоказатьВопрос или Вопрос()
Асинхронный вызов через оповещение. Работает в веб-клиенте, тонком и толстом клиенте, соответствует стандартам разработки. Требует разделения кода на две процедуры
Синхронная функция, возвращает ответ сразу. Проще для понимания, но недоступна в веб-клиенте и запрещена при отключенной модальной синхронности. Подходит только для старых конфигураций в режиме совместимости
Проверить, разрешены ли модальные синхронные вызовы, можно в свойствах конфигурации: параметр «Режим использования модальности». Если установлено «Не использовать», вызов Вопрос() вызовет ошибку времени выполнения. Поэтому при доработке типовых конфигураций ориентируйтесь только на ПоказатьВопрос.
Миграция старого кода сводится к переносу всей логики после вопроса в обработчик. Конструкция вида Если Вопрос("Удалить?", ...) = КодВозвратаДиалога.Да Тогда ... КонецЕсли; превращается в вызов ПоказатьВопрос плюс экспортную процедуру с той же проверкой результата.
Типичные ошибки и ограничения
Первая и самая частая ошибка — размещение зависимого кода сразу после вызова ПоказатьВопрос. Такой код выполнится до того, как пользователь ответит, и логика сломается. Всё, что зависит от ответа, должно жить внутри обработчика оповещения.
Вторая группа ошибок связана с контекстом выполнения. ПоказатьВопрос доступен только на клиенте: вызов в серверной процедуре или в фоновом задании приведёт к ошибке. Если логика выполняется на сервере, вопрос нужно задавать до вызова серверной процедуры или после возврата из неё.
Также учитывайте ограничения:
- в фоновых заданиях и на сервере интерактивные диалоги недоступны в принципе;
- обработчик без слова Экспорт вызовет ошибку «Процедура не обнаружена»;
- при закрытии формы до ответа пользователя обработчик может не выполниться — для вопросов при закрытии используйте обработчик ПередЗакрытием с Отказ = Истина и повторным закрытием из оповещения;
- длинный текст вопроса плохо читается — выносите детали в заголовок или отдельное предупреждение.
Как проверить, что диалог работает правильно
После внедрения вопроса прогоните все ветки сценария вручную в том клиенте, где работают пользователи (тонкий, толстый или веб). Поведение диалога в разных клиентах визуально отличается, хотя логика одинакова.
Как проверить результат
Выполняется именно та ветка кода, которая соответствует выбору
Выполняется действие по умолчанию независимо от выбора или код срабатывает до ответа
Приходит ожидаемое значение кнопки таймаута, деструктивные действия не выполняются
По таймауту запускается удаление или запись
Диалог открывается, ответ корректно доходит до обработчика
Ошибка вызова или молчаливое завершение без выполнения обработчика
Поведение предсказуемо, данных не теряется
Обработчик падает с ошибкой или изменения записываются без подтверждения
Полезный приём при отладке — временно добавить в обработчик вывод значения Результат через Сообщить() или СообщитьПользователю. Так видно, что именно вернул диалог в каждом сценарии, включая таймаут и закрытие окна крестиком (что эквивалентно кнопке «Отмена», если она есть).
FAQ: частые вопросы о ПоказатьВопрос
Почему код после ПоказатьВопрос выполняется сразу, не дожидаясь ответа?
Метод асинхронный: он только открывает диалог и сразу возвращает управление. Ответ приходит позже в процедуру, указанную в ОписаниеОповещения. Всю логику, зависящую от ответа, перенесите в эту процедуру-обработчик.
Как передать в обработчик свои данные, например ссылку на документ?
Используйте третий параметр конструктора ОписаниеОповещения: передайте туда Структуру с нужными значениями. В обработчике она будет доступна через второй параметр — ДополнительныеПараметры.
Можно ли вызвать ПоказатьВопрос на сервере или в фоновом задании?
Нет. Интерактивные диалоги доступны только в клиентском контексте. В фоновом задании вопрос задать нельзя в принципе — решение нужно принимать на клиенте до запуска задания или возвращать результат на клиент и спрашивать там.
Что вернёт диалог, если пользователь закроет его крестиком?
Вернётся значение кнопки «Отмена», если такая кнопка есть в выбранном режиме. Если кнопки отмены нет (например, режим ДаНет), закрытие крестиком может быть заблокировано — поведение зависит от режима диалога и клиента, поэтому этот сценарий стоит проверить вручную.
Как сделать свои надписи на кнопках вместо «Да» и «Нет»?
Передайте в параметр «Кнопки» СписокЗначений: представление элемента станет надписью на кнопке, а значение элемента вернётся в обработчик как результат. Так можно сделать кнопки «Провести», «Записать», «Пропустить» и любые другие.
Почему обработчик оповещения не вызывается?
Чаще всего процедура объявлена без ключевого слова Экспорт, либо имя процедуры в ОписанииОповещения указано с ошибкой. Также проверьте, что модуль, указанный вторым параметром конструктора, действительно содержит эту процедуру и форма ещё не закрыта к моменту ответа.
Что важно запомнить
ПоказатьВопрос — асинхронный клиентский метод: диалог открывается мгновенно, а ответ приходит в экспортную процедуру через ОписаниеОповещения. Вся зависимая логика размещается в обработчике, для деструктивных операций кнопкой по умолчанию назначается безопасный вариант, а работоспособность проверяется во всех клиентах и сценариях, включая таймаут.