Разберем сложную, но крайне интересную задачу: как полностью программно, без использования конфигуратора и готовых макетов в метаданных, создать схему компоновки данных (СКД), сформировать отчет и сохранить результат на диск.
В процессе обсуждения этой темы на форумах часто возникает путаница. Разработчики смешивают три разных понятия:
Мы детально разберем каждый из этих аспектов, изучим программный код для их реализации и найдем обходные пути для известных ограничений платформы.
Для того чтобы создать схему компоновки данных полностью программно, нам не нужны готовые макеты в конфигурации. Мы можем создать объект СхемаКомпоновкиДанных в оперативной памяти, наполнить его источниками, наборами данных, полями и настройками вывода по умолчанию.
Рассмотрим подробнее пошаговый пример создания схемы, которая выбирает данные из справочника «Номенклатура»:
// 1. Инициализируем новую схему компоновки данных
СхемаСКД = Новый СхемаКомпоновкиДанных;
// 2. Добавляем источник данных. Для работы с базой данных используется тип "local"
ИсточникДанных = СхемаСКД.ИсточникиДанных.Добавить();
ИсточникДанных.Имя = "ИсточникДанных1";
ИсточникДанных.ТипИсточникаДанных = "local";
// 3. Добавляем набор данных - запрос
НаборДанных = СхемаСКД.НаборыДанных.Добавить(Тип("НаборДанныхЗапросСхемыКомпоновкиДанных"));
НаборДанных.Имя = "НаборДанныхНоменклатура";
НаборДанных.ИсточникДанных = "ИсточникДанных1";
НаборДанных.Запрос =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Товар,
| Номенклатура.Код КАК Код,
| Номенклатура.Наименование КАК Наименование
|ИЗ
| Справочник.Номенклатура КАК Номенклатура";
// Очень важная строка: включаем автозаполнение доступных полей на основе текста запроса
НаборДанных.АвтозаполнениеДоступныхПолей = Истина;
// 4. Настраиваем структуру вывода (настройки по умолчанию)
Настройки = СхемаСКД.НастройкиПоУмолчанию;
// Добавляем выбранные поля (колонки), которые будут выводиться в отчет
ВыбранноеПолеТовар = Настройки.ВыбранныеПоля.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
ВыбранноеПолеТовар.Поле = Новый ПолеКомпоновкиДанных("Товар");
ВыбранноеПолеТовар.Использование = Истина;
ВыбранноеПолеКод = Настройки.ВыбранныеПоля.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
ВыбранноеПолеКод.Поле = Новый ПолеКомпоновкиДанных("Код");
ВыбранноеПолеКод.Использование = Истина;
// Создаем группировку для вывода детальных записей (строк отчета)
Группировка = Настройки.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
Группировка.Использование = Истина;
// Чтобы вывелись выбранные нами поля, добавляем автополе в созданную группировку
АвтоПоле = Группировка.ВыбранныеПоля.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
АвтоПоле.Использование = Истина;
Схема полностью готова в оперативной памяти. Теперь ее можно передавать в процессор компоновки для формирования отчета.
Если задача состоит в том, чтобы сохранить именно саму спроектированную схему (структуру отчета) в файл на диске, чтобы затем ее можно было загрузить в конфигураторе или другой базе данных, мы используем механизм сериализации 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.Закрыть();
Выясним важную техническую деталь, о которой шла речь в сообщениях 11 и 15 форума. Платформа 1С не умеет создавать бинарные файлы внешних отчетов (.erf) или внешних обработок (.epf) с чистого листа программным путем. Платформа не предоставляет методов для создания и сохранения этих файлов из кода напрямую.
Однако существует обходной путь (паттерн «Шаблон»), который успешно применяется на практике:
ШаблонВнешнегоОтчета.Рассмотрим, как выглядит этот алгоритм в коде:
// Извлекаем двоичные данные шаблона отчета на диск
МакетШаблона = ПолучитьОбщийМакет("ШаблонВнешнегоОтчета");
ВременныйПуть = КаталогВременныхФайлов() + "DynamicReport.erf";
МакетШаблона.Записать(ВременныйПуть);
// Подключаем извлеченный пустой отчет через менеджер внешних отчетов
ВнешнийОтчетОбъект = ВнешниеОтчеты.Создать(ВременныйПуть, Ложь);
// Подменяем схему компоновки данных во внешнем отчете на нашу программно созданную схему
ВнешнийОтчетОбъект.СхемаКомпоновкиДанных = СхемаСКД;
// Теперь мы можем программно работать с объектом внешнего отчета
Если конечная цель пользователя — получить не саму схему и не файл отчета, а готовые данные (например, реестр товаров или прайс-лист в формате Excel или PDF), мы должны запустить процесс компоновки программно и сохранить итоговый ТабличныйДокумент.
Давайте разберем по шагам стандартный цикл вывода и сохранения программного отчета:
// Инициализируем компоновщик макета
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
// Создаем макет компоновки, передавая нашу программную схему и ее настройки по умолчанию
ДанныеРасшифровки = Новый ДанныеРасшифровкиКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаСКД, СхемаСКД.НастройкиПоУмолчанию, ДанныеРасшифровки);
// Инициализируем процессор компоновки данных и передаем ему макет
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки, Истина);
// Выводим результат в табличный документ
ТабличныйДокумент = Новый ТабличныйДокумент;
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ТабличныйДокумент);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
// Сохраняем табличный документ в файл нужного формата
ПутьДляСохранения = "C:\temp\РезультатОтчета.xlsx";
ТабличныйДокумент.Записать(ПутьДляСохранения, ТипФайлаТабличногоДокумента.XLSX);
Сообщить("Отчет успешно сформирован и сохранен в Excel!");
Малоизвестная, но очень мощная возможность платформы 1С — вызов визуального конструктора СКД непосредственно в пользовательском режиме. Если вы хотите дать продвинутому пользователю возможность отредактировать созданную вами программную схему визуально, вы можете использовать объект КонструкторСхемыКомпоновкиДанных.
Посмотрим на пример его вызова:
// Инициализируем конструктор схем
Конструктор = Новый КонструкторСхемыКомпоновкиДанных;
// Загружаем в конструктор нашу программную схему
Конструктор.УстановитьСхему(СхемаСКД);
// Открываем диалоговое окно конструктора для пользователя
Если Конструктор.Редактировать(ЭтаФорма) Тогда
// Если пользователь нажал "ОК", получаем модифицированную им схему
МодифицированнаяСхема = Конструктор.ПолучитьСхему();
// Можем сохранить обновленную схему или сразу вывести отчет по ней
СхемаСКД = МодифицированнаяСхема;
КонецЕсли;
Этот подход часто используется при создании сложных консолей отчетов, динамических рабочих мест аналитиков или в гибких системах администрирования.