Искал на просторах интернета, но полного решения, которое меня устраивало, не нашел.
Надеюсь, решение сохранит кому-то время.
Берём любую таблицу значений (ТЗ) или преобразовываем табличное поле в ТЗ.
На форме добавляем реквизит "ЕстьДерево" с типом Булево.
Передаём в (естественно, поля для упорядочивания и итогов должны быть в передаваемой ТЗ)
ДеревоОбъект=Обработки.СозданиеЗаказаПоставщику.ТаблицуЗначенийВДеревоЗначений(Объект.ТоварныеПозиции.Выгрузить());
Функция ТаблицуЗначенийВДеревоЗначений(ТаблицаЗначений) Экспорт
Запрос=Новый Запрос;
Запрос.МенеджерВременныхТаблиц=Новый МенеджерВременныхТаблиц;
Текст="ВЫБРАТЬ
| *
|ПОМЕСТИТЬ НаЭкран
|ИЗ
| &ВремТЗ КАК ТаблицаЗначений
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| НаЭкран.*
|ИЗ
| НаЭкран КАК НаЭкран
|УПОРЯДОЧИТЬ ПО
| ПоставщикНаименование,
| Рекомендовано УБЫВ, КЗаказу УБЫВ
|ИТОГИ ПО
| Поставщик,КЗаказу";
Запрос.УстановитьПараметр("ВремТЗ",ТаблицаЗначений);
Запрос.Текст=Текст;
Результат = Запрос.Выполнить();
Дерево=Результат.Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкам);
Возврат Дерево;
КонецФункции //ТаблицуЗначенийВДеревоЗначений(ТаблицаЗначений)
Полученное дерево отрисовываем на форме, попутно избавляясь от значения Null, которое ВСЕГДА добавляет запрос.
Если ТипЗнч(ДеревоОбъект)=Тип("ДеревоЗначений") И ДеревоОбъект.Строки.Количество()>0 Тогда
Если 1=2 Тогда
ДеревоОбъект=Новый ДеревоЗначений;
КонецЕсли;
ЕстьДерево=Истина;
Элементы.ГруппаСвернуто.Видимость=Истина;
Элементы.ТоварныеПозиции.Видимость=Ложь;
МассивУдаляемыхРеквизитов = Новый Массив;
РеквизитыФормы = ЭтаФорма.ПолучитьРеквизиты();
ЕстьУдаляемые=Ложь;
Для Каждого РеквизитФормы Из РеквизитыФормы Цикл
ИмяРеквизита = РеквизитФормы.Имя;
Если ИмяРеквизита="ЕстьДерево" Тогда
Продолжить;
КонецЕсли;
Если СтрНайти(ИмяРеквизита, "Дерево")>0 Тогда
МассивУдаляемыхРеквизитов.Добавить(ИмяРеквизита);
ЕстьУдаляемые=Истина;
КонецЕсли;
КонецЦикла;
ИзменитьРеквизиты(,МассивУдаляемыхРеквизитов);
Если ЕстьУдаляемые=Истина Тогда
ПодчЭлем=Элементы.ГруппаСвернуто.ПодчиненныеЭлементы;
Для каждого Элем Из ПодчЭлем Цикл
Попытка
Элементы.Удалить(Элем);
Исключение
КонецПопытки;
КонецЦикла;
КонецЕсли;
МассивДобавляемыхРеквизитов = Новый Массив;
МассивДобавляемыхРеквизитов.Добавить(Новый РеквизитФормы("Дерево", Новый ОписаниеТипов("ДеревоЗначений")));
Для Каждого Колонка Из ДеревоОбъект.Колонки Цикл
КолонкаИмя=Колонка.Имя;
МассивДобавляемыхРеквизитов.Добавить(Новый РеквизитФормы(КолонкаИмя, Новый ОписаниеТипов(Колонка.ТипЗначения,,"NULL"), "Дерево"));
КонецЦикла;
ИзменитьРеквизиты(МассивДобавляемыхРеквизитов);
ЗначениеВРеквизитФормы(ДеревоОбъект, "Дерево");
ЭлементДерево = Элементы.Добавить("Дерево", Тип("ТаблицаФормы"),Элементы.ГруппаСвернуто);
ЭлементДерево.ПутьКДанным = "Дерево";
ЭлементДерево.Отображение = ОтображениеТаблицы.Дерево;
ЭлементДерево.ИзменятьСоставСтрок=Ложь;
ЭлементДерево.ИзменятьПорядокСтрок=Ложь;
Для Каждого Колонка Из ДеревоОбъект.Колонки Цикл
КолонкаИмя=Колонка.Имя;
НовыйЭлемент = Элементы.Добавить("_"+КолонкаИмя, Тип("ПолеФормы"), ЭлементДерево);
НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода;
Если КолонкаИмя="Поставщик" ИЛИ КолонкаИмя="Номенклатура" Тогда
НовыйЭлемент.Ширина=25;
ИначеЕсли КолонкаИмя="ДоОстатка" Тогда
НовыйЭлемент.Заголовок="ДО";
НовыйЭлемент.Подсказка="До остатка";
НовыйЭлемент.Вид=ВидПоляФормы.ПолеФлажка;
НовыйЭлемент.ВидФлажка=ВидФлажка.Флажок;
НовыйЭлемент.ШиринаЭлемента=3;
ИначеЕсли КолонкаИмя="Рекомендовано" Тогда
НовыйЭлемент.Шрифт=Новый Шрифт(,,Истина);
ИначеЕсли КолонкаИмя="ИсходныйНомерСтроки" Тогда
НовыйЭлемент.Видимость=Ложь;
Иначе
НовыйЭлемент.Ширина=7;
КонецЕсли;
НовыйЭлемент.ПутьКДанным = "Дерево." + КолонкаИмя;
КонецЦикла;
КонецЕсли;
В клиентской процедуре добавляем рекурсивную процедуру для обработки (свертки, развертки строк дерева)
Если ЕстьДерево=Истина Тогда
ОбойтиДеревоРекурсивноСтрокиДереваНаКлиенте(ЭтаФорма["Дерево"]);
КонецЕсли;
&НаКлиенте
Процедура ОбойтиДеревоРекурсивноСтрокиДереваНаКлиенте(ДеревоЗначений)
СтрокиДерева=ДеревоЗначений.ПолучитьЭлементы();
Для каждого СтрокаД Из СтрокиДерева Цикл
ИдСтроки=СтрокаД.ПолучитьИдентификатор();
Элем=СтрокаД.ПолучитьЭлементы();
Если Элем.Количество()>0 Тогда
Стр=Элем.Получить(0);
Парам=Новый Структура("Поставщик");
Парам.Вставить("КЗаказу");
ЗаполнитьЗначенияСвойств(Парам,Стр);
ИдСтроки1=Стр.ПолучитьИдентификатор();
Если Парам.КЗаказу=Истина Тогда
Если Элементы.Дерево.Развернут(ИдСтроки)=Ложь Тогда
Элементы.Дерево.Развернуть(ИдСтроки);
КонецЕсли;
Если Элементы.Дерево.Развернут(ИдСтроки1)=Ложь Тогда
Элементы.Дерево.Развернуть(ИдСтроки1);
КонецЕсли;
КонецЕсли;
А=1;
КонецЕсли;
КонецЦикла;
КонецПроцедуры // ОбойтиДеревоРекурсивноСтрокиДереваНаКлиенте()
Я рекурсию тут не использую, но возможность её есть. Нужно чуток поправить код под себя.
Вступайте в нашу телеграмм-группу Инфостарт