При разработке механизмов автоматической рассылки или пакетной выгрузки отчетов программисты часто сталкиваются с проблемой: большинство примеров кода в сети завязаны на использование метода ПолучитьФорму() или ОткрытьФорму(). Однако в контексте серверного вызова, например, при выполнении регламентного задания, обращение к экранным формам недопустимо и вызывает ошибку. В этой статье мы подробно разберем, как программно проинициализировать, настроить и выгрузить «Универсальный отчет» исключительно средствами серверного кода.
Рассмотрим ситуацию: нам необходимо реализовать выгрузку данных в файл по расписанию. Традиционный подход «открыть отчет — нажать кнопку — сохранить» здесь не применим. Регламентные задания исполняются в фоновом процессе на стороне сервера 1С:Предприятия, где отсутствует понятие «интерфейс» и «окно». Попытка вызвать ПолучитьФорму() приведет к аварийному завершению задания, так как сервер не умеет работать с объектами отображения.
Для решения задачи нам потребуется работать напрямую с объектом отчета, его внутренними структурами и методами, которые заложены в модуле объекта «Универсального отчета».
Этот вариант актуален для конфигураций, использующих «старый» универсальный отчет (например, УПП 1.3, КА 1.1, БП 2.0). Здесь вся логика построения базируется на объекте ПостроительОтчета. Проанализируем программный код, который позволяет обойти использование форм.
Разберем по шагам процесс инициализации и формирования:
УстановитьНачальныеНастройки(), который подготавливает структуру метаданных.СформироватьОтчет() с передачей в него объекта ТабличныйДокумент.Посмотрим на практический пример кода:
// 1. Подготовка внешней обработки (если отчет внешний)
СпрОтчет = Справочники.ВнешниеОбработки.НайтиПоНаименованию("Наценка", Истина);
ИмяФайла = ПолучитьИмяВременногоФайла("epf");
ДвоичныеДанные = СпрОтчет.ХранилищеВнешнейОбработки.Получить();
ДвоичныеДанные.Записать(ИмяФайла);
// 2. Создание объекта отчета
ОтчетОбъект = ВнешниеОтчеты.Создать(ИмяФайла, Истина);
// 3. Инициализация структуры
ОтчетОбъект.УстановитьНачальныеНастройки();
// Отключаем попытки системы восстановить настройки пользователя (так как формы нет)
ОтчетОбъект.УниверсальныйОтчет.мВосстанавливатьНастройкиПриОткрытии = Ложь;
// 4. Установка параметров периода
ОтчетОбъект.УниверсальныйОтчет.ДатаНач = НачалоДня(ТекущаяДата());
ОтчетОбъект.УниверсальныйОтчет.ДатаКон = КонецДня(ТекущаяДата());
// 5. Настройка группировок (измерений строки)
ОтчетОбъект.УниверсальныйОтчет.ПостроительОтчета.ИзмеренияСтроки.Очистить();
ОтчетОбъект.УниверсальныйОтчет.ДобавитьИзмерениеСтроки("Регистратор");
ОтчетОбъект.УниверсальныйОтчет.ДобавитьИзмерениеСтроки("Номенклатура");
// 6. Формирование в табличный документ
ТД = Новый ТабличныйДокумент;
ОтчетОбъект.СформироватьОтчет(ТД);
// 7. Сохранение результата
ТД.Записать("C:\Exports\Report_Markup.xlsx", ТипФайлаТабличногоДокумента.XLSX);
// Не забываем удалить временный файл
УдалитьФайлы(ИмяФайла);
Выясним причину, по которой настройки могут «слетать». Метод УстановитьНачальныеНастройки() всегда должен вызываться до того, как вы начнете программно заполнять даты или отборы. Если вызвать его позже, он может перезатереть ваши значения значениями по умолчанию из макета или метаданных.
Проанализируем ситуацию с отборами. Если вам нужно установить фильтр по конкретной организации или складу, используйте метод ДобавитьОтбор() объекта УниверсальныйОтчет. Это позволит корректно передать параметры в запрос ПостроителяОтчета.
В современных конфигурациях (ERP 2.x, КА 2.x, БП 3.0), построенных на базе Библиотеки Стандартных Подсистем (БСП), «Универсальный отчет» работает через Систему компоновки данных (СКД). Работа с ним на сервере выглядит иначе, так как ПостроительОтчета там не используется.
Рассмотрим алгоритм для СКД-версии:
СхемаКомпоновкиДанных из объекта отчета.ПроцессорКомпоновкиДанных и ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений (или в Табличный документ).Такой подход полностью исключает обращение к ПолучитьФорму() и позволяет гибко управлять результатом выгрузки. Вы можете программно менять КомпоновщикНастроек.Настройки, добавляя новые поля или условия отбора прямо в коде регламентного задания.
Для реализации полноценной пакетной выгрузки нам необходимо предусмотреть несколько технических моментов:
Права доступа: Проверьте, что пользователь, под которым запущена служба 1C:Enterprise Server, имеет права на запись в целевую папку (особенно если это сетевой ресурс). Часто ошибки «Доступ запрещен» возникают именно из-за того, что программист тестирует код под своей учетной записью, а регламентное задание выполняется под системной.
Уникальность имен файлов: Чтобы отчеты не перезаписывали друг друга, рекомендуется добавлять в имя файла временную метку или идентификатор настройки. Например:
ИмяФайла = "Report_" + Формат(ТекущаяДата(), "ДФ=yyyyMMdd_HHmm") + ".pdf";
Очистка временных ресурсов: Как показано в примере выше, при работе с внешними отчетами всегда используйте ПолучитьИмяВременногоФайла() и обязательно вызывайте УдалитьФайлы() в конце процедуры. Это предотвратит замусоривание временных папок сервера 1С.
Мы выяснили, что для успешного формирования «Универсального отчета» на сервере достаточно отказаться от методов расширения формы и перейти к работе с объектом отчета и его внутренним построителем (или компоновщиком). Правильная последовательность вызова инициализирующих методов и программное управление свойствами УниверсальныйОтчет позволяют автоматизировать любую отчетность без участия пользователя.