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

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

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

Зачем выводить СКД в таблицу значений?

Прежде чем мы перейдем к коду, давайте проанализируем ситуации, когда стандартный вывод в ТабличныйДокумент нам не подходит. Чаще всего это требуется для:

  1. Передачи данных отчета во внешние системы через API (JSON, XML) — для этого подойдёт обработка автоматической выгрузки данных СКД во внешние системы.
  2. Программного анализа итоговых цифр для принятия решений в бизнес-логике.
  3. Использования СКД как мощного конструктора запросов с автоматическим наложением отборов и параметров.
  4. Последующего объединения результатов нескольких отчетов в одну структуру данных. Если задача сложная, иногда приходится использовать две разных схемы в одном отчете СКД.

Основные этапы программного формирования отчета

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

Шаг 1. Инициализация схемы и настроек

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


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

// Получаем настройки по умолчанию или из конкретного варианта
Настройки = СхемаКомпоновкиДанных.НастройкиПоУмолчанию;

Важно помнить, что НастройкиПоУмолчанию содержат структуру, заданную в конфигураторе. Если пользователь изменил настройки на форме, их нужно извлекать из КомпоновщикНастроек.Настройки.

Шаг 2. Работа с параметрами и отборами

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


// Установка значения параметра "Период"
ПараметрПериод = Настройки.ПараметрыДанных.Элементы.Найти("Период");
Если ПараметрПериод <> Неопределено Тогда
    ПараметрПериод.Значение = Новый СтандартныйПериод(НачалоМесяца(ТекущаяДата()), КонецМесяца(ТекущаяДата()));
    ПараметрПериод.Использование = Истина;
КонецЕсли;

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

Шаг 3. Компоновка макета

Теперь наступает критически важный момент — создание макета компоновки. На этом этапе 1С объединяет схему, настройки и данные информационной базы в готовый "чертеж" отчета. Для этого мы используем объект КомпоновщикМакетаКомпоновкиДанных.


КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;

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

Обратите внимание на последний параметр метода Выполнить. Мы явно указываем тип генератора макета для коллекции значений. Это оптимизирует процесс, так как платформе не нужно рассчитывать оформление (цвета, шрифты), которое необходимо только для табличного документа.

Шаг 4. Инициализация процессора компоновки

Следующим шагом мы создаем ПроцессорКомпоновкиДанных. Этот объект отвечает за выполнение запросов к базе данных и расчет итогов в соответствии с макетом. Если ваша схема использует внешние наборы данных (например, таблицу значений), стоит заранее изучить вопросы оптимизации отчетов с набором данных - объект, чтобы избежать проблем с производительностью.


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

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

Шаг 5. Вывод в Таблицу значений

Финальный этап — получение результата. Вместо привычного вывода в ТабличныйДокумент, мы используем специальный класс ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений.


// Создаем таблицу, куда попадут данные
ТаблицаРезультат = Новый ТаблицаЗначений;

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

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

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

Особенности и тонкости реализации

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

Полезный совет: Если вам нужны только детальные записи без итогов, убедитесь, что в Настройки выбрана только группировка "Детальные записи" и отсутствуют общие итоги.

Полный пример функции для использования в модуле

Для удобства совместной работы, объединим всё вышесказанное в одну конструкцию. Подобная универсальная функция ПолучитьРезультатСКД() позволяет рассчитывать таблицы даже по данным из внешней базы через COM-соединение.


Функция ПолучитьТаблицуИзСКД(ИмяОтчета, ИмяМакета) Экспорт
    
    Схема = Отчеты[ИмяОтчета].ПолучитьМакет(ИмяМакета);
    Настройки = Схема.НастройкиПоУмолчанию;
    
    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
    Макет = КомпоновщикМакета.Выполнить(Схема, Настройки, , , Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));
    
    ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
    ПроцессорКомпоновки.Инициализировать(Макет);
    
    Результат = Новый ТаблицаЗначений;
    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
    ПроцессорВывода.УстановитьОбъект(Результат);
    ПроцессорВывода.Вывести(ПроцессорКомпоновки);
    
    Возврат Результат;
    
КонецФункции

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

← На главную