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