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