Имя: Пароль:
1C
1С v8
Из ТаблицыЗначений в ДеревоЗначений
, , ,
0 roman383
 
15.03.13
10:46
Вот возникла задачка: преобразовать таблицу значений из двух колонок (одного строкового типа) без всяких агрегированных полей в дерево значений

Значение  Родитель            (1 -)
   1                            (2 1)
   2         1                  (3 1)
   3         1     --->             (4 3)
   4         3                          (5 4)
   5         4
1 chelentano
 
15.03.13
10:46
(0) это здорово, когда возникают задачи
2 butterbean
 
15.03.13
10:47
запрос + выгрузка его в дерево
3 Лефмихалыч
 
15.03.13
10:47
(0) ты жалуешься или хвастаешься?
4 roman383
 
15.03.13
10:48
помогите пожалуйста, я уже голову сломал
5 Лефмихалыч
 
15.03.13
10:49
(4) пока вопрос не задашь, ни кто не поможет
6 Maxus43
 
15.03.13
10:50
(4) ответ в (2)
7 chelentano
 
15.03.13
10:53
(4) голову сломал над чем?
8 roman383
 
15.03.13
11:00
Что-то не получается:

Запрос = Новый Запрос;
   Запрос.Текст =
   "ВЫБРАТЬ
   |    Таблица.Значение,
   |    Таблица.Родитель
   |ПОМЕСТИТЬ Таблица
   |ИЗ
   |    &Таблица КАК Таблица
   |;
   |
   |////////////////////////////////////////////////////////////////////////////////
   |ВЫБРАТЬ
   |    Таблица.Значение,
   |    Таблица.Родитель КАК Родитель
   |ИЗ
   |    Таблица КАК Таблица
   |ИТОГИ ПО
   |    Родитель";
   Запрос.УстановитьПараметр("Таблица", РеквизитФормыВЗначение("Таблица", Тип("ТаблицаЗначений")));
   
   ЗначениеВРеквизитФормы(Запрос.Выполнить().Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией), "Дерево");
9 roman383
 
15.03.13
11:01
Дерево получается с двумя уровнями иерархии
10 Maxus43
 
15.03.13
11:02
тут получается не запросом лучше, а обходить в цикле и формировать дерево
11 roman383
 
15.03.13
11:04
(7) (10) вот с обходом в цикле я и сломал голову. Там кажется нужна рекурсия.
12 kabanoff
 
15.03.13
11:08
Странная у тебя какая-то иерархия в (0) - я нихрена не понял.
13 roman383
 
15.03.13
11:12
(12) Представь, что значение - это ссылка иерархического справочника, а родитель - это его стандартный реквизит. Иерархия по элементам.
14 roman383
 
15.03.13
11:16
Есть один способ: создать вспомогательный иерархический справочник. Программно записывать туда данные и запрос делать по нему. Но это не оптимальный способ.
15 kabanoff
 
15.03.13
11:32
(13) "Ссылка иерархического справочника" как-то не вяжется с постановкой задачи в (0): "одного строкового типа". И ты специально так поля назвал, чтобы сбить всех с толку?

В (2) тебе была дана подсказка, а в (8) даже разжевано решение. Ну не нужна тебе иерархия по родителю, сделай по значению (ИТОГИ ПО Значение). Что тебе еще нужно?

(14) Ну это вообще пи$дец.
16 Лефмихалыч
 
15.03.13
11:35
(14) жги жарче! нужен больше адова угара и сотонинского трэша
17 kabanoff
 
15.03.13
11:48
(16) Пятнично :)
18 roman383
 
15.03.13
12:39
(15) У меня нет ни каких справочников, только таблица со строками.

Вот так все равно не получается:

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

вот что получилось: http://www.imageup.ru/img225/1249579/snimok.jpg.html
19 roman383
 
15.03.13
12:48
А вот так получается,если ИТОГИ ПО Родителю: http://www.imageup.ru/img225/1249588/snimok.jpg.html

И вообще данную задачу одним запросом не решить.
(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией преминяется к иерархическим справочникам, а их в данной задаче НЕТ)
20 butterbean
 
15.03.13
12:49
(19) делай ОбходРезультатаЗапроса.ПоГруппировкам
21 roman383
 
15.03.13
12:52
(20) Сделал, результат ни как не отличается от (18) и (19)
22 roman383
 
15.03.13
13:35
К сожалению правильное решение данной задачи ни кто предложить не может. Единственное решение только в (14).

Может кто-нибудь встречал похожую задачку?
23 mikecool
 
15.03.13
13:37
упорядочить по родителю и в один проход нарисовать дерево
24 roman383
 
15.03.13
13:42
(23) В один проход ни как не сделать, т.к. свойство "Родитель" у ДереваЗначения доступно только для чтения. Нужно как-то "поциклено-рекурсивно" заходить в каждый уровень иерархии.
25 mikecool
 
15.03.13
13:44
(24) ой, ну раз ты говоришь, то никак...
26 roman383
 
15.03.13
13:51
(25) Это мое лишь мнение. Если можно, то пжл примерно в общих словах расскажи как?
27 cw014
 
15.03.13
14:01
Функция ТаблицаВДерево(ТЗ)
   
   Результат = Новый ДеревоЗначений;
   Результат.Колонки.Добавить("Значение");
   Результат.Колонки.Добавить("Родитель");
   
   Для Каждого СтрокаТаблицы Из ТЗ Цикл
       
       Если СтрокаТаблицы.Родитель = 0 тогда
           СтрокаДерева = Результат.Строки.Добавить();
       Иначе
           СтрокаРодитель = Результат.Строки.Найти(СтрокаТаблицы.Родитель, "Родитель");
           СтрокаДерева = СтрокаРодитель.Строки.Добавить();
       КонецЕсли;
       
       ЗаполнитьЗначенияСвойств(СтрокаДерева, СтрокаТаблицы);
       
   КонецЦикла;
   
КонецФункции
28 roman383
 
15.03.13
14:24
(27) Спасибо, работает. (только поиск строки дерева не по родителю, а по значению).
29 cw014
 
15.03.13
14:28
(28) Нафига по значению? У тебя в точности наоборот будет. Или у тебя наоборот наверное колонки называются?
30 roman383
 
15.03.13
14:33
(29) У дерева значений есть только одна колонка "Значение". А колонка "Родитель" у таблицыЗначений должна соответствовать стандартному свойству "Родитель" у ДереваЗначений.
31 roman383
 
15.03.13
14:34
(29) поэтому поиск по родителю вызывает ошибку (т.к. такой колонки у ДЗ нет).
32 cw014
 
15.03.13
14:37
(31) Создай колонку. После заполнения удали. Иначе лажу получишь
33 roman383
 
15.03.13
14:47
(32) Я уже проверил. Все работает правильно. Колонка "Значение" является родителем для вложенного уровня.

Для Каждого СтрокаТаблицы Из ТЗЗапроса Цикл
       
       Если СтрокаТаблицы.Родитель = 0 тогда
           СтрокаДерева = пДерево.Строки.Добавить();
       Иначе
           СтрокаРодитель = пДерево.Строки.Найти(СтрокаТаблицы.Родитель, "Значение", Истина);
           СтрокаДерева = СтрокаРодитель.Строки.Добавить();
       КонецЕсли;
       
       ЗаполнитьЗначенияСвойств(СтрокаДерева, СтрокаТаблицы);
       
   КонецЦикла;