Как программно получить данные из сложного отчета СКД в виде простой таблицы?

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

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

Проанализируем ситуацию: у нас есть готовый отчет СКД, который выводит информацию в удобном для пользователя, но неудобном для программной обработки виде. Наша цель — получить из этого отчета ТаблицуЗначений, содержащую все детальные записи без группировок и форматирования.

Решение 1: Программное формирование отчета с использованием специального варианта настроек

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

Разберем по шагам, как это реализовать:

  1. Создаем "плоский" вариант настроек. Откройте нужный отчет в режиме пользователя (1С:Предприятие). В настройках отчета перейдите на вкладку "Структура". Здесь вы увидите все группировки. Ваша задача — отключить или удалить все группировки, оставив только уровень "Детальные записи". После этого сохраните получившийся вариант настроек под понятным именем, например, "Для выгрузки в таблицу". Эти настройки сохранятся в справочнике ВариантыОтчетов.

  2. Пишем код для программного формирования. Теперь, имея упрощенный вариант, мы можем использовать его в коде для получения данных напрямую в ТаблицуЗначений.

    Для этого нам понадобится следующая последовательность объектов и методов:

    • КомпоновщикМакетаКомпоновкиДанных — этот объект подготовит макет для вывода.
    • ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений — специальный генератор, который указывает системе, что результат нужно подготовить для выгрузки в коллекцию, а не в табличный документ.
    • ПроцессорКомпоновкиДанных — выполняет подготовку данных на основе макета.
    • ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений — непосредственно выводит результат в указанный приемник (нашу ТаблицуЗначений).

Посмотрим на пример кода, который реализует этот механизм:


// Получаем схему компоновки данных из отчета
СхемаКомпоновкиДанных = Отчеты.МойСуперОтчет.ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");

// Получаем наш специальный вариант настроек
// Его можно получить по ключу из справочника ВариантыОтчетов или задать программно
Настройки = СхемаКомпоновкиДанных.НастройкиПоУмолчанию; // Для примера возьмем по умолчанию, но лучше загрузить сохраненный вариант

// 1. Создаем компоновщик макета
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;

// 2. Генерируем макет для вывода в коллекцию значений
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, , , Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));

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

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

// Выводим результат
ПроцессорВывода.Вывести(ПроцессорКомпоновки);

// Теперь в переменной РезультатТаблица находится искомая плоская таблица

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

Если нет возможности создать отдельный вариант настроек, можно модифицировать существующий прямо в коде. Для этого нужно получить доступ к структуре отчета через КомпоновщикНастроек.Настройки.Структура и программно отключить ненужные группировки, установив для них свойство Использование в значение Ложь.

Решение 2: Выгрузка результата в Excel и последующая обработка

Этот способ можно считать обходным маневром. Он подходит, если первый метод по каким-то причинам не сработал или кажется слишком сложным. Идея в том, чтобы сформировать отчет как обычно, сохранить его в формат Excel, а затем прочитать этот файл средствами 1С и преобразовать в таблицу.

Разберем по шагам:

  1. Формируем и сохраняем отчет. Программно или вручную формируем отчет и сохраняем результат (ТабличныйДокумент) во временный файл в формате XLS или XLSX.

  2. Читаем данные из файла Excel. С помощью объекта ТабличныйДокумент читаем сохраненный файл обратно в систему.

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

Посмотрим на пример кода, иллюстрирующий чтение и обработку файла:


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

// Теперь читаем его обратно
ТабДокИзФайла = Новый ТабличныйДокумент;
ТабДокИзФайла.Прочитать(ИмяВременногоФайла);
УдалитьФайлы(ИмяВременногоФайла);

// Получаем нужную область данных (номера строк и колонок нужно определить заранее)
// Например, мы знаем, что данные начинаются с 5-й строки и 1-й колонки
ОбластьДанных = ТабДокИзФайла.Область(5, 1, ТабДокИзФайла.ВысотаТаблицы, ТабДокИзФайла.ШиринаТаблицы);

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

ТаблицаДанных = ПостроительЗапроса.Выполнить().Выгрузить();

// В переменной ТаблицаДанных теперь находятся наши данные

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

Решение 3: Прямой запрос к исходным данным

Иногда самый простой путь — самый короткий. Проанализируем, какие данные использует отчет СКД. Для этого можно открыть схему компоновки и посмотреть наборы данных-запросы. Если логика формирования данных не слишком сложна, можно "воссоздать" основной запрос из СКД в своем коде и выполнить его напрямую, получив сразу готовую таблицу.

Этот метод имеет свои плюсы:

Однако он требует хорошего понимания как самого запроса в СКД, так и структуры данных в базе. Если в отчете используется сложная логика вычисляемых полей, нескольких наборов данных и их связей, воспроизвести это вручную может быть очень трудоемко.

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

← К списку