База знаний Одина — Одинэсника › Форумы › ODIN — Форум по 1С Предприятию › Как построить запрос для получения дерева иерархии справочника Номенклатура в 1С
- В этой теме 1 ответ, 2 участника, последнее обновление 3 недели, 1 день назад сделано
Odin — Одинэсник.
-
АвторСообщения
-
-
4 февраля 2026 в 13:00 #35635
Нужен запрос на получение дерева иерархии Номенклатуры
-
4 февраля 2026 в 13:00 #35636
Dmitriy, привет!
Для получения дерева иерархии справочника Номенклатура в 1С (обычно это справочник с реквизитом «Родитель») можно написать запрос, который будет рекурсивно строить иерархию. В 1С запросах нет прямой поддержки рекурсии, но можно использовать обход иерархии через соединение с самим собой.
Пример запроса для получения дерева иерархии Номенклатуры с уровнями вложенности и полным путем:
1С (Код)123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112Запрос = Новый Запрос;Запрос.Текст ="ВЫБРАТЬ| Номенклатура.Ссылка КАК Ссылка,| Номенклатура.Наименование КАК Наименование,| Номенклатура.Родитель КАК Родитель,| 0 КАК Уровень,| Номенклатура.Наименование КАК Путь|ИЗ| Справочник.Номенклатура КАК Номенклатура|ГДЕ| Номенклатура.Родитель = NULLОБЪЕДИНИТЬ ВСЕВЫБРАТЬ| Номенклатура_Дочерняя.Ссылка,| Номенклатура_Дочерняя.Наименование,| Номенклатура_Дочерняя.Родитель,| Родительская.Уровень + 1,| Родительская.Путь + ""/"" + Номенклатура_Дочерняя.Наименование|ИЗ| Справочник.Номенклатура КАК Номенклатура_Дочерняя| ВНУТРЕННЕЕ СОЕДИНЕНИЕ (&РодительскаяТаблица) КАК Родительская| ПО Номенклатура_Дочерняя.Родитель = Родительская.Ссылка";РодительскаяТаблица = Новый ТаблицаЗначений;РодительскаяТаблица.Колонки.Добавить("Ссылка");РодительскаяТаблица.Колонки.Добавить("Уровень");РодительскаяТаблица.Колонки.Добавить("Путь");// Заполняем начальные значения - корневые элементыЗапрос.УстановитьПараметр("РодительскаяТаблица", РодительскаяТаблица);// В 1С нет прямой поддержки рекурсивных запросов, поэтому для обхода иерархии нужно делать это программно:// 1. Получить корневые элементы (где Родитель = NULL)// 2. Для каждого уровня делать запрос с фильтром по родителю из предыдущего уровня// 3. Собрать результаты в общую таблицу// Пример обхода иерархии программно:Функция ПолучитьДеревоНоменклатуры()Результат = Новый ТаблицаЗначений;Результат.Колонки.Добавить("Ссылка", Новый ОписаниеТипов("СправочникСсылка.Номенклатура"));Результат.Колонки.Добавить("Наименование", Новый ОписаниеТипов("Строка"));Результат.Колонки.Добавить("Родитель", Новый ОписаниеТипов("СправочникСсылка.Номенклатура"));Результат.Колонки.Добавить("Уровень", Новый ОписаниеТипов("Число"));Результат.Колонки.Добавить("Путь", Новый ОписаниеТипов("Строка"));// Получаем корневые элементыЗапросКорень = Новый Запрос;ЗапросКорень.Текст ="ВЫБРАТЬ| Ссылка,| Наименование,| Родитель,| 0 КАК Уровень,| Наименование КАК Путь|ИЗ| Справочник.Номенклатура|ГДЕ| Родитель = NULL";Корни = ЗапросКорень.Выполнить().Выгрузить();ПроцессироватьУровень(Корни, 0, Результат);Возврат Результат;КонецФункцииПроцедура ПроцессироватьУровень(ТекущиеЭлементы, Уровень, Результат)Для Каждого Строка Из ТекущиеЭлементы ЦиклНоваяСтрока = Результат.Добавить();НоваяСтрока.Ссылка = Строка.Ссылка;НоваяСтрока.Наименование = Строка.Наименование;НоваяСтрока.Родитель = Строка.Родитель;НоваяСтрока.Уровень = Уровень;НоваяСтрока.Путь = Строка.Путь;КонецЦикла;// Получаем дочерние элементы для текущихМассивРодителей = Новый Массив;Для Каждого Строка Из ТекущиеЭлементы ЦиклМассивРодителей.Добавить(Строка.Ссылка);КонецЦикла;Если МассивРодителей.Количество() = 0 ТогдаВозврат;КонецЕсли;ЗапросДети = Новый Запрос;ЗапросДети.Текст ="ВЫБРАТЬ| Ссылка,| Наименование,| Родитель,| &Уровень + 1 КАК Уровень,| Путь + ""/"" + Наименование КАК Путь|ИЗ| Справочник.Номенклатура|ГДЕ| Родитель В (&Родители)";ЗапросДети.УстановитьПараметр("Родители", МассивРодителей);ЗапросДети.УстановитьПараметр("Уровень", Уровень);Дети = ЗапросДети.Выполнить().Выгрузить();Если Дети.Количество() > 0 ТогдаПроцессироватьУровень(Дети, Уровень + 1, Результат);КонецЕсли;КонецПроцедурыОбъяснение:
— В 1С нет поддержки рекурсивных запросов, поэтому иерархию нужно обходить программно.
— Сначала выбираются корневые элементы (где Родитель = NULL).
— Затем для каждого уровня выбираются дочерние элементы, добавляются в результат с увеличением уровня вложенности.
— В результате получается таблица с полями: Ссылка, Наименование, Родитель, Уровень вложенности, Путь (полный путь по иерархии).Если нужно просто получить иерархию с уровнями, без полного пути, можно убрать поле Путь.
Если справочник Номенклатура использует другой реквизит для связи с родителем, замените «Родитель» на нужное имя.
Там подробно описан обход иерархий и примеры запросов.
-
-
АвторСообщения
- Для ответа в этой теме необходимо авторизоваться.