Как получить значение из родительской группы в детальных записях СКД

Программист 1С v8.3 (Управляемые формы) Управленческий учет Промышленность, строительство и АПК
← На главную

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

Метод 1. Использование функции ВычислитьВыражение в ресурсах

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

Для этого в поле «Выражение» на вкладке «Ресурсы» можно использовать следующую конструкцию:

ВычислитьВыражение("Максимум(Коэффициент)", "Иерархия", "Группировка")

Рассмотрим параметры этой функции:

  1. Первый параметр: Агрегатная функция над полем, которое мы хотим получить (например, Максимум или Сумма, если коэффициент один в группе).
  2. Второй параметр: Имя группировки, из которой нужно взять данные. Если мы укажем "Иерархия", система будет искать значение в этой конкретной группировке.
  3. Третий параметр: Область поиска. Значение "Группировка" указывает системе, что расчет должен производиться в контексте текущей иерархической ветки.

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

Метод 2. Предварительная подготовка данных в запросе (Join)

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

Рассмотрим пример кода на языке запросов 1С, который объединяет иерархическую структуру и детальные данные:


ВЫБРАТЬ
    Данные.КлючДетали,
    Данные.Номенклатура,
    Данные.Количество,
    Иерархия.Коэффициент КАК КоэффициентИерархии
ИЗ
    &ТЗИерархия КАК Иерархия
ЛЕВОЕ СОЕДИНЕНИЕ 
    &ТЗДанные КАК Данные
ПО 
    Иерархия.КлючДетали = Данные.КлючДетали

Этот метод гарантирует, что в каждой строке детальных записей уже будет присутствовать КоэффициентИерархии. Однако, как было замечено в обсуждении, если одна и та же деталь входит в разные узлы, при обычном соединении могут возникнуть дубли. Чтобы этого избежать, проанализируем ситуацию: необходимо использовать уникальные идентификаторы (ключи связи) для каждой ветки дерева, а не просто ссылку на объект (например, Номенклатура).

Метод 3. Связи наборов данных (Recursive Links)

В СКД есть мощный механизм — связи наборов данных. Если у вас есть два набора (один для иерархии, другой для деталей), вы можете настроить их связь на соответствующей вкладке конструктора схемы.

  1. Создадим первый набор данных НаборИерархия, который выбирает узлы и их коэффициенты.
  2. Создадим второй набор данных НаборДетали.
  3. На вкладке «Связи наборов данных» свяжем их по полю КлючУзла.
  4. В колонке «Параметры связи» укажем, что значение коэффициента из первого набора должно передаваться в дочерние записи.

Это позволяет системе автоматически «пробрасывать» значения из родительского набора в подчиненный для каждой строки. Выясним причину, почему это работает лучше простого запроса: СКД строит дерево итеративно, и при обращении к деталям она уже «знает», в контексте какого родителя она находится.

Метод 4. Вычисляемые поля и системное поле Уровень

Если нам нужно различать логику вывода в самой группе и в деталях, мы можем использовать вычисляемое поле с проверкой системного поля Уровень. Рассмотрим подробнее конструкцию в выражении вычисляемого поля:


Выбор 
    Когда Уровень > 0 
        Тогда ВычислитьВыражение("Коэффициент", "Иерархия", "Группировка") 
    Иначе Коэффициент 
Конец

Здесь мы явно указываем: если это не корень дерева (уровень больше 0), мы берем значение методом вычисления по группировке. Это позволяет избежать ошибок Null в корневых записях и корректно отобразить данные в детальных строках.

Метод 5. Программная обработка через Внешнюю Функцию

В сложных случаях, когда иерархия строится по нетривиальным правилам (например, расчет спецификаций в УПП или ERP), можно прибегнуть к вызову функции общего модуля. В выражении поля СКД пишем:

ПолучитьКоэффициентРодителя(Номенклатура, КлючСвязи)

Сама функция в общем модуле (с флагом «Сервер») должна выглядеть примерно так:


Функция ПолучитьКоэффициентРодителя(ТекущаяНоменклатура, Ключ) Экспорт
    // Логика поиска коэффициента в кэшированной таблице или через запрос
    // Возвращаем найденное Число
КонецФункции

Важно: этот метод может существенно замедлить формирование отчета, если записей десятки тысяч, так как функция будет вызываться для каждой строки. Рекомендуется использовать кэширование (например, через ПараметрыСеанса или статические переменные модуля) для хранения таблицы соответствий.

Рекомендации по настройке ресурсов

При настройке полей в ресурсах, обратим внимание на колонку «Рассчитывать по...». Часто ошибка кроется именно здесь. Для поля Коэффициент, который должен отображаться в деталях:

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

Заключение

Мы разобрали пять различных подходов к получению данных из родительских групп. Выбор метода зависит от объема данных и сложности вашей иерархии. Для простых отчетов идеально подойдет ВычислитьВыражение. Для высоконагруженных систем с внешними источниками данных лучше подготовить таблицу заранее в коде 1С, обеспечив уникальность связей через дополнительные ключи (GUID или составные ключи).

← На главную