Имя: Пароль:
1C
1С v8
Самое быстрое заполнение дерева значений иерархическим списком
, ,
0 ac13
 
16.06.20
08:57
Как быстро заполнить дерево значений иерархическим справочником?
Пусть это будет мега уродский метод, главное самый быстрый.
Обход результата запроса с группировкой по иерархии очень медленный,
поэтому я использую следующий извращенный способ, но и он недостаточно скоро выполняется.

Получаю таблицу значений (сам запрос выполняется быстро):

Номенклатура КАК Уровень4
Номенклатура.Родитель КАК Уровень3
Номенклатура.Родитель.Родитель КАК Уровень2
Номенклатура.Родитель.Родитель.Родитель КАК Уровень1

Дальше делаю прямой обход по таблице и заполняю дерево:

Уровень1 = 0;
Уровень2 = 0;
Уровень3 = 0;
Уровень4 = 0;

Для каждого Стр из ТЗ Цикл
    
    Если Стр.Уровень1 <> Уровень1 Тогда
        НС1 = ДеревоЗначений.Строки.Добавить();
        НС1.Номенклатура = Стр.Уровень1;
        Если Стр.Уровень2 <> Уровень2 Тогда
            НС2 = НС1.Строки.Добавить();
            НС2.Номенклатура = Стр.Уровень2;
            Если Стр.Уровень3 <> Уровень3 Тогда
                НС3 = НС2.Строки.Добавить();
                НС3.Номенклатура = Стр.Уровень3;
                НС4 = НС3.Строки.Добавить();
                НС4.Номенклатура = Стр.Уровень1;
                Строки3 = НС3;
            КонецЕсли;
            Строки2 = НС2;
        КонецЕсли;
        Строки1 = НС1;
    Иначе
        Если Стр.Уровень2 <> Уровень2 Тогда
            НС2 = Строки1.Строки.Добавить();
            НС2.Номенклатура = Стр.Уровень2;
            Если Стр.Уровень3 <> Уровень3 Тогда
                НС3 = НС2.Строки.Добавить();
                НС3.Номенклатура = Стр.Уровень3;
                НС4 = НС3.Строки.Добавить();
                НС4.Номенклатура = Стр.Уровень1;
                Строки3 = НС3;
            КонецЕсли;
            Строки2 = НС2;
        Иначе
            Если Стр.Уровень3 <> Уровень3 Тогда
                НС3 = Строки2.Строки.Добавить();
                НС3.Номенклатура = Стр.Уровень3;
                НС4 = НС3.Строки.Добавить();
                НС4.Номенклатура = Стр.Уровень1;
                Строки3 = НС3;
            Иначе
                НС4 = Строки3.Строки.Добавить();
                НС4.Номенклатура = Стр.Уровень1;
            КонецЕсли;    
        КонецЕсли;
    КонецЕсли;
    
    Уровень1 = Стр.Уровень1;
    Уровень2 = Стр.Уровень2;
    Уровень3 = Стр.Уровень3;
    Уровень4 = Стр.Уровень4;
    
КонецЦикла;
1 ac13
 
16.06.20
08:58
Можно быстрее? Когда обрабатывается 60000 строк, время заполнения может занимать до 15 минут.
2 dka80
 
16.06.20
09:02
Заполнить дерево выгрузив (а не обходя) в него результат запроса с группировками
3 Веселый собака
 
16.06.20
09:03
выгрузить с иерархией
4 Конструктор1С
 
16.06.20
09:20
А зачем ты сразу 60 тыщ строк вываливаешь? Кто-то будет их все читать? Выведи верхний уровень и подуровень. Если пользователь начнет разворачивать ветку (обработчик события есть подходящий), выводи на уровень глубже, и так далее
5 ac13
 
16.06.20
09:29
(4) дерево выводится в развернутом виде, так пользователю сразу нужно видеть самый низкий уровень, хотя это идея, можно попробовать, пусть разворачивают нужные ветки. спасибо!
6 ac13
 
16.06.20
09:31
(4) А как вывести, например, первый и второй уровень, при этом отображать плюсик для разворачивания более низкого уровня?
7 Ненавижу 1С
 
гуру
16.06.20
09:31
+(2) запрос с итогами, выгрузка с иерархией
8 ASU_Diamond
 
16.06.20
09:32
(0) через рекурсию было бы читабельнее
(5) в раскрытом виде он сколько искать будет нужный элемент в 60 000? всё равно по иерархии пойдет, да ещё сворачивать будет ненужные ветки.
9 Serg_1960
 
16.06.20
09:50
Sorry, вопрос не в тему: хотел бы услышать задачу полностью и почему нельзя использовать иерархический справочник Номенклатура по прямому назначению?
10 МихаилМ
 
16.06.20
09:50
построитель запроса умеет тз в дерево значений  конвертировать.
11 Serg_1960
 
16.06.20
09:58
Угу. И даже "умеет" так, что Дерево = Запрос.Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией);
12 Serg_1960
 
16.06.20
10:00
PS: но 60 тысяч строк - убивает саму идею(смысл) выгрузки и показа юзверю.
13 ac13
 
16.06.20
10:15
(9) иерархический справочник загружается не полностью, а с определенными отборами.
загружаются не только элементы справочника, но еще связанные через регистр элементы другого справочника и после - обрабатывается сразу в дереве.
на самом деле это был отчет и пользователи посчитали, что им удобнее всего будет работать с такой формой и сразу обрабатывать объекты.
14 ac13
 
16.06.20
10:17
+(13) конечно можно было бы обрабатывать элементы прямо через форму отчета используя обработку расшифровки, но чтобы видеть результат - отчет придется переформировывать. перерисовывать табличный документ отчете ещё муторней. решил, что удобнее всего будет работать с деревом. одна проблема - быстро заполнить дерево.
но идея - не заполнять все уровни сразу более менее подходит, пока попробую так
15 Serg_1960
 
16.06.20
10:32
(13) Ок. Имхо, задача сводится к построению такого запроса, который позволит выгрузить дерево сразу нужного вида, без постобработки.
16 ac13
 
16.06.20
10:45
(15) данных слишком много, одним запросом реально долго. лучше буду каждую ветку заполнять при раскрытии
17 Конструктор1С
 
16.06.20
11:28
(6) смотри по родителю.

первый уровень: Родитель = &ПустаяСсылка
второй уровень: Родитель.Родитель = &ПустаяСсылка
Компьютер — устройство, разработанное для ускорения и автоматизации человеческих ошибок.