Три способа получить дерево элементов иерархического справочника

11.11.15

Разработка - Математика и алгоритмы

Рассматривается применимость и недостатки следующих способов получения дерева
1) Запрос с использованием итогов по иерархии
2) Формирование дерева обходом выборки с упорядочиванием по иерархии
3) Формирование иерархии по списку элементов транзитивным замыканием

1) Идея проста - выбираем запросом элементы, не являющиеся папками, а всю иерархию нам построит запрос. Тут сразу начинаются неожиданности. Какую конструкцию использовать: ИЕРАРХИЯ или ТОЛЬКО ИЕРАРХИЯ? Вроде логично было бы ТОЛЬКО ИЕРАРХИЯ, т.к.  итоги на уровне элементов нам не нужны (будут дубли). Заглядываем в справку: "ИЕРАРХИЯ. В результате будут рассчитаны итоги по контрольным точкам и итоги по иерархии для контрольных точек ... При необходимости можно рассчитать итоги только значений по иерархии, без расчета итогов в контрольных точках. Для этого перед ключевым словом ИЕРАРХИЯ нужно указать ключевое слово ТОЛЬКО."

Для однозначного понимания моих объяснений введу несколько "терминов", которыми буду пользоваться. Все листья дерева буду называть элементами. Узлы дерева, которые содержат только элементы - нижние папки, Остальные узлы, которые содержат хотя бы одну нижнюю папку - верхние папки.

Для ИЕРАРХИЯ - все логично: разбираем дерево итогов по иерархии для папок. У всех папок тип  - ТипЗаписиЗапроса.ИтогПоИерархии. У элементов тип - ТипЗаписиЗапроса.ИтогПоГруппировке. Внутри группировки одна запись того же элемента но уже с типом  ТипЗаписиЗапроса.ДетальнаяЗапись. Все как заявлено. Но если выгрузить в дерево, дубль пропадает!

Запрос = Новый Запрос;
Запрос.Текст = 
"ВЫБРАТЬ
|	Номенклатура.Ссылка КАК Ссылка
|ИЗ
|	Справочник.Номенклатура КАК Номенклатура
|ГДЕ
|	НЕ Номенклатура.ЭтоГруппа
// Тут могут быть условия
| |УПОРЯДОЧИТЬ ПО | Номенклатура.ЭтоГруппа, | Ссылка |ИТОГИ ПО | Ссылка ИЕРАРХИЯ |АВТОУПОРЯДОЧИВАНИЕ"; Дерево=Запрос.Выполнить().Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией);

Либо сформировать вручную

ВыборкаСИерархией=Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией,"Ссылка");
Дерево=Новый ДеревоЗначений;
Дерево.Колонки.Добавить("Номенклатура");
ВыбратьЭлементыВИерархии(ВыборкаСИерархией,Дерево);
КонецПроцедуры

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

Для ТОЛЬКО ИЕРАРХИЯ все немного не так, как ожидалось. Верхние папки - ТипЗаписиЗапроса.ИтогПоИерархии, нижние - ТипЗаписиЗапроса.ИтогПоГруппировке. Внутри элементы с типом - ТипЗаписиЗапроса.ДетальнаяЗапись. НО, если верхняя папка содержит элементы, все они будут помещены в еще в одну вложенную группу с типом  ТипЗаписиЗапроса.ИтогПоГруппировке.  Поэтому выгрузить() приводит к дублированию! Цель такого дублирования думаю в том, чтобы все элементы обязательно содержались в папке с ТипЗаписиЗапроса.ИтогПоГруппировке, чтобы мы могли обходить выборку ОбходРезультатаЗапроса.ПоГруппировкам. Поэтому, если использовать ТОЛЬКО ИЕРАРХИЯ, лучше обойти выборку и сформировать ручками дерево, устраняя дублирование.  При обходе нужно обязательно указывать второй параметр "Группировки". Привожу обход для  ТОЛЬКО ИЕРАРХИЯ

