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