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