Запрос = Новый Запрос;
Запрос.Текст = 
"ВЫБРАТЬ
|	Номенклатура.Ссылка КАК Ссылка
|ИЗ
|	Справочник.Номенклатура КАК Номенклатура
|ГДЕ
|	НЕ Номенклатура.ЭтоГруппа
// Тут могут быть условия
| |УПОРЯДОЧИТЬ ПО | Номенклатура.ЭтоГруппа, | Ссылка |ИТОГИ ПО | Ссылка ТОЛЬКО ИЕРАРХИЯ |АВТОУПОРЯДОЧИВАНИЕ"; Результат=Запрос.Выполнить(); ВыборкаСИерархией=Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией,"Ссылка"); Дерево=Новый ДеревоЗначений; Дерево.Колонки.Добавить("Номенклатура"); ВыбратьЭлементыВИерархии(ВыборкаСИерархией,Дерево); Процедура ВыбратьЭлементыВИерархии(ВыборкаСИерархией,Дерево) Пока ВыборкаСИерархией.Следующий() Цикл Если ВыборкаСИерархией.ТипЗаписи()=ТипЗаписиЗапроса.ИтогПоИерархии Тогда Строка=Дерево.Строки.Добавить(); Строка.Номенклатура=ВыборкаСИерархией.Ссылка; ВыбратьЭлементыВИерархии (ВыборкаСИерархией.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией,"Ссылка"),Строка); ИначеЕсли ВыборкаСИерархией.ТипЗаписи()=ТипЗаписиЗапроса.ИтогПоГруппировке Тогда Если Не ЗначениеЗаполнено(ВыборкаСИерархией.Ссылка) ИЛИ ТипЗнч(Дерево)=Тип("СтрокаДереваЗначений") И ВыборкаСИерархией.Ссылка=Дерево.Номенклатура Тогда ВыбратьЭлементыБезИерархии(ВыборкаСИерархией.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам),Дерево); Иначе Строка=Дерево.Строки.Добавить(); Строка.Номенклатура=ВыборкаСИерархией.Ссылка; ВыбратьЭлементыБезИерархии(ВыборкаСИерархией.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам),Строка); КонецЕсли; КонецЕсли; КонецЦикла; КонецПроцедуры Процедура ВыбратьЭлементыБезИерархии (ВыборкаБезИерархии,Дерево) Пока ВыборкаБезИерархии.Следующий() Цикл Строка=Дерево.Строки.Добавить(); Строка.Номенклатура=ВыборкаБезИерархии.Ссылка; КонецЦикла; КонецПроцедуры

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

2) Для решения этой проблемы необходимо выбрать папки в запросе. Такой запрос не получиться выгрузить в дерево, но, если мы будем использовать в запросе УПОРЯДОЧИТЬ ПО ... ИЕРАРХИЯ, а также выберем в запросе родителя, то обход дерева станет простым, мы будем обходить выборку в цикле и прицеплять следующий элемент к текущему или одному из его родителей. К кому цеплять покажет выбранное поле родитель.

Запрос = Новый Запрос;
Запрос.Текст ="
|ВЫБРАТЬ
|	Номенклатура.Ссылка КАК Ссылка,
|	Номенклатура.Родитель КАК Родитель
|ИЗ
|	Справочник.Номенклатура КАК Номенклатура
// Тут могут быть условия
| |УПОРЯДОЧИТЬ ПО | Номенклатура.Ссылка ИЕРАРХИЯ |АВТОУПОРЯДОЧИВАНИЕ"; Результат = Запрос.Выполнить(); ДеревоПапок=Новый ДеревоЗначений; ДеревоПапок.Колонки.Добавить("Номенклатура"); Выборка = Результат.Выбрать(); Пока Выборка.Следующий() Цикл Если Не ЗначениеЗаполнено(Выборка.Родитель) Тогда ТекЭлемент=ДеревоПапок.Строки.Добавить(); ТекЭлемент.Номенклатура=Выборка.Ссылка; Иначе Пока ТекЭлемент.Номенклатура<>Выборка.Родитель Цикл ТекЭлемент=ТекЭлемент.Родитель; КонецЦикла; ТекЭлемент=ТекЭлемент.Строки.Добавить(); ТекЭлемент.Номенклатура=Выборка.Ссылка; КонецЕсли; КонецЦикла;

