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