Как программно создать отчет СКД и сохранить его в файл?

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

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

В процессе обсуждения этой темы на форумах часто возникает путаница. Разработчики смешивают три разных понятия:

  1. Схема компоновки данных (СКД) — структура, описывающая источники данных, поля, связи и настройки отчета.
  2. Внешний отчет (файл .erf) — бинарный файл 1С, который можно запустить в режиме «Предприятие».
  3. Результат отчета (Табличный документ) — сформированная печатная форма, которую пользователь видит на экране и может сохранить в форматы Excel, PDF или MXL.

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

Решение 1: Полное программное создание схемы СКД с нуля

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

Рассмотрим подробнее пошаговый пример создания схемы, которая выбирает данные из справочника «Номенклатура»:


// 1. Инициализируем новую схему компоновки данных
СхемаСКД = Новый СхемаКомпоновкиДанных;

// 2. Добавляем источник данных. Для работы с базой данных используется тип "local"
ИсточникДанных = СхемаСКД.ИсточникиДанных.Добавить();
ИсточникДанных.Имя = "ИсточникДанных1";
ИсточникДанных.ТипИсточникаДанных = "local";

// 3. Добавляем набор данных - запрос
НаборДанных = СхемаСКД.НаборыДанных.Добавить(Тип("НаборДанныхЗапросСхемыКомпоновкиДанных"));
НаборДанных.Имя = "НаборДанныхНоменклатура";
НаборДанных.ИсточникДанных = "ИсточникДанных1";
НаборДанных.Запрос = 
    "ВЫБРАТЬ
    |	Номенклатура.Ссылка КАК Товар,
    |	Номенклатура.Код КАК Код,
    |	Номенклатура.Наименование КАК Наименование
    |ИЗ
    |	Справочник.Номенклатура КАК Номенклатура";

// Очень важная строка: включаем автозаполнение доступных полей на основе текста запроса
НаборДанных.АвтозаполнениеДоступныхПолей = Истина;

// 4. Настраиваем структуру вывода (настройки по умолчанию)
Настройки = СхемаСКД.НастройкиПоУмолчанию;

// Добавляем выбранные поля (колонки), которые будут выводиться в отчет
ВыбранноеПолеТовар = Настройки.ВыбранныеПоля.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
ВыбранноеПолеТовар.Поле = Новый ПолеКомпоновкиДанных("Товар");
ВыбранноеПолеТовар.Использование = Истина;

ВыбранноеПолеКод = Настройки.ВыбранныеПоля.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
ВыбранноеПолеКод.Поле = Новый ПолеКомпоновкиДанных("Код");
ВыбранноеПолеКод.Использование = Истина;

// Создаем группировку для вывода детальных записей (строк отчета)
Группировка = Настройки.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
Группировка.Использование = Истина;

// Чтобы вывелись выбранные нами поля, добавляем автополе в созданную группировку
АвтоПоле = Группировка.ВыбранныеПоля.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
АвтоПоле.Использование = Истина;

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

Решение 2: Сохранение созданной схемы СКД в файл XML

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

Проанализируем пример кода для записи схемы в XML-формат:


ПутьКФайлу = "C:\temp\MyGeneratedSchema.xml";

// Создаем объект записи XML и открываем файл в кодировке UTF-8
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.ОткрытьФайл(ПутьКФайлу, "UTF-8");

// Сериализуем объект схемы СКД в формат XML с правильным пространством имен
СериализаторXDTO.ЗаписатьXML(ЗаписьXML, СхемаСКД, "dataComposition", "http://v8.1c.ru/8.1/data-composition-system/composition-template");

ЗаписьXML.Закрыть();
Сообщить("Схема успешно сохранена в файл XML!");

Для обратного чтения и воссоздания схемы из XML-файла используем следующий код:


ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(ПутьКФайлу);

// Читаем XML и преобразуем обратно в объект СхемаКомпоновкиДанных
СхемаСКД = СериализаторXDTO.ПрочитатьXML(ЧтениеXML, Тип("СхемаКомпоновкиДанных"));

ЧтениеXML.Закрыть();

Решение 3: Программное создание и сохранение внешнего отчета (файла .erf)

Выясним важную техническую деталь, о которой шла речь в сообщениях 11 и 15 форума. Платформа 1С не умеет создавать бинарные файлы внешних отчетов (.erf) или внешних обработок (.epf) с чистого листа программным путем. Платформа не предоставляет методов для создания и сохранения этих файлов из кода напрямую.

Однако существует обходной путь (паттерн «Шаблон»), который успешно применяется на практике:

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

Рассмотрим, как выглядит этот алгоритм в коде:


// Извлекаем двоичные данные шаблона отчета на диск
МакетШаблона = ПолучитьОбщийМакет("ШаблонВнешнегоОтчета");
ВременныйПуть = КаталогВременныхФайлов() + "DynamicReport.erf";
МакетШаблона.Записать(ВременныйПуть);

// Подключаем извлеченный пустой отчет через менеджер внешних отчетов
ВнешнийОтчетОбъект = ВнешниеОтчеты.Создать(ВременныйПуть, Ложь);

// Подменяем схему компоновки данных во внешнем отчете на нашу программно созданную схему
ВнешнийОтчетОбъект.СхемаКомпоновкиДанных = СхемаСКД;

// Теперь мы можем программно работать с объектом внешнего отчета

Решение 4: Вывод отчета в табличный документ и сохранение в файлы Excel/PDF

Если конечная цель пользователя — получить не саму схему и не файл отчета, а готовые данные (например, реестр товаров или прайс-лист в формате Excel или PDF), мы должны запустить процесс компоновки программно и сохранить итоговый ТабличныйДокумент.

Давайте разберем по шагам стандартный цикл вывода и сохранения программного отчета:


// Инициализируем компоновщик макета
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;

// Создаем макет компоновки, передавая нашу программную схему и ее настройки по умолчанию
ДанныеРасшифровки = Новый ДанныеРасшифровкиКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаСКД, СхемаСКД.НастройкиПоУмолчанию, ДанныеРасшифровки);

// Инициализируем процессор компоновки данных и передаем ему макет
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки, Истина);

// Выводим результат в табличный документ
ТабличныйДокумент = Новый ТабличныйДокумент;
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ТабличныйДокумент);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);

// Сохраняем табличный документ в файл нужного формата
ПутьДляСохранения = "C:\temp\РезультатОтчета.xlsx";
ТабличныйДокумент.Записать(ПутьДляСохранения, ТипФайлаТабличногоДокумента.XLSX);

Сообщить("Отчет успешно сформирован и сохранен в Excel!");

Полезный нюанс: Интерактивный конструктор схемы в режиме «1С:Предприятие»

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

Посмотрим на пример его вызова:


// Инициализируем конструктор схем
Конструктор = Новый КонструкторСхемыКомпоновкиДанных;

// Загружаем в конструктор нашу программную схему
Конструктор.УстановитьСхему(СхемаСКД);

// Открываем диалоговое окно конструктора для пользователя
Если Конструктор.Редактировать(ЭтаФорма) Тогда
    // Если пользователь нажал "ОК", получаем модифицированную им схему
    МодифицированнаяСхема = Конструктор.ПолучитьСхему();
    
    // Можем сохранить обновленную схему или сразу вывести отчет по ней
    СхемаСКД = МодифицированнаяСхема;
КонецЕсли;

Этот подход часто используется при создании сложных консолей отчетов, динамических рабочих мест аналитиков или в гибких системах администрирования.

← На главную