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

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

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

Почему фильтрация в запросе не всегда дает нужный результат

Когда мы пишем запрос с использованием ИТОГИ ПО ... ИЕРАРХИЯ, платформа 1С выполняет SQL-запрос для получения «плоской» выборки, а затем сама надстраивает дерево итогов. Если вы добавите условие ГДЕ, чтобы отсечь корневую группу, вы просто удалите её из детальных записей, но если эта группа является единственным «предком» для остальных элементов, механизм иерархии может повести себя непредсказуемо или вовсе вернуть плоский список. Понимание того, что иерархия достраивается движком платформы уже после получения данных, помогает нам выбрать верный путь решения.

Способ 1: Постобработка дерева значений

Это наиболее гибкий метод, который позволяет оставить основной запрос без изменений и просто «подчистить» полученный результат. Мы получаем полное дерево, а затем программно находим корневую группу и переносим её потомков на уровень вверх, после чего удаляем саму группу.

Рассмотрим пример реализации функции для переноса веток:


Процедура Перенести(Ветка, Куда, Индекс = Неопределено) Экспорт
    Если Индекс = Неопределено Тогда
        НоваяВетка = Куда.Строки.Добавить();
    Иначе
        НоваяВетка = Куда.Строки.Вставить(Индекс);
    КонецЕсли;
    ЗаполнитьЗначенияСвойств(НоваяВетка, Ветка); 
    Для каждого ПодСтрока из Ветка.Строки цикл 
        Перенести(Подстрока, НоваяВетка); 
    КонецЦикла;
    Ветка.Родитель.Строки.Удалить(Ветка);
КонецПроцедуры

После получения результата запроса через Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией), мы перебираем верхний уровень дерева. Как только находим нужную нам группу (например, «Товары»), мы вызываем процедуру переноса для всех её дочерних элементов в основной корень дерева, а затем удаляем саму группу.

Способ 2: Формирование дерева через вложенные временные таблицы

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

Разберем пример запроса, который отсекает верхний уровень:


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

ВЫБРАТЬ
    Номенклатура.Ссылка КАК Ссылка
ПОМЕСТИТЬ ВТ
ИЗ
    Справочник.Номенклатура КАК Номенклатура
ГДЕ
    Номенклатура.ЭтоГруппа
    И Номенклатура.Родитель В (ВЫБРАТЬ Т.Ссылка ИЗ ВТ0 КАК Т)
;

ВЫБРАТЬ
    Номенклатура.Ссылка КАК Ссылка
ИЗ
    Справочник.Номенклатура КАК Номенклатура
ГДЕ
    Номенклатура.Ссылка В ИЕРАРХИИ (ВЫБРАТЬ Т.Ссылка ИЗ ВТ КАК Т)
УПОРЯДОЧИТЬ ПО
    Ссылка ИЕРАРХИЯ

В этом примере мы сначала находим группы верхнего уровня (ВТ0), затем находим их дочерние группы (ВТ), и в конечном запросе выводим всё, что находится «в иерархии» от этих найденных под-групп. Таким образом, корневые элементы (родители) исключаются из выборки, и итоговое дерево начинается сразу со второго уровня.

Важные рекомендации

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

← На главную