Этот метод хорош, но его невозможно применить, если мы не можем получить сразу всю иерархию. Если у нас есть только набор элементов, нам необходимо предварительно построить всю иерархию.
3) Итак, у нас есть набор элементов (набор условий отбора на элементы), но мы не знаем их родителей, нам нужно их вычислить, а затем сформировать дерево. Тут нам не обойтись без Сергея (ildarovich) (отдельное спасибо ему за качественный контент) и его публикации //infostart.ru/public/158512/

Рассмотрим задачу получения только иерархии по набору элементов. Для решения задачи выберем для элементов все папки, в которых они содержатся, затем замыканием вычислим всех родителей этих папок, ну и далее выборка с обходом по 2 методу.

Запрос = Новый Запрос;
Запрос.Текст =ТранзитивноеЗамыкание(256);

Результат = Запрос.Выполнить();

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

Функция ТранзитивноеЗамыкание(МаксимальнаяДлинаПути)
	//Эмуляция отбора элементов. Выборка Папок, в которых они содержаться, затем замыкаем
    Пролог = "ВЫБРАТЬ	Ссылка ПОМЕСТИТЬ ВТ_Элементы ИЗ	Справочник.Номенклатура КАК Номенклатура ГДЕ НЕ ЭтоГруппа;
	|ВЫБРАТЬ РАЗЛИЧНЫЕ	Ссылка.Родитель КАК Ссылка,	Ссылка.Родитель.Родитель КАК Родитель ПОМЕСТИТЬ ВТ_Папки ИЗ	ВТ_Элементы КАК ВТ_Элементы;
	|ВЫБРАТЬ Родитель НачалоДуги, Ссылка КонецДуги ПОМЕСТИТЬ ЗамыканияДлины1 ИЗ ВТ_Папки
    | ГДЕ Родитель <> Значение(Справочник.Номенклатура.ПустаяСсылка)
    | ОБЪЕДИНИТЬ ВЫБРАТЬ Ссылка, Ссылка ИЗ ВТ_Папки;";
    Рефрен = "ВЫБРАТЬ РАЗЛИЧНЫЕ ПерваяДуга.НачалоДуги, ВтораяДуга.КонецДуги ПОМЕСТИТЬ ЗамыканияДлины#2 ИЗ ЗамыканияДлины#1 КАК ПерваяДуга
    | ВНУТРЕННЕЕ СОЕДИНЕНИЕ ЗамыканияДлины#1 КАК ВтораяДуга ПО ПерваяДуга.КонецДуги = ВтораяДуга.НачалоДуги;
    | УНИЧТОЖИТЬ ЗамыканияДлины#1;";
    Эпилог = "ВЫБРАТЬ РАЗЛИЧНЫЕ НачалоДуги КАК Ссылка ПОМЕСТИТЬ ВТ_ВсеПапки ИЗ ЗамыканияДлины#2 ГДЕ НачалоДуги<>Значение(Справочник.Номенклатура.ПустаяСсылка);
	|ВЫБРАТЬ Ссылка, Ссылка.Родитель КАК Родитель ИЗ ВТ_ВсеПапки УПОРЯДОЧИТЬ ПО Ссылка ИЕРАРХИЯ АВТОУПОРЯДОЧИВАНИЕ";
    ТекстЗапроса = Пролог;
    МаксимальнаяДлинаЗамыканий = 1;
    Пока МаксимальнаяДлинаЗамыканий < МаксимальнаяДлинаПути Цикл
        ТекстЗапроса = ТекстЗапроса + СтрЗаменить(СтрЗаменить(Рефрен, "#1", Формат(МаксимальнаяДлинаЗамыканий, "ЧГ=0")), "#2", Формат(2 * МаксимальнаяДлинаЗамыканий, "ЧГ=0"));
        МаксимальнаяДлинаЗамыканий = 2 * МаксимальнаяДлинаЗамыканий
    КонецЦикла;
    ТекстЗапроса = ТекстЗапроса + СтрЗаменить(Эпилог, "#2", Формат(МаксимальнаяДлинаЗамыканий, "ЧГ=0"));
    Возврат ТекстЗапроса;
