При разработке интеграций, регламентных заданий или универсальных сервисных обработок часто возникает задача программно сформировать отчет и выгрузить его в файл Excel (XLSX). Если отчет разработан на базе системы компоновки данных (СКД), задача решается стандартизировано через программный вызов процессора компоновки на сервере. Однако при работе со старыми отчетами (построенными на обычных макетах или построителе отчета) разработчики сталкиваются с ошибками контекста и невозможностью выполнить код без интерактивного открытия формы.
Разберем детально, почему возникает эта проблема, какие архитектурные ограничения платформы 1С влияют на выполнение отчетов и какими способами можно программно сформировать отчет без СКД и выгрузить его результат.
Проанализируем ключевые различия между отчетами на СКД и классическими отчетами прошлых поколений:
ТабличныйДокумент) исторически располагался в модуле формы под обработчиком нажатия кнопки «Сформировать». Вне контекста формы этот код просто недоступен.&НаСервере) интерактивные методы ПолучитьФорму(), Форма.Открыть() и ТабДок.Показать() вызывают синтаксические или контекстные ошибки платформы, так как форма является исключительно клиентским объектом.ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент, у старых отчетов нет общего интерфейса инициализации параметров и запуска.Рассмотрим наиболее правильный и надежный подход при наличии доступа к доработке конфигурации. Суть метода заключается в разделении логики построения данных и визуального интерфейса.
В модуле объекта отчета создадим экспортную процедуру, которая принимает на вход параметры и возвращает или заполняет переданный ТабличныйДокумент:
// В модуле объекта отчета
Процедура СформироватьОтчетВТабличныйДокумент(ТабДок, СтруктураПараметров) Экспорт
Макет = ПолучитьМакет("ОсновнойМакет");
ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
// Заполняем параметры запроса
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ОстаткиНоменклатурыОстатки.Номенклатура КАК Номенклатура,
| ОстаткиНоменклатурыОстатки.КоличествоОстаток КАК Количество
|ИЗ
| РегистрНакопления.ОстаткиНоменклатуры.Остатки(&Период, ) КАК ОстаткиНоменклатурыОстатки";
Запрос.УстановитьПараметр("Период", СтруктураПараметров.Период);
Выборка = Запрос.Выполнить().Выбрать();
ТабДок.Очистить();
ТабДок.Вывести(ОбластьШапка);
Пока Выборка.Следующий() Цикл
ОбластьСтрока.Параметры.Заполнить(Выборка);
ТабДок.Вывести(ОбластьСтрока);
КонецЦикла;
КонецПроцедуры
Теперь в вызывающей обработке мы можем без создания форм и открытия окон инициализировать объект отчета на сервере, передать параметры и сразу сохранить сформированный табличный документ в файл:
&НаСервере
Процедура ВыгрузитьОтчетВExcelНаСервере(ПутьКФайлу, ДатаОтчета)
ОтчетОбъект = Отчеты.МойОтчетБезСКД.Создать();
ПараметрыОтчета = Новый Структура;
ПараметрыОтчета.Вставить("Период", ДатаОтчета);
ТабДок = Новый ТабличныйДокумент;
ОтчетОбъект.СформироватьОтчетВТабличныйДокумент(ТабДок, ПараметрыОтчета);
// Сохраняем в файл на сервере
ТабДок.Записать(ПутьКФайлу, ТипФайлаТабличногоДокумента.XLSX);
КонецПроцедуры
Если конфигурацию нельзя изменять напрямую (типовая конфигурация на полной поддержке или строгий регламент разработки), используем механизм расширений:
&Вместо, &После.Если старый отчет использует объект ПостроительОтчета и логика запроса заложена в свойствах объекта, его можно исполнить напрямую через серверные методы построителя без участия форм:
&НаСервере
Процедура СформироватьПостроительВФайл(ПутьКФайлу)
ОтчетОбъект = Отчеты.АнализПродаж.Создать();
// Инициализация построителя отчета из модуля объекта
Построитель = ОтчетОбъект.ПостроительОтчета;
Построитель.Параметры.Вставить("ДатаНачала", НачалоМесяца(ТекущаяДата()));
Построитель.Параметры.Вставить("ДатаОкончания", КонецДня(ТекущаяДата()));
Построитель.Выполнить();
ТабДок = Новый ТабличныйДокумент;
Построитель.Вывести(ТабДок);
ТабДок.Записать(ПутьКФайлу, ТипФайлаТабличногоДокумента.XLSX);
КонецПроцедуры
Если исходный отчет нельзя модифицировать, а расширения по какой-либо причине не используются, создадим внешний отчет (файл .erf), в который перенесем запрос, макет и алгоритм расчета. Для интеграции в типовые решения БСП такой отчет адаптируется под стандарты подсистемы «Дополнительные отчеты и обработки» с реализацией функции СведенияОВнешнейОбработке(). Это позволит запускать формирование отчета регламентными заданиями БСП в фоновом режиме на сервере.
При сохранении сформированного ТабличныйДокумент в Excel обратим внимание на важные детали:
ТипФайлаТабличногоДокумента.XLSX вместо устаревшего XLS. Формат XLS ограничен 65 536 строками и 256 колонками, а также менее стабильно обрабатывается платформой при формировании на серверах под управлением Linux.Записать() на сервере путь к файлу должен указывать на локальную файловую систему сервера 1С:Предприятия или на сетевой ресурс, к которому у системной учетной записи службы ragent (или usr1cv8) есть полные права на запись.ПоместитьВоВременноеХранилище() на сервере и последующее сохранение через ПолучитьФайл() на клиенте.