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