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

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

При разработке отчетов и обработок в 1С часто возникает задача: выбрать элементы справочника (например, Номенклатура) и определить, к какой именно из заданных верховых групп (родителей) они принадлежат. Если иерархия имеет развитую структуру со множеством подгрупп (Товары11, Товары12, Товары131 и т. д.), простым обращением к реквизиту Родитель обойтись не удастся.

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

Ограничения платформы 1С при работе с оператором В ИЕРАРХИИ

Проанализируем базовые ограничения языка запросов 1С, которые мешают решить задачу «в лоб»:

  1. Запрет на использование В ИЕРАРХИИ в секции группировки: Платформа не позволяет группировать данные по выражению, содержащему иерархическую проверку. Попытка написать ГРУППИРОВАТЬ ПО ВЫБОР КОГДА Номенклатура В ИЕРАРХИИ(&Группа1) ... приведет к ошибке выполнения запроса.
  2. Ограничение в условиях соединения: Оператор В ИЕРАРХИИ нельзя использовать в секции ПО при левом, правом или полном соединении таблиц.

Разберем наиболее изящные и производительные способы обхода этих ограничений.

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

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

Шаг 1. В первом запросе вычисляем родительскую группу с помощью конструкции ВЫБОР КОГДА ... В ИЕРАРХИИ и сохраняем результат во временную таблицу.

Шаг 2. Во втором запросе обращаемся к временной таблице, где поле с родительской группой уже является готовой ссылкой, и свободно выполняем любые группировки или агрегации.

Рассмотрим пример кода 1С:


ВЫБРАТЬ
	Товары.Ссылка КАК Товар,
	ВЫБОР
		КОГДА Товары.Ссылка В ИЕРАРХИИ(&ГруппаТовары1) ТОГДА &ГруппаТовары1
		КОГДА Товары.Ссылка В ИЕРАРХИИ(&ГруппаТовары2) ТОГДА &ГруппаТовары2
		КОГДА Товары.Ссылка В ИЕРАРХИИ(&ГруппаТовары3) ТОГДА &ГруппаТовары3
	КОНЕЦ КАК РодительскаяГруппа
ПОМЕСТИТЬ ВТ_ТоварыСГруппами
ИЗ
	Справочник.Номенклатура КАК Товары
ГДЕ
	Товары.Ссылка В ИЕРАРХИИ(&СписокВсехГрупп);

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	ВТ.РодительскаяГруппа КАК РодительскаяГруппа,
	ВТ.Товар КАК Товар,
	КОЛИЧЕСТВО(1) КАК Количество
ИЗ
	ВТ_ТоварыСГруппами КАК ВТ
ГРУППИРОВАТЬ ПО
	ВТ.РодительскаяГруппа,
	ВТ.Товар;

Этот подход не требует динамического формирования текста запроса в цикле через ОБЪЕДИНИТЬ ВСЕ, выглядит лаконично и выполняется достаточно быстро на стороне СУБД.

Способ 2. Явная проверка уровней иерархии через реквизит Родитель

Если глубина вложенности справочника заранее ограничена (например, структура гарантированно не превышает 3–4 уровней), можно обойтись без оператора В ИЕРАРХИИ. В этом случае проверка выполняется через последовательное обращение к родительским элементам.

Посмотрим на пример такого запроса:


ВЫБРАТЬ
	Товары.Ссылка КАК Товар,
	ВЫБОР
		КОГДА Товары.Родитель В (&СписокРодительскихГрупп) 
			ТОГДА Товары.Родитель
		КОГДА Товары.Родитель.Родитель В (&СписокРодительскихГрупп) 
			ТОГДА Товары.Родитель.Родитель
		КОГДА Товары.Родитель.Родитель.Родитель В (&СписокРодительскихГрупп) 
			ТОГДА Товары.Родитель.Родитель.Родитель
	КОНЕЦ КАК РодительскаяГруппа
ИЗ
	Справочник.Номенклатура КАК Товары
ГДЕ
	Товары.Ссылка В ИЕРАРХИИ(&СписокРодительскихГрупп);

Преимущества метода:

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

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

Способ 3. Использование Системы компоновки данных (СКД)

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

Проанализируем порядок действий при работе с СКД:

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

Это позволяет полностью переложить распределение элементов по группам на платформу 1С без усложнения текста запроса.

← На главную