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

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

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

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

Способ 1. Метод «Елочки» (проверка цепочки родителей)

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

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


Сумма(Выбор
    Когда [Номенклатура.Группа.Наименование] = "Молоко"
        Тогда Выручка
    Когда [Номенклатура.Группа.Группа.Наименование] = "Молоко"
        Тогда Выручка
    Когда [Номенклатура.Группа.Группа.Группа.Наименование] = "Молоко"
        Тогда Выручка
    Когда [Номенклатура.Группа.Группа.Группа.Группа.Наименование] = "Молоко"
        Тогда Выручка
    Иначе 0
Конец)

Важные замечания к этому методу:

Способ 2. Использование сегментов номенклатуры (рекомендуемый)

Для конфигураций на базе «1С:Управление торговлей 11», «1С:ERP» или «1С:Комплексная автоматизация» наиболее правильным решением будет использование механизма Сегментов номенклатуры. Сегмент — это гибкий инструмент, который позволяет объединить товары по любым правилам, включая иерархию, и затем обращаться к этому объединению в отчетах.

Разберем алгоритм действий:

  1. Создайте новый сегмент номенклатуры (например, «Продукция группы Молоко»).
  2. Настройте способ формирования сегмента: Формировать динамически или Периодически обновлять.
  3. В схеме компоновки сегмента укажите условие: Номенклатура В ИЕРАРХИИ [Ваша Группа].
  4. В основном отчете вместо проверки иерархии используйте проверку вхождения в сегмент.

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


// Пример выражения в вычисляемом поле (в конфигураторе)
ВЫБОР 
    КОГДА СегментыСервер.ПроверитьВхождениеВСегмент(Номенклатура, &СсылкаНаСегмент) 
    ТОГДА Выручка 
    ИНАЧЕ 0 
КОНЕЦ

Способ 3. Использование дополнительных реквизитов

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

Выполним следующие шаги:

  1. Добавьте для справочника Номенклатура дополнительный реквизит «Товарная категория» (тип: Дополнительное значение).
  2. С помощью групповой обработки заполните этот реквизит для всех нужных товаров (значение «Молочные продукты»).
  3. В пользовательском поле СКД выражение станет предельно простым и надежным:

ВЫБОР 
    КОГДА [Номенклатура.Товарная категория] = "Молочные продукты" 
    ТОГДА Выручка 
    ИНАЧЕ 0 
КОНЕЦ

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

Почему не работает В ИЕРАРХИИ в пользовательских полях?

Посмотрим на проблему с технической стороны. Оператор В ИЕРАРХИИ требует выполнения рекурсивного запроса к базе данных или обращения к специальным промежуточным таблицам иерархии, которые платформа 1С создает «под капотом». Когда система выполняет запрос основного набора данных, она получает плоскую таблицу.

Пользовательское выражение вычисляется после того, как основные данные уже получены. На этом этапе у системы нет возможности отправить новый запрос к БД для выяснения всех «предков» конкретного товара, если они не были выбраны заранее. Именно поэтому приходится либо «прокидывать» родителей через точки (как в Способе 1), либо использовать заранее подготовленные данные (как в Способах 2 и 3).

Рекомендации по оптимизации

Если вы все же решили использовать проверку через Родитель.Наименование, постарайтесь минимизировать количество уровней и всегда проверяйте типы данных. В языке запросов или вычисляемых полях полезно использовать функцию ВЫРАЗИТЬ, чтобы система четко понимала, с каким типом справочника она работает:

ВЫРАЗИТЬ(Номенклатура КАК Справочник.Номенклатура).Родитель.Наименование

Также помните, что сравнение со строкой ("Молоко") в коде — это плохая практика («магические строки»). По возможности используйте параметры, куда передается ссылка на конкретную группу, или создавайте предопределенные элементы, если это оправдано логикой задачи.

← На главную