Вход | Регистрация
 
1С:Предприятие :: 1С:Предприятие 8 общая

Самое быстрое заполнение дерева значений иерархическим списком

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

первый уровень: Родитель = &ПустаяСсылка
второй уровень: Родитель.Родитель = &ПустаяСсылка

Список тем форума
Рекламное место пустует  Рекламное место пустует
Оптимист верит, что мы живем в лучшем из миров. Пессимист боится, что так оно и есть.
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.