Как вывести значение на уровне иерархии групп в СКД 1С

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

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

Выясним причину: почему СКД не присоединяет данные к группам

Рассмотрим механику работы платформы 1С при компоновке отчета. Если в первом наборе данных содержатся только конечные элементы (детальные записи), а во втором наборе хранятся показатели как для элементов, так и для их родителей (групп), стандартная связь наборов данных по полю ссылки не сработает для групп.

Причина заключается в последовательности выполнения операций компоновщиком макета СКД:

  1. Платформа сначала выполняет связь наборов данных на уровне реально существующих строк (детальных записей).
  2. Виртуальные узлы-группы, формирующие визуальное дерево иерархии, создаются компоновщиком позже — уже на этапе построения группировок отчета.

Поскольку на момент связывания наборов элементов-групп в первом наборе физически не существует, платформа не может сопоставить с ними строки из второго источника. В результате напротив родительских узлов выводится значение NULL или агрегированная сумма дочерних элементов.

Способ 1. Подготовка иерархии внутри одного набора данных (Рекомендуемый)

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

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


ВЫБРАТЬ
	Номенклатура.Ссылка КАК Ссылка,
	Номенклатура.Родитель КАК Родитель,
	ЛОЖЬ КАК ЭтоГруппа
ПОМЕСТИТЬ ВТ_Иерархия
ИЗ
	Справочник.Номенклатура КАК Номенклатура
ГДЕ
	НЕ Номенклатура.ЭтоГруппа

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ РАЗЛИЧНЫЕ
	Номенклатура.Родитель,
	Номенклатура.Родитель.Родитель,
	ИСТИНА
ИЗ
	Справочник.Номенклатура КАК Номенклатура
ГДЕ
	Номенклатура.Родитель <> ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка)
;

ВЫБРАТЬ
	ТекИерархия.Ссылка КАК Элемент,
	ТекИерархия.Родитель КАК Родитель,
	ЕСТЬНУЛЛ(ТаблицаПоказателей.Значение, 0) КАК Значение
ИЗ
	ВТ_Иерархия КАК ТекИерархия
	ЛЕВОЕ СОЕДИНЕНИЕ РегионЗначений КАК ТаблицаПоказателей
		ПО ТекИерархия.Ссылка = ТаблицаПоказателей.Элемент

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

Способ 2. Настройка собственной иерархии через связи наборов данных

Если данные обязательно должны поступать из разных источников (например, один из наборов — это объект ТаблицаЗначений), перенастроим связи наборов данных в СКД.

Вместо использования стандартной авто-иерархии зададим связи вручную:

  1. В первом наборе данных выберем поля Ссылка и Родитель.
  2. На вкладке Связи наборов данных добавим связь первого набора с самим собой:
    • Выражение источник: Родитель
    • Выражение приемник: Ссылка
    • Параметр: &Ссылка
    • Условие связи: укажем значение начального условия (например, ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка)).
  3. Добавим связь со вторым набором данных по полю Ссылка.

При явном задании иерархических связей система компоновки рекурсивно запрашивает данные для каждого узла дерева, что позволяет правильно подтянуть показатели из второго источника как для листьев, так и для групп.

Способ 3. Переопределение выражения ресурса для разных уровней

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

Перейдем на вкладку Ресурсы и добавим поле Значение дважды:

  1. Для поля Значение с указанием группировки Элемент зададим стандартное выражение: Сумма(Значение)
  2. Для поля Значение с указанием группировки Элемент Иерархия пропишем выражение с использованием функций языка СКД, например, ВычислитьВыражение(): ВычислитьВыражение("Сумма(Значение)", "Элемент", "Иерархия")

Это позволяет разграничить расчеты: детальные записи будут выводить собственные значения, а иерархические узлы — рассчитывать значения с учетом переданного контекста группировки.

← На главную