Как реализовать подтверждение закрытия программы в управляемом приложении 1С 8.3 без модальных окон?

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

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

Способ 1. Использование штатного механизма события ПередЗавершениемРаботыСистемы

Проанализируем самый простой и рекомендуемый платформой способ. В модуле управляемого приложения существует предопределенное событие ПередЗавершениемРаботыСистемы, которое принимает два параметра: Отказ и ТекстПредупреждения.

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

Посмотрим на пример кода в модуле управляемого приложения:


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

Рассмотрим особенности работы данного метода:

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

Способ 2. Реализация собственного асинхронного диалога через ПоказатьВопрос

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

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

  1. Создадим клиентский общий модуль (например, ЗавершениеРаботыКлиент). Модуль должен быть неглобальным, и у него должен быть установлен флаг Клиент (управляемое приложение).
  2. В общем модуле объявим экспортную переменную-флаг, которая будет предотвращать зацикливание при повторном вызове закрытия.
  3. Напишем процедуру обработки ответа пользователя.

Посмотрим на пример кода в общем модуле ЗавершениеРаботыКлиент:


&НаКлиенте
Перем ЗавершениеРазрешено Экспорт;

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

Теперь рассмотрим код в модуле управляемого приложения:


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

Важное отличие ЗавершитьРаботуСистемы() от ПрекратитьРаботуСистемы()

Проанализируем разницу между двумя методами завершения работы, так как выбор неправильного метода может привести к потере пользовательских данных:

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

Таким образом, для базовой задачи подтверждения выхода оптимально использовать штатный параметр ТекстПредупреждения, а при необходимости расширенной логики — связку из ПоказатьВопрос(), флага завершения в общем модуле и метода ЗавершитьРаботуСистемы().

← На главную