КонецФункции



Дерево Иерахия Справочник

См. также

Метод Дугласа-Пойкера для эффективного хранения метрик

Математика и алгоритмы Платформа 1C v8.2 Конфигурации 1cv8 Россия Абонемент ($m)

На написание данной работы меня вдохновила работа @glassman «Переход на ClickHouse для анализа метрик». Автор анализирует большой объем данных, много миллионов строк, и убедительно доказывает, что ClickHouse справляется лучше PostgreSQL. Я же покажу как можно сократить объем данных в 49.9 раз при этом: 1. Сохранить значения локальных экстремумов 2. Отклонения от реальных значений имеют наперед заданную допустимую погрешность.

1 стартмани

30.01.2024    1886    stopa85    12    

34

Алгоритм симплекс-метода для решения задачи раскроя

Математика и алгоритмы Бесплатно (free)

Разработка алгоритма, построенного на модели симплекс-метода, для нахождения оптимального раскроя.

19.10.2023    4687    user1959478    50    

34

Регулярные выражения на 1С

Математика и алгоритмы Инструментарий разработчика Платформа 1С v8.3 Мобильная платформа Россия Абонемент ($m)

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

1 стартмани

09.06.2023    7687    4    SpaceOfMyHead    17    

56

Мини-обзор разных решений задач

Математика и алгоритмы Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Три задачи - три идеи - три решения. Мало кода, много смысла. Мини-статья.

03.04.2023    3115    RustIG    6    

25

Модель распределения суммы по базе

Математика и алгоритмы Платформа 1С v8.3 Россия Абонемент ($m)

Обычно под распределением понимают определение сумм пропорционально коэффициентам. Предлагаю включить сюда также распределение по порядку (FIFO, LIFO) и повысить уровень размерности до 2-х. 1-ое означает, что распределение может быть не только пропорциональным, но и по порядку, а 2-ое - это вариант реализации матричного распределения: по строкам и столбцам. Возможно вас заинтересует также необычное решение этой задачи через создание DSL на базе реализации текучего интерфейса

1 стартмани

21.03.2022    7952    7    kalyaka    11    

44

Изменения формата файлов конфигурации (CF) в 8.3.16

Математика и алгоритмы Платформа 1С v8.3 Бесплатно (free)

Дополнение по формату файлов конфигурации (*.cf) в версии 8.3.16.

16.12.2021    4565    fishca    13    

36

Интересная задача на Yandex cup 2021

Математика и алгоритмы Бесплатно (free)

Мое решение задачи на Yandex cup 2021 (frontend). Лабиринт. JavaScript.

12.10.2021    8957    John_d    73    

46
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. echo77 1881 13.11.15 08:44 Сейчас в теме
Есть еще один способ, который, ИМХО, является более громоздким, но работает быстрее, т.к. СКД выгружает в дерево значений быстрее.
Это тот же запрос в СКД и настройка иерархической группировки
dekrain; +1
2. 32ops 191 13.11.15 09:25 Сейчас в теме
(1) На первый взгляд, весьма спорно, ведь СКД все равно должно построить иерархию, значит идет речь про запрос из способа 1, а он медленный, плюс накладные затраты времени в СКД. Поподробней бы - откуда берется преимущество в скорости. И как из СКД дерево потом получать?
+
3. echo77 1881 16.11.15 13:46 Сейчас в теме
(2) Да, с помощью СКД дольше.

// Заполняет переданный объект на основани СКД
//
// Параметры
//
//  СКД – собствеено настройки СКД
//
//  ОбъектДляЗагрузки – объект в который выгружаются данные, таблица значений, дерево значений, табличный документ
//
//  ИсполняемыеНастройки – Пользовательские настройки СКД если не указаны будут использованы настроки СКД по умолчанию
//
//  СтруктураПараметров - Структура – Передаваемые для СКД параметры
//
//  краткий лекбез, поправлю позже
//
Процедура ПолучитьДанныеНаОснованииСКД(СКД, ИсполняемыеНастройки = Неопределено, ОбъектДляЗагрузки, СтруктураПараметров = Неопределено, РасшифровкаСКД = Неопределено, МакетКомпоновки = Неопределено, ВнешниеНаборыДанных = Неопределено) Экспорт

    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;

    Если ТипЗнч(ОбъектДляЗагрузки) = Тип("ПолеТабличногоДокумента") ИЛИ ТипЗнч(ОбъектДляЗагрузки) = Тип("ТабличныйДокумент") Тогда
        ТипГенератора = Тип("ГенераторМакетаКомпоновкиДанных");
    Иначе
        ТипГенератора = Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений");
    КонецЕсли;

    Если ИсполняемыеНастройки = Неопределено Тогда

        ИсполняемыеНастройки = СКД.НастройкиПоУмолчанию;

    КонецЕсли;

    Если СтруктураПараметров <> Неопределено Тогда

        КоллекцияЗначенийПараметров = ИсполняемыеНастройки.ПараметрыДанных.Элементы;

        Для каждого Параметр Из СтруктураПараметров Цикл

            НайденноеЗначениеПараметра = КоллекцияЗначенийПараметров.Найти(Параметр.Ключ);

            Если НайденноеЗначениеПараметра <> Неопределено Тогда

                НайденноеЗначениеПараметра.Использование = Истина;

                НайденноеЗначениеПараметра.Значение = Параметр.Значение;

            КонецЕсли;

        КонецЦикла;

    КонецЕсли;

    МакетКомпоновкиСКД = КомпоновщикМакета.Выполнить(СКД, ИсполняемыеНастройки, РасшифровкаСКД, МакетКомпоновки, ТипГенератора);

    ПроцессорКомпановки = Новый ПроцессорКомпоновкиДанных;

    ПроцессорКомпановки.Инициализировать(МакетКомпоновкиСКД, ВнешниеНаборыДанных, РасшифровкаСКД);

    Если ТипЗнч(ОбъектДляЗагрузки) = Тип("ПолеТабличногоДокумента") ИЛИ ТипЗнч(ОбъектДляЗагрузки) = Тип("ТабличныйДокумент") Тогда

        ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;

        ПроцессорВывода.УстановитьДокумент(ОбъектДляЗагрузки);

    Иначе

        ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;

        ПроцессорВывода.УстановитьОбъект(ОбъектДляЗагрузки);

    КонецЕсли;

    ПроцессорВывода.ОтображатьПроцентВывода = Истина;

    ПроцессорВывода.Вывести(ПроцессорКомпановки, Истина);

КонецПроцедуры // ПолучитьДанныеНаОснованииСКД()

// Пример использования
//ДеревоЗначений = Новый ТаблицаЗначений;
//СхемаКомпоновкиДанных = ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
////СтруктураПараметров = Новый Структура("ДатаОтчета", НашаДата);
//ПолучитьДанныеНаОснованииСКД(СхемаКомпоновкиДанных, СхемаКомпоновкиДанных.НастройкиПоУмолчанию, ДеревоЗначений, Неопределено);
//
//ДеревоЗначений.ВыбратьСтроку();
Показать
32ops; +1
4. 32ops 191 16.11.15 13:53 Сейчас в теме
(3) Мысль понял. Я чет даже в эту сторону и не смотрел. (ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений). Спасибо, буду в курсе))
+
5. Max.Potapov 17.02.17 17:48 Сейчас в теме
Есть более интересное и простое решение на СКД - http://start1c.blogspot.ru/2017/01/blog-post.html
vl_vedernikov; mickey.1cx; +2
6. Дейл 8 16.12.17 02:29 Сейчас в теме
Просто, ради интереса. А как построить дерево , если есть к примеру только два поля "Артикул" и "АртикулРодитель". Оба "Строка". Иерархии не доступны.
additive; +1
7. Дейл 8 16.12.17 02:30 Сейчас в теме
Что-то близкое к 3 варианту, но...
+
8. Mart 106 28.02.18 02:35 Сейчас в теме
Супер! Признаться, я и не знал, что упорядочивать можно не только по возрастанию/убыванию, но еще и по иерархии. Спасибо, для меня это как раз то, что нужно.
+
9. echo77 1881 11.11.18 10:12 Сейчас в теме
(0)
Запрос = Новый Запрос;
Запрос.Текст = 
"ВЫБРАТЬ
|    Номенклатура.Ссылка КАК Ссылка
|ИЗ
|    Справочник.Номенклатура КАК Номенклатура
|ГДЕ
|    НЕ Номенклатура.ЭтоГруппа
// Тут могут быть условия
|
|УПОРЯДОЧИТЬ ПО
|    Номенклатура.ЭтоГруппа,
|    Ссылка
|ИТОГИ ПО
|    Ссылка ИЕРАРХИЯ
|АВТОУПОРЯДОЧИВАНИЕ";
Дерево=Запрос.Выполнить().Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией);
Показать


При выгрузке в дерево так же двоит элементы
Ryo3000; +1
12. waol 313 05.08.21 22:21 Сейчас в теме
(9) да, в 18 г уже двоит. В 21 в принципе, все еще тоже
Ryo3000; +1
10. m_nazar 25.06.20 10:54 Сейчас в теме
В первом способе есть ошибка. Должно быть:

//Тут на самом деле есть еще один уровень, но нам он может потребоваться,
//только если нужно взять данные на уровне записи
//Если это нужно, здесь обходим один элемент, забираем из него данные
Выборка=ВыборкаСИерархией.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока Выборка.Следующий() Цикл
Строка = Дерево.Строки.Добавить();
Строка.Номенклатура = Выборка.Номенклатура;
КонецЦикла
+
11. SizovE 263 02.09.20 20:40 Сейчас в теме
Я бы предложил во втором способе уйти от цикла
		
		СоответствиеСтрок = Новый Соответствие();
		
		Выборка = РезультатЗапроса.Выбрать();
		Пока Выборка.Следующий() Цикл
			
			Если НЕ ЗначениеЗаполнено(Выборка.Родитель) Тогда
				НоваяСтрока = Данные.Строки.Добавить();								
			Иначе				
				СтрокаРодитель = СоответствиеСтрок.Получить(Выборка.Родитель);				
				НоваяСтрока = СтрокаРодитель.Строки.Добавить();
			КонецЕсли;
						
			ЗаполнитьЗначенияСвойств(НоваяСтрока, Выборка);
			
			НоваяСтрока.РодительЭлемент = Выборка.Родитель;
			
			СоответствиеСтрок.Вставить(Выборка.Ссылка, НоваяСтрока);			
			
		КонецЦикла;		
Показать
+
13. AJIekceuT 18.05.22 07:46 Сейчас в теме
Запрос.Текст = "ВЫБРАТЬ
	               |	ТипыРекламы.Ссылка КАК Ссылка,
	               |	ТипыРекламы.ЭтоГруппа КАК ЭтоГруппа,
	               |	ТипыРекламы.Наименование КАК Наименование
	               |ИЗ
	               |	Справочник.ТипыРекламы КАК ТипыРекламы
	               |
	               |УПОРЯДОЧИТЬ ПО
	               |	Ссылка ИЕРАРХИЯ"; 
	ВыгрузкаДЗ = Запрос.Выполнить().Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией);  
	ВыгрузкаДЗ.Строки.Сортировать("ЭтоГруппа УБЫВ,Наименование",Истина); //чтобы папки были сверху
	ЗначениеВРеквизитФормы(ВыгрузкаДЗ,"ДЗ")
Показать
Прикрепленные файлы:
YurasMIA; vers139; Lolmes; user1800274; vladnet; CaSH_2004; +6
14. Lolmes 28.07.23 16:39 Сейчас в теме
(13) Для моей задачи оказался самым удобным и простым вариантом
+
15. MaCCapAkIII 14.09.23 16:15 Сейчас в теме
А как быть со справочником с иерархией элементов, ЭтоГруппа отсутствует?
И решение проблемы, когда родитель одновременно является и полем и дублируется в результате вывода пока не нашел.
+
Оставьте свое сообщение