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

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

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

Почему в БСП нет универсальной функции для вывода СКД в таблицу значений?

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

  1. Сложная структура. Отчеты СКД — это далеко не всегда плоские таблицы. Они могут содержать вложенные иерархические группировки, несколько таблиц в одном отчете (встречаются даже две разных схемы в отчете СКД), диаграммы, кросс-таблицы (когда значения одной колонки становятся новыми колонками). Однозначно представить такую сложную структуру в виде одной `ТаблицыЗначений` невозможно без потерь.
  2. Расчет итогов и ресурсов. В СКД ресурсы (итоги) рассчитываются для каждого уровня группировки. При выгрузке в плоскую таблицу возникает вопрос: как отображать эти итоги? Включать их отдельными строками? Добавлять отдельные колонки? Любое универсальное решение будет компромиссом и не подойдет для всех случаев.
  3. Разнообразие настроек. Пользовательские настройки отчета (отборы, сортировки, выбранные поля, условное оформление) кардинально меняют итоговый результат. Функция должна была бы учитывать все возможные комбинации, что делает ее неоправданно громоздкой.

Именно поэтому в типовых конфигурациях разработчики часто создают свои, узкоспециализированные функции для выгрузки конкретных отчетов, как, например, ФинансоваяОтчетностьСервер.ВыгрузитьРезультатСКД в 1С:ERP. При этом часто приходится учитывать наименование отчета в конфигурации с БСП, чтобы корректно связать результат с вариантом отчета. Эти "велосипеды" создаются не от хорошей жизни, а потому, что они точно адаптированы под структуру и логику конкретного отчета.

Правильный способ: используем платформенный механизм

Несмотря на отсутствие готовой функции в БСП, платформа 1С предоставляет все необходимые инструменты для решения этой задачи. Ключевым объектом здесь является ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений. Он позволяет направить результат работы СКД напрямую в ТаблицуЗначений или ДеревоЗначений.

Рассмотрим по шагам, как это сделать. Алгоритм будет следующим:

  1. Получить схему компоновки данных из макета отчета.
  2. Получить и, при необходимости, изменить настройки компоновки данных.
  3. Скомпоновать макет на основе схемы и настроек.
  4. Инициализировать процессор компоновки данных.
  5. Инициализировать процессор вывода результата в коллекцию значений.
  6. Выполнить вывод и получить готовую таблицу.

Посмотрим на пример кода, который реализует этот алгоритм. А для тех, кто хочет максимально сократить подобный код, существует СКДБилдер, упрощающий программную работу со схемами.


Функция СформироватьОтчетСКДВТаблицуЗначений(ИмяОтчета, ИмяМакета, НастройкиОтчета)

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

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

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

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

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

КонецФункции

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

Важный момент: этот подход отлично работает для "плоских" отчетов, где нет сложной иерархии. Если в отчете есть группировки, результат будет содержать только детальные записи, без итоговых строк. Для получения иерархического результата следует использовать в качестве приемника ДеревоЗначений.

Дискуссия: СКД или прямой запрос?

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

Аргументы "ЗА" использование СКД для получения данных

Аргументы "ПРОТИВ" (в пользу прямых запросов)

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

← На главную