При работе с Системой компоновки данных (СКД) программисты часто сталкиваются с задачей постобработки данных — для этого пригодится набор инструментов программиста 1С с консолями запросов и СКД. Например, когда результат отчета нужно не просто показать пользователю, а передать в другую систему, сохранить в специфический формат Excel или использовать для дальнейших расчетов. Стандартный механизм ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений отлично работает для простых списков, но выдает ошибку, если в структуре отчета присутствуют таблицы (кросс-таблицы) или диаграммы. Рассмотрим, как обойти это ограничение и получить данные программно.
Система компоновки данных изначально проектировалась как инструмент для визуализации. Когда мы определяем структуру отчета как «Таблицу» (с группировками в строках и колонках), СКД формирует многомерный результат. Механизм выгрузки в ТаблицаЗначений или ДеревоЗначений «из коробки» не умеет автоматически разворачивать измерения колонок в плоскую структуру. Именно поэтому возникает ошибка: «Не поддерживается вывод таблиц и диаграмм в универсальную коллекцию значений».
Разберем по шагам несколько эффективных способов решения этой задачи, от простых к более продвинутым — также есть готовая обработка выгрузки СКД в таблицу значений.
Этот способ лучше всего подходит, когда нам нужны «сырые» данные из базы, но с учетом всех пользовательских отборов, параметров и условий, которые были заданы в экранной форме отчета — для такой интеграции подойдёт универсальная выгрузка из 1С во внешние СУБД. Мы не выполняем запрос из схемы напрямую, а просим СКД подготовить финальный текст запроса.
Проанализируем программный код, который позволяет это реализовать:
// 1. Получаем схему и настройки
СхемаКомпоновкиДанных = ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
Настройки = КомпоновщикНастроек.ПолучитьНастройки();
// 2. Формируем макет компоновки
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, , , Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));
// 3. Извлекаем текст запроса из первого набора данных
// ВАЖНО: СКД может генерировать текст с учетом временных таблиц
ТекстЗапроса = МакетКомпоновки.НаборыДанных[0].Запрос;
// 4. Выполняем запрос вручную
Запрос = Новый Запрос(ТекстЗапроса);
// 5. Переносим параметры из макета компоновки в запрос
Для Каждого Параметр Из МакетКомпоновки.ЗначенияПараметров Цикл
Запрос.УстановитьПараметр(Параметр.Имя, Параметр.Значение);
КонецЦикла;
РезультатТаблица = Запрос.Выполнить().Выгрузить();
Важные нюансы этого метода:
НаборыДанных[0] может вернуть неполную картину.Чтобы заставить ПроцессорВывода работать, мы можем временно изменить структуру отчета в коде. Вместо сложной таблицы мы создадим плоский список (группировку «Детальные записи»), выгрузим его в таблицу значений, а затем вернем настройки в исходное состояние.
Рассмотрим алгоритм действий:
Структура в настройках.ГруппировкаКомпоновкиДанных.ВыбранныеПоля этой группировки добавим все поля, которые нам необходимы в итоговой таблице значений.Этот метод хорош тем, что он корректно рассчитывает все вычисляемые поля и итоги, так как задействуется полноценный ПроцессорКомпоновкиДанных.
Если нам нужно выгрузить данные из кросс-таблицы, сохранив логику ее построения (например, развернув месяца из колонок в строки или наоборот), следует использовать метод НачатьВывод() объекта ПроцессорКомпоновкиДанных. Это позволяет нам вручную перехватывать каждый элемент результата.
Проанализируем пример обхода:
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки);
ТаблицаРезультат = Новый ТаблицаЗначений;
// Предварительно добавим колонки в ТаблицаРезультат
Пока Истина Цикл
ЭлементРезультата = ПроцессорКомпоновки.Выбрать();
Если ЭлементРезультата = Неопределено Тогда
Прервать;
КонецЕсли;
// Проверяем тип элемента (начало группировки, детальная запись и т.д.)
Если ЭлементРезультата.ТипЭлемента = ТипЭлементаРезультатаКомпоновкиДанных.НачалоГруппировки Тогда
// Здесь можно получить значения полей группировки
НоваяСтрока = ТаблицаРезультат.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, ЭлементРезультата.ЗначенияПараметров);
КонецЕсли;
КонецЦикла;
Данный подход является самым гибким. С его помощью можно реализовать логику «каждый объект на новый лист Excel» (удобно через инструмент экспорта данных из 1С в Excel), обходя дерево группировок верхнего уровня и создавая новый файл или лист при смене значения группировки.
Выясним причину, почему иногда этот «медленный» способ оказывается самым надежным. Если отчет уже сформирован и выведен пользователю на экран, данные в нем уже структурированы и оформлены. Мы можем перебрать области табличного документа.
Для этого удобно использовать свойство ячейки Расшифровка. В нем часто хранятся ссылки на объекты или структуры данных, которые легли в основу этой ячейки. Проходя циклом по строкам и колонкам ТабличныйДокумент, мы можем программно заполнить свою ТаблицуЗначений, анализируя текст в ячейках или их расшифровку.
Подведем итог и выберем оптимальный путь:
Выполняя эти рекомендации, вы сможете эффективно манипулировать данными СКД и решать задачи любой сложности по экспорту и преобразованию отчетности. Для построения сквозной аналитики есть автоматизированная выгрузка данных из 1С в BI-системы.