При разработке отчетов на системе компоновки данных (СКД) часто возникает задача не просто вывести результат на экран пользователю, но и произвести с этими данными дополнительные действия: отправить по почте, сохранить в файл или сформировать на их основе специфический XML-выгрузку для государственных органов или внешних систем. Основная сложность для начинающего разработчика заключается в том, что по умолчанию СКД настроена на визуальное представление данных в ТабличныйДокумент, который крайне неудобен для программного разбора. Для решения такой задачи можно использовать готовое решение для выгрузки данных в XML через СКД.
В этой статье мы подробно разберем, как «перехватить» результат компоновки, получить его в виде удобной коллекции значений и корректно сформировать XML-файл. Рассмотрим несколько подходов, от простых до профессиональных с использованием XDTO.
Разберем типичную ошибку. Программист выводит отчет в ТабличныйДокумент (результат на форме), а затем пытается обойти его ячейки в цикле. Проанализируем, почему это плохо:
ТабличныйДокумент гораздо медленнее, чем прямая работа с данными в памяти.Это самый популярный и эффективный метод. Вместо того чтобы «рисовать» таблицу, мы заставляем СКД выгрузить результат в ДеревоЗначений или ТаблицаЗначений. Рассмотрим этот процесс по шагам.
Для начала нам необходимо подготовить основные объекты СКД. Обратите внимание на ключевой момент — использование специального типа генератора макета.
// Получаем схему и настройки
ОбъектОтчет = РеквизитФормыВЗначение("Отчет");
СхемаСКД = ОбъектОтчет.ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
Настройки = КомпоновщикНастроек.ПолучитьНастройки();
// Важный момент: создаем компоновщик макета
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
// Ключевое отличие: указываем тип генератора для коллекции значений
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаСКД, Настройки, , ,
Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));
// Инициализируем процессор компоновки
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки);
// Готовим дерево значений для результата
ДеревоРезультата = Новый ДеревоЗначений;
// Используем специальный процессор вывода
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
ПроцессорВывода.УстановитьОбъект(ДеревоРезультата);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
Теперь в переменной ДеревоРезультата находятся все данные вашего отчета в иерархическом виде. Каждая колонка соответствует полю из СКД, а типы данных (Ссылки, Числа, Даты) полностью сохранены. Проанализируем ситуацию: теперь мы можем легко обойти это дерево рекурсией и записать данные в XML.
Если данных в отчете очень много (десятки и сотни тысяч строк), выгрузка их целиком в ДеревоЗначений может переполнить оперативную память. В таких случаях мы можем использовать ПроцессорКомпоновкиДанных как итератор. Выясним, как это работает.
Метод Следующий() позволяет получать по одной строке за раз, обрабатывать её и сразу записывать в файл. Это наиболее экономичный способ с точки зрения ресурсов.
// ... (инициализация ПроцессораКомпоновки как в примере выше)
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.ОткрытьФайл("C:\Reports\Output.xml", "WINDOWS-1251");
ЗаписьXML.ЗаписатьОбъявлениеXML();
ЗаписьXML.ЗаписатьНачалоЭлемента("Root");
Пока Истина Цикл
ЭлементРезультата = ПроцессорКомпоновки.Следующий();
Если ЭлементРезультата = Неопределено Тогда
Прервать;
КонецЕсли;
// Проверяем, что это детальная запись, а не группировка
Если ЭлементРезультата.ЗначенияПараметров.Количество() > 0 Тогда
ЗаписьXML.ЗаписатьНачалоЭлемента("Row");
Для Каждого Параметр Из ЭлементРезультата.ЗначенияПараметров Цикл
ЗаписьXML.ЗаписатьАтрибут(Параметр.Имя, Строка(Параметр.Значение));
КонецЦикла;
ЗаписьXML.ЗаписатьКонецЭлемента();
КонецЕсли;
КонецЦикла;
ЗаписьXML.ЗаписатьКонецЭлемента();
ЗаписьXML.Закрыть();
Если ваша задача — сформировать отчетность по строго заданной схеме (например, J0208206.xsd, как упоминал автор темы), ручная запись тегов через ЗаписьXML может привести к ошибкам. Правильнее использовать механизм XDTO. Для быстрого старта и изучения этого механизма подойдет обучающий материал по работе с XDTO с нуля.
Разберем по шагам алгоритм работы с XDTO:
.xsd в конфигурацию как Пакет XDTO.ФабрикаXDTO.Создать().ДеревоРезультата (полученное Способом №1) и заполняйте свойства XDTO-объектов.ФабрикаXDTO.ЗаписатьXML() выгрузите всю структуру в файл. 1С сама проследит за типами, порядком полей и пространствами имен.Рассмотрим несколько нюансов, которые помогут сделать ваш отчет более гибким и профессиональным:
1. Настройка параметров: Перед выполнением компоновки программно не забывайте устанавливать параметры (даты периода, организации), иначе запрос вернет пустой результат или ошибку.
ПараметрНачало = Настройки.ПараметрыДанных.Элементы.Найти("НачалоПериода");
Если ПараметрНачало <> Неопределено Тогда
ПараметрНачало.Значение = Объект.ДатаНачала;
ПараметрНачало.Использование = Истина;
КонецЕсли;
2. Имена полей: Помните, что в XML нельзя использовать пробелы в именах тегов. Убедитесь, что в СКД для всех выбранных полей заданы корректные «Пути к данным» без спецсимволов.
3. Литература: Для глубокого изучения работы с СКД крайне рекомендуем книгу Е. Хрусталевой «Разработка сложных отчетов в системе компоновки данных». В ней детально разобраны все программные интерфейсы, включая работу с процессорами вывода.
Таким образом, мы выяснили, что для решения задачи выгрузки в XML нужно отказаться от работы с визуальными формами отчета и перейти к программному управлению ПроцессоромКомпоновкиДанных. Выбор между выгрузкой в ДеревоЗначений или построчным обходом зависит от объема данных, а использование XDTO обеспечит гарантированное соответствие внешней схеме.