Как правильно реализовать вопрос пользователю перед закрытием формы в режиме без использования модальности?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Суть проблемы: почему форма закрывается раньше появления вопроса?

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

Чтобы форма «дождалась» решения пользователя, мы должны принудительно установить параметр Отказ = Истина. Это дает нам время на получение ответа и принятие решения о том, нужно ли закрывать окно или оставить его открытым.

Пошаговое решение: алгоритм работы

Для корректной реализации нам необходимо разделить логику на два этапа: инициация вопроса и обработка результата.

  1. В процедуре ПередЗакрытием мы проверяем, нужно ли задавать вопрос (например, по признаку модифицированности данных). Если нужно — устанавливаем Отказ = Истина и вызываем ПоказатьВопрос.
  2. В процедуре-обработчике оповещения мы анализируем Результат и выполняем необходимые действия (запись данных), после чего принудительно закрываем форму методом Закрыть().

Пример реализации кода

Рассмотрим пример кода, который позволит избежать бесконечного зацикливания и корректно обработать выбор пользователя:


&НаКлиенте
Процедура ПередЗакрытием(Отказ, СтандартнаяОбработка)
    Если ВнесеныИзменения Тогда
        Режим = РежимДиалогаВопрос.ДаНет;
        Оповещение = Новый ОписаниеОповещения("ПослеЗакрытияВопроса", ЭтаФорма);
        ПоказатьВопрос(Оповещение, "Были внесены изменения. Сохранить изменения?", Режим, 0);
        Отказ = Истина;
    КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура ПослеЗакрытияВопроса(Результат, Параметры) Экспорт
    Если Результат = КодВозвратаДиалога.Нет Тогда
        // Пользователь отказался от сохранения, просто закрываем форму
        Закрыть();
    ИначеЕсли Результат = КодВозвратаДиалога.Да Тогда
        // Выполняем запись, затем закрываем
        ЗаписатьДокументНаСервере();
        Закрыть();
    КонецЕсли;
КонецПроцедуры

Важные нюансы реализации

При работе с данным подходом обратите внимание на следующие моменты:

Альтернативный подход через реквизит формы

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


&НаКлиенте
Процедура ПередЗакрытием(Отказ, СтандартнаяОбработка)
    Если НужноЗадатьВопрос И Не ПропущенВопрос Тогда
        Отказ = Истина;
        ПоказатьВопрос(Новый ОписаниеОповещения("ПослеВопроса", ЭтаФорма), "Продолжить?");
    КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура ПослеВопроса(Результат, ДопПараметры) Экспорт
    Если Результат = КодВозвратаДиалога.Да Тогда
        ПропущенВопрос = Истина;
        Закрыть();
    КонецЕсли;
КонецПроцедуры

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

← На главную