Как исправить ошибку «Серверные вызовы при завершении работы запрещены» в 1С?

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

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

Почему возникает ошибка серверных вызовов?

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

Как решить задачу подтверждения закрытия?

Поскольку мы не можем «спросить» сервер о состоянии константы в момент нажатия на крестик, нам необходимо подготовить эти данные заранее. Рассмотрим три эффективных способа реализации этой задачи.

Способ 1: Использование параметров сеанса

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

  1. Создайте в конфигураторе параметр сеанса, например, НужноПодтверждениеЗакрытия (тип Булево).
  2. В модуле сеанса, в процедуре УстановкаПараметровСеанса, при первом обращении считайте значение константы и запишите его в этот параметр.
  3. Теперь в модуле управляемого приложения вы можете обращаться к этому значению напрямую:

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

Способ 2: Использование переменных модуля управляемого приложения

Если задача не требует глобального хранения параметров сеанса, можно воспользоваться переменными, объявленными в модуле управляемого приложения. Этот метод работает быстрее и проще в реализации.

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

// В модуле управляемого приложения
Перем НужноПодтверждениеЗакрытия Экспорт;

Процедура ПриНачалеРаботыСистемы()
    НужноПодтверждениеЗакрытия = Константы.ПідтвердженняЗакриття.Получить();
КонецПроцедуры

Процедура ПередЗавершениемРаботыСистемы(Отказ, ТекстПредупреждения)
    Если НужноПодтверждениеЗакрытия Тогда
        // Логика вопроса
    КонецЕсли;
КонецПроцедуры

Способ 3: Хранилище общих настроек

Для пользовательских настроек также можно использовать ХранилищеОбщихНастроек. Данные из него кэшируются на клиенте. Однако для системных констант первые два способа являются более предпочтительными и надежными.

Рекомендации по реализации

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

Используя предложенные выше варианты, вы сможете избавить пользователей от ошибок при закрытии и сделать работу программы более стабильной и предсказуемой.

← На главную