Как программно сформировать и сохранить в Excel отчет не на СКД без открытия формы

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

При разработке интеграций, регламентных заданий или универсальных сервисных обработок часто возникает задача программно сформировать отчет и выгрузить его в файл Excel (XLSX). Если отчет разработан на базе системы компоновки данных (СКД), задача решается стандартизировано через программный вызов процессора компоновки на сервере. Однако при работе со старыми отчетами (построенными на обычных макетах или построителе отчета) разработчики сталкиваются с ошибками контекста и невозможностью выполнить код без интерактивного открытия формы.

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

В чем причина сложности выполнения старых отчетов

Проанализируем ключевые различия между отчетами на СКД и классическими отчетами прошлых поколений:

  1. Привязка алгоритма к модулю формы: В не-СКД отчетах весь код (запрос к базе, обход результатов выборки, заполнение секций макета и вывод в реквизит формы типа ТабличныйДокумент) исторически располагался в модуле формы под обработчиком нажатия кнопки «Сформировать». Вне контекста формы этот код просто недоступен.
  2. Ограничения клиент-серверного взаимодействия: При выполнении серверного кода (в фоновом или регламентном задании, в модулях с директивой &НаСервере) интерактивные методы ПолучитьФорму(), Форма.Открыть() и ТабДок.Показать() вызывают синтаксические или контекстные ошибки платформы, так как форма является исключительно клиентским объектом.
  3. Отсутствие единого стандарта интерфейса: В отличие от СКД, где схема и настройки выводятся стандартным серверным конвейером через ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент, у старых отчетов нет общего интерфейса инициализации параметров и запуска.

Способ 1. Вынесение алгоритма формирования в модуль объекта

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

В модуле объекта отчета создадим экспортную процедуру, которая принимает на вход параметры и возвращает или заполняет переданный ТабличныйДокумент:


// В модуле объекта отчета
Процедура СформироватьОтчетВТабличныйДокумент(ТабДок, СтруктураПараметров) Экспорт
    
    Макет = ПолучитьМакет("ОсновнойМакет");
    ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
    ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
    
    // Заполняем параметры запроса
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |   ОстаткиНоменклатурыОстатки.Номенклатура КАК Номенклатура,
        |   ОстаткиНоменклатурыОстатки.КоличествоОстаток КАК Количество
        |ИЗ
        |   РегистрНакопления.ОстаткиНоменклатуры.Остатки(&Период, ) КАК ОстаткиНоменклатурыОстатки";
    Запрос.УстановитьПараметр("Период", СтруктураПараметров.Период);
    
    Выборка = Запрос.Выполнить().Выбрать();
    
    ТабДок.Очистить();
    ТабДок.Вывести(ОбластьШапка);
    
    Пока Выборка.Следующий() Цикл
        ОбластьСтрока.Параметры.Заполнить(Выборка);
        ТабДок.Вывести(ОбластьСтрока);
    КонецЦикла;
    
КонецПроцедуры

Теперь в вызывающей обработке мы можем без создания форм и открытия окон инициализировать объект отчета на сервере, передать параметры и сразу сохранить сформированный табличный документ в файл:


&НаСервере
Процедура ВыгрузитьОтчетВExcelНаСервере(ПутьКФайлу, ДатаОтчета)
    
    ОтчетОбъект = Отчеты.МойОтчетБезСКД.Создать();
    
    ПараметрыОтчета = Новый Структура;
    ПараметрыОтчета.Вставить("Период", ДатаОтчета);
    
    ТабДок = Новый ТабличныйДокумент;
    ОтчетОбъект.СформироватьОтчетВТабличныйДокумент(ТабДок, ПараметрыОтчета);
    
    // Сохраняем в файл на сервере
    ТабДок.Записать(ПутьКФайлу, ТипФайлаТабличногоДокумента.XLSX);
    
КонецПроцедуры

Способ 2. Использование расширения конфигурации (без снятия с поддержки)

Если конфигурацию нельзя изменять напрямую (типовая конфигурация на полной поддержке или строгий регламент разработки), используем механизм расширений:

  1. Подключим расширение конфигурации с режимом совместимости, соответствующим основной базе.
  2. Добавим в расширение исходный отчет.
  3. В расширении добавим собственный экспортный метод в модуль объекта отчета или перехватим логику формирования через директивы &Вместо, &После.
  4. Вызовем формирование отчета из внешней обработки так же, как описано в первом способе.

Способ 3. Программная работа с отчетами на базе «Построителя отчета»

Если старый отчет использует объект ПостроительОтчета и логика запроса заложена в свойствах объекта, его можно исполнить напрямую через серверные методы построителя без участия форм:


&НаСервере
Процедура СформироватьПостроительВФайл(ПутьКФайлу)
    
    ОтчетОбъект = Отчеты.АнализПродаж.Создать();
    
    // Инициализация построителя отчета из модуля объекта
    Построитель = ОтчетОбъект.ПостроительОтчета;
    Построитель.Параметры.Вставить("ДатаНачала", НачалоМесяца(ТекущаяДата()));
    Построитель.Параметры.Вставить("ДатаОкончания", КонецДня(ТекущаяДата()));
    
    Построитель.Выполнить();
    
    ТабДок = Новый ТабличныйДокумент;
    Построитель.Вывести(ТабДок);
    
    ТабДок.Записать(ПутьКФайлу, ТипФайлаТабличногоДокумента.XLSX);
    
КонецПроцедуры

Способ 4. Создание внешнего отчета-обертки

Если исходный отчет нельзя модифицировать, а расширения по какой-либо причине не используются, создадим внешний отчет (файл .erf), в который перенесем запрос, макет и алгоритм расчета. Для интеграции в типовые решения БСП такой отчет адаптируется под стандарты подсистемы «Дополнительные отчеты и обработки» с реализацией функции СведенияОВнешнейОбработке(). Это позволит запускать формирование отчета регламентными заданиями БСП в фоновом режиме на сервере.

Особенности сохранения результата в Excel

При сохранении сформированного ТабличныйДокумент в Excel обратим внимание на важные детали:

  1. Выбор формата: Всегда предпочтительнее использовать ТипФайлаТабличногоДокумента.XLSX вместо устаревшего XLS. Формат XLS ограничен 65 536 строками и 256 колонками, а также менее стабильно обрабатывается платформой при формировании на серверах под управлением Linux.
  2. Доступ к путям на сервере: При вызове метода Записать() на сервере путь к файлу должен указывать на локальную файловую систему сервера 1С:Предприятия или на сетевой ресурс, к которому у системной учетной записи службы ragent (или usr1cv8) есть полные права на запись.
  3. Передача файла на клиент: Если файл формируется на сервере, но должен быть сохранен на компьютере пользователя, используем передачу через ПоместитьВоВременноеХранилище() на сервере и последующее сохранение через ПолучитьФайл() на клиенте.
← На главную