Преобразовать Таблицу Значений в Дерево #449310


#0 by jk3
Например, есть исходная Таблица Значений (именно так, надо немного абстрагироваться от 1С :)) n=9 строк k=4 колонок, по значениям в которых будет строится дерево r=2 числовых колонок, значения которых будут суммироваться На выходе должно получиться Дерево, состоящее r+2 колонок. В 1-ой колонке вложенная ТЗ, если она есть Во 2-ой колонке значение в узле дерева (одно из k колонок) В остальных r колонках числовые данные В данном случае получится такое Дерево (значения числовых колонок взяты в скобки): Нужен рекурсивный алгоритм, который построит такое дерево при заданных n, k, r.
#1 by Ненавижу 1С
Отбираешь строки по первому столбцу, по которому строится дерево, выгружаешь это в ТЗ, добавляешь в дерево узел, для этой ТЗ делаешь рекурсивно как то так
#2 by Turpentine
А на хрена рекурсия. Можно конечно и рекурсией и не сложно. Но ГОРАЗДО проще запросом к таблице с итогами и выгрузкой результата "с группировкой"
#3 by Жан Пердежон
дерево из колонок? интересно-интересно... кто вкурил - отсыпьте
#4 by Жан Пердежон
поднатужился - получилось представить только колонки из дерева
#5 by Serginio1
#6 by jk3
ну и, где там дерево, которое я описал в ?
#7 by Serginio1
Применяешь глСгруппироватьПоПолюСТЗБыстр(Тз,Поле) к каждой группировке и заменяешь ТзПоГруппе на глСгруппироватьПоПолюСТЗБыстр(ТзПоГруппе,Поле) и так пока полей хватит
#8 by Serginio1
Процедурка СгруппироватьТз(Тз,СписокПолей,Индекс,КоличествоПолей) Тз.ВыбратьСтроки; Пока Тз.ПолучитьСтроку=1 Цикл Тз.ТзПоГруппе=глСгруппироватьПоПолюСТЗБыстр(Тз.ТзПоГруппе,СписокПолей.ПолучитьЗначение(Индекс); Если Индекс<=КоличествоПолей Тогда СгруппироватьТз(Тз.ТзПоГруппе,СписокПолей,Индекс+1,КоличествоПолей) КонецЕсли; КонецЦикла; КонецПроцедурки Сперва Нужно сделать первичную группировку, где тз это плоская таблица Тз=СгруппироватьТз(Тз,СписокПолей,Индекс,КоличествоПолей)
#9 by Serginio1
Тьфу Сначала Получить Первичную Группировочную Таблицу Тз=глСгруппироватьПоПолюСТЗБыстр(,Поле); А затем ее дербанить на оствшиеся поля СгруппироватьТз(Тз,СписокПолей,1,КоличествоПолей)
#10 by Ёпрст
Индексированная ТЗ.. метод Группировать
#11 by Mitriy
это что? О_О
#12 by Ёпрст
#13 by Ёпрст
+12 Для отчета, можно еще Класс.ИтогиПоГруппировкам задействовать..
#14 by jk3
индексированная таблица -- это конечно хорошо, но нужен сам алгоритм, реализованный на 7-ке и который можно потом будет с минимальным допиливанием перенести на 8-ку оптимальность/скорость работы не играет особой роли
#15 by Барбариска
Посмотри такое. Внимательно не вчитывалась в условие, но вроде это то... )) //************************************************************ Функция ИтоговаяТЗ(ТЗНач, СпКолонокГрупп, СпКолонокСумма, НачУровень = 0, СтруктураВнутр = "") Экспорт    Перем ТЗНачКопия, ТЗИтог, ТекТЗ, ВремТЗ;    ТЗНач.Выгрузить(ТЗНачКопия);    Если НачУровень = 0 Тогда        ТЗНачКопия.Сортировать(СпКолонокГрупп);        СтруктураВнутр = ЗначениеВСтрокуВнутр(СоздатьОбъект("ТаблицаЗначений"));    КонецЕсли;    ТЗНачКопия.Выгрузить(ТЗИтог);    ТЗНачКопия.Выгрузить(ВремТЗ);    Поз = Найти(СпКолонокГрупп, ",");    Если Поз > 0 Тогда        ТекИзм = СокрЛП(Лев(СпКолонокГрупп, Поз - 1));        ОстИзм = СокрЛП(Сред(СпКолонокГрупп, Поз + 1));    Иначе        ТекИзм = СокрЛП(СпКолонокГрупп);        ОстИзм = "";    КонецЕсли;    ТЗИтог.Свернуть(ТекИзм, СпКолонокСумма);    Если ОстИзм = "" Тогда        // по строкам - заполнить таблицы значений        ТЗИтог.НоваяКолонка("ТаблицаЗначений");        ТЗИтог.ВыбратьСтроки;        Пока ТЗИтог.ПолучитьСтроку = 1 Цикл            ТЗИтог.ТаблицаЗначений = ЗначениеИзСтрокиВнутр(СтруктураВнутр);        КонецЦикла;        Возврат ТЗИтог;    КонецЕсли;    Если ТЗИтог.КоличествоСтрок = 0 Тогда        Возврат ТЗИтог;    КонецЕсли;    ТЗИтог.НоваяКолонка("ТаблицаЗначений");    ТЗИтог.НоваяКолонка("СлужебнаяНач","Число");    ТЗИтог.НоваяКолонка("СлужебнаяКон" ,"Число");    ТЗИтог.ВыбратьСтроки;    Пока ТЗИтог.ПолучитьСтроку = 1 Цикл        НомСтр = 0;        ВремТЗ.НайтиЗначение(ТЗИтог.ПолучитьЗначение(ТЗИтог.НомерСтроки, ТекИзм), НомСтр, ТекИзм);        ТЗИтог.СлужебнаяНач = НомСтр;        Если ТЗИтог.НомерСтроки <> 1 Тогда            ТЗИтог.УстановитьЗначение(ТЗИтог.НомерСтроки - 1, "СлужебнаяКон", НомСтр - 1);        КонецЕсли;    КонецЦикла;    ТЗИтог.УстановитьЗначение(ТЗИтог.КоличествоСтрок, "СлужебнаяКон", ВремТЗ.КоличествоСтрок);    ТЗИтог.ВыбратьСтроки;    Пока ТЗИтог.ПолучитьСтроку = 1 Цикл        ТЗИтог.Выгрузить(ТекТЗ, 1, 1, 1);        ВремТЗ.Выгрузить(ТекТЗ, ТЗИтог.СлужебнаяНач, ТЗИтог.СлужебнаяКон, ОстИзм + "," + СпКолонокСумма);        ТекТЗ.Свернуть(ОстИзм, СпКолонокСумма);        ТЗИтог.ТаблицаЗначений = ИтоговаяТЗ(ТекТЗ, ОстИзм, СпКолонокСумма, 1, СтруктураВнутр);    КонецЦикла;    ТЗИтог.УдалитьКолонку("СлужебнаяНач");    ТЗИтог.УдалитьКолонку("СлужебнаяКон");    Возврат ТЗИтог; КонецФункции
#16 by Злобный Йожег
Сделать запрос к исходной таблице значений, и в запросе указать раздел итоги, куда расписать всю иерархию колонок. Результат запроса выгрузить: ДеревоЗнач = РезультатЗапроса.Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкам);
#18 by jk3
да, это оно. БОЛЬШОЕ спасибо! остальное завтра посмотрю
#19 by jk3
В итоге получилось вот что и добавил функцию вычисления к полученному дереву общего итого (при желании её можно интегрировать в функцию создания дерева)
Тэги: Математика и алгоритмы
Ответить:
Комментарии доступны только авторизированным пользователям

В этой группе 1С