При работе с Системой компоновки данных (СКД) пользователи и разработчики часто сталкиваются с ограничением: в пользовательских полях (те, которые создаются непосредственно в режиме «1С:Предприятие» в настройках отчета) невозможно использовать оператор В ИЕРАРХИИ. Этот оператор является специфической конструкцией языка запросов 1С и работает только на уровне выполнения запроса к базе данных. Когда же мы настраиваем выражение в пользовательском поле, расчет происходит уже на этапе компоновки результата, где доступен лишь ограниченный набор функций.
В данной статье мы разберем несколько способов решения этой задачи: от простого (но «хрупкого») метода проверки уровней вложенности до архитектурно правильных подходов с использованием сегментов и дополнительных реквизитов.
Если структура справочника номенклатуры имеет фиксированную или ограниченную глубину вложенности, мы можем проверить каждого родителя по отдельности. Рассмотрим ситуацию, когда нам нужно посчитать выручку только для товаров, входящих в группу «Молоко» (включая все подгруппы: «Молоко козье», «Молоко козье премиум» и т.д.).
Проанализируем выражение, которое позволяет обойти отсутствие иерархического оператора через последовательную проверку наименований групп:
Сумма(Выбор
Когда [Номенклатура.Группа.Наименование] = "Молоко"
Тогда Выручка
Когда [Номенклатура.Группа.Группа.Наименование] = "Молоко"
Тогда Выручка
Когда [Номенклатура.Группа.Группа.Группа.Наименование] = "Молоко"
Тогда Выручка
Когда [Номенклатура.Группа.Группа.Группа.Группа.Наименование] = "Молоко"
Тогда Выручка
Иначе 0
Конец)
Важные замечания к этому методу:
Для конфигураций на базе «1С:Управление торговлей 11», «1С:ERP» или «1С:Комплексная автоматизация» наиболее правильным решением будет использование механизма Сегментов номенклатуры. Сегмент — это гибкий инструмент, который позволяет объединить товары по любым правилам, включая иерархию, и затем обращаться к этому объединению в отчетах.
Разберем алгоритм действий:
Номенклатура В ИЕРАРХИИ [Ваша Группа].В пользовательских полях СКД напрямую обратиться к регистру сведений НоменклатураСегмента сложно, однако вы можете использовать сегмент в качестве Отбора в настройках отчета. Если же вам нужно именно вычисляемое поле, которое разделяет выручку по сегментам, это лучше реализовать через Вычисляемые поля в Конфигураторе, используя функцию общего модуля:
// Пример выражения в вычисляемом поле (в конфигураторе)
ВЫБОР
КОГДА СегментыСервер.ПроверитьВхождениеВСегмент(Номенклатура, &СсылкаНаСегмент)
ТОГДА Выручка
ИНАЧЕ 0
КОНЕЦ
Если вам часто требуется аналитика в разрезе определенных групп, которые не всегда совпадают с физической иерархией папок в справочнике, проанализируем вариант с Дополнительными реквизитами. Группировка по папкам в 1С часто служит для удобства поиска, а не для финансовой аналитики.
Выполним следующие шаги:
Номенклатура дополнительный реквизит «Товарная категория» (тип: Дополнительное значение).
ВЫБОР
КОГДА [Номенклатура.Товарная категория] = "Молочные продукты"
ТОГДА Выручка
ИНАЧЕ 0
КОНЕЦ
Этот подход избавляет от зависимости от структуры папок и исключает ошибки, связанные с изменением уровней вложенности.
Посмотрим на проблему с технической стороны. Оператор В ИЕРАРХИИ требует выполнения рекурсивного запроса к базе данных или обращения к специальным промежуточным таблицам иерархии, которые платформа 1С создает «под капотом». Когда система выполняет запрос основного набора данных, она получает плоскую таблицу.
Пользовательское выражение вычисляется после того, как основные данные уже получены. На этом этапе у системы нет возможности отправить новый запрос к БД для выяснения всех «предков» конкретного товара, если они не были выбраны заранее. Именно поэтому приходится либо «прокидывать» родителей через точки (как в Способе 1), либо использовать заранее подготовленные данные (как в Способах 2 и 3).
Если вы все же решили использовать проверку через Родитель.Наименование, постарайтесь минимизировать количество уровней и всегда проверяйте типы данных. В языке запросов или вычисляемых полях полезно использовать функцию ВЫРАЗИТЬ, чтобы система четко понимала, с каким типом справочника она работает:
ВЫРАЗИТЬ(Номенклатура КАК Справочник.Номенклатура).Родитель.Наименование
Также помните, что сравнение со строкой ("Молоко") в коде — это плохая практика («магические строки»). По возможности используйте параметры, куда передается ссылка на конкретную группу, или создавайте предопределенные элементы, если это оправдано логикой задачи.