При разработке под управляемые формы 1С часто возникает задача прервать выполнение алгоритма для получения подтверждения от пользователя. В отличие от «толстого» клиента, где существовала блокирующая функция Вопрос(), в современной архитектуре 1С мы сталкиваемся с асинхронностью. Давайте разберем, почему попытки «заставить» систему ждать привычными способами не работают и как организовать код правильно.
В управляемом приложении любой интерактивный вызов (например, ПоказатьВопрос) является асинхронным. Это архитектурное решение, принятое для обеспечения работы веб-клиента и кроссплатформенности. Когда вы вызываете ПоказатьВопрос, платформа не приостанавливает выполнение вашего кода — она отправляет команду на клиент и сразу же переходит к исполнению следующей строки. Попытки использовать циклы или «заморозку» сеанса приведут к зависанию интерфейса, а в веб-клиенте — к ошибке исполнения.
Единственный верный способ «дождаться» ответа пользователя — изменить логику работы программы. Весь код, который должен выполняться после получения ответа, необходимо вынести в отдельную процедуру-обработчик.
ОписаниеОповещения для связи диалога с процедурой-обработчиком.ПоказатьВопрос выполнение текущего метода завершалось естественным образом.Допустим, у нас есть процедура, которая выполняет какое-то действие, но перед этим мы должны спросить пользователя, уверен ли он в своих намерениях. Рассмотрим пошаговую реализацию.
Шаг 1: Подготовка диалога
В основной процедуре мы инициализируем оповещение и вызываем окно вопроса:
// Инициализируем оповещение, указывая имя процедуры-обработчика
// ЭтотОбъект указывает, что обработчик находится в текущем модуле
Обработчик = Новый ОписаниеОповещения("ПослеЗакрытияВопроса", ЭтотОбъект);
// Вызываем диалог
ТекстВопроса = "Вы уверены, что хотите выполнить данную операцию?";
ПоказатьВопрос(Обработчик, ТекстВопроса, РежимДиалогаВопрос.ДаНет);
Шаг 2: Создание процедуры-обработчика
Теперь создадим процедуру ПослеЗакрытияВопроса. Обратите внимание, что система автоматически передаст в нее результат выбора пользователя:
&НаКлиенте
Процедура ПослеЗакрытияВопроса(Результат, Параметры) Экспорт
Если Результат = КодВозвратаДиалога.Да Тогда
// Здесь мы пишем код, который должен был идти после вопроса
ВыполнитьДействие();
Иначе
// Обработка отказа пользователя
Сообщить("Операция отменена пользователем.");
КонецЕсли;
КонецПроцедуры
Если ваша процедура большая и содержит много логики после вызова диалога, не пытайтесь вставить весь код прямо в обработчик. Лучше вынесите этот код в отдельный метод (процедуру или функцию), который будет вызываться из обработчика результата.
Полезный совет: В редакторе кода конфигуратора 1С можно упростить работу. Напишите ПоказатьВопрос, выделите текст, который должен идти после вопроса, и воспользуйтесь инструментом рефакторинга «Создать обработку оповещения». Платформа автоматически создаст процедуру-обработчик и перенесет туда ваш код.
ПоказатьВопрос работает только на клиенте. В серверных процедурах (например, внутри ПриЗаписи или ОбработкаПроведения) интерактив невозможен. Если вам нужно подтверждение перед записью, выносите его на уровень формы, а не в модуль объекта — для этого подойдёт универсальная настройка проверок данных без программирования.&Вместо, чтобы полностью перехватить вызов и реализовать логику с асинхронным вопросом.Соблюдение этого простого подхода позволит сделать ваш код чистым, предсказуемым и готовым к работе в любых современных средах: от тонкого клиента до веб-обозревателей.