|
02.08.2006, 11:01 | #1 |
Участник
|
перебор элементов в Tree
Добрый день, господа. Возникла следующая проблема - необходимо перебрать все элементы дерева, начиная с корня и проходя по всем child-элементам. Думаю что это будет какая-то рекурсивная функция, но с реализацией ее пока проблема... Если кто-то сталкивался с подобным - прошу помочь.
|
|
02.08.2006, 11:12 | #2 |
Участник
|
Правда нужна лицензия на crm
PHP код:
|
|
02.08.2006, 11:47 | #3 |
Участник
|
Спасибо за ответ, думаю когда-нибудь он пригодится... Я наверно неправильно выразился, нужно было пройтись не по таблице, а по элементам контрола Tree. Решение только что нашел на форуме, ссылка прилагается
Работа с деревом |
|
02.08.2006, 16:41 | #4 |
Участник
|
Еще один вопрос по деревьям
Как записать значение в Data() элемента formTreeItem?
В моем конкретном случае нужно записать enum, но думаю тут тип не влияет на результат. Привожу псевдокод: (Tree - элемент дерево на форме) Код: formTreeItem Tmp; DetailingOfSales detailing; //таблица int curr; curr = tree.add(parent, 0, detailing.unitId); Tmp = tree.getItem(curr); Tmp.data(detailing.UnitType); Не знаю что делать, поиск не помог |
|
02.08.2006, 11:45 | #5 |
Участник
|
Код: void rebuildSubnodes(TreeItemIdx _treeItemIdx = FormTreeAdd::Root) { FormTreeItem treeItem; TreeItemIdx childIdx = treeControl.getChild(_treeItemIdx); while (childIdx) { treeItem = treeControl.getItem(childIdx); if (conFind(conCheckedNodes, treeItem.data())) treeItem.stateImage(imageListAppl.image(#ImageCheckAll)); else treeItem.stateImage(imageListAppl.image(#ImageCheckNone)); treeControl.setItem(treeItem); if (conFind(conBuiltNodes, treeItem.data())) this.rebuildSubnodes(treeItem.idx()); childIdx = treeControl.getNextSibling(childIdx); } } |
|
02.08.2006, 16:59 | #6 |
Участник
|
Добавьте в ваш код
X++: ... tree.setItem(Tmp);
__________________
Axapta v.3.0 sp5 kr2 |
|
02.08.2006, 17:23 | #7 |
Участник
|
Кстати, можно добавлять узлы так
X++: curr = new FormTreeItem(detailing.unitId);
curr.data(map);
tree.addItem(parent, 0, curr);
__________________
Axapta v.3.0 sp5 kr2 |
|
03.08.2006, 11:33 | #8 |
Участник
|
Благодарю, последний вариант подошел идеально
|
|
12.04.2013, 16:34 | #9 |
Участник
|
Вопрос по деревьям:
Строится отчёт Excel, есть поле Отдел продаж(salesUnitid), там дерево. Нужно сделать выборку по этому полю и чтобы в отчёт попадали те строки, которые соответствуют выбранному уровню, то есть, если выбран отдел продаж, нужно выбирать все строки, которые соответствуют нижнему уровню отдела продаж(БП,РФ,ДЗАт и т.д.), а если выбран один из нижних уровней - строки только нижнего уровня. То есть, чтобы раскрытие дерева шло вниз. Посоветовали использовать List и в цикле прогонять каждый раз, но не совсем представляю как это сделать, показали пример на cte, но у меня запрос не на чистом sql, а на аксаптовском sql, если можно так выразиться, так что не думаю, что мне cte подойдёт. Может кто подсказать в какую сторону копать и с чего начинать проход ? Почитал на форуме ещё, что можно Map-ы использовать для этого дела... Я так понимаю, по таблице SMMSALESUNIT и сравнивать PARENTID и SALESUNITID , но что-то голова не работает... Что-то вроде X++: while select salesunitid from SmmSalesUnit where .SmmSalesUnit salesunitid like SmmSalesUnit .parentid { List.add(salesunitid); } Последний раз редактировалось user_ax; 12.04.2013 в 16:53. |
|
12.04.2013, 17:43 | #10 |
Участник
|
Никто не может подсказать хотя бы приблизительного решения?
|
|
12.04.2013, 17:56 | #11 |
Участник
|
Ну в общем Вы двигаетесь в правильном направлении.
Если я Вас правлиьно понял, Вам надо выбрать все дочерние записи отталкиваясь от определенного значения SalesUnitId, тогда напишите рекурсивную функцию, которая, получая SalesUnitId как параметр, выбирает по очереди (while select) все дочерние записи, и, если какая нибудь из них тоже содержит дочерние, вызывается рекурсивно для этой конкретой дочерней записи. Ну например: X++: static void Job45(Args _args) { SMMSalesUnitId salesUnitId; List salesUnits = new List(Types::String); List getChildSalesUnit(SMMSalesUnitId _salesUnitIdParent) { SMMSalesUnit salesUnit; List childSalesUnit = new List(Types::String); //Add current sales unit to list childSalesUnit.addEnd(_salesUnitIdParent); //Check for child records select count(RecId) from salesUnit where salesUnit.ParentId == _salesUnitIdParent; if (!salesUnit) { return childSalesUnit; } //Go through child records and call recurent function while select SalesUnitId from salesUnit where salesUnit.ParentId == _salesUnitIdParent { //Merge list with the result list of all children childSalesUnit = List::merge(childSalesUnit, getChildSalesUnit(salesUnit.SalesUnitId)); } return childSalesUnit; } ; salesUnitId = "any value"; salesUnits = getChildSalesUnit(salesUnitId); }
__________________
http://www.axdevposts.blogspot.com Пришел, уведел.... отойди, дай другому увидеть! Последний раз редактировалось plumbum; 12.04.2013 в 18:07. Причина: Орфография... мда, 3 года всего учил русский в школе :) |
|
|
За это сообщение автора поблагодарили: user_ax (1). |
12.04.2013, 17:59 | #12 |
Участник
|
Цитата:
Сообщение от plumbum
Ну в общем Вы двигаетесь в правильном направлении.
Если я Вас правлиьно понял, Вам надо выбрать все дочерние записи отталкиваясь от определенного значения SalesUnitId, тогда напишите рекурсивную функцию, которая, получая SalesUnitId как параметр, выбирает поочереди (while select) все дочерние записи, и, если какая нибудь из них тоже содержит дочернии, вызывается рекурсивно для этой конкретой дочерней записи. Да, вы меня правильно поняли. Если есть дочерние - выбирать их, если нет - выбирать текущее значение salesunitid, которые выделено. Сейчас попробую ваш джобик) |
|
12.04.2013, 18:08 | #13 |
Участник
|
Я прошу прощения, допустил в джобе ошибку. Критерий выборки конечно:
X++: where salesUnit.ParentId == _salesUnitIdParent
__________________
http://www.axdevposts.blogspot.com Пришел, уведел.... отойди, дай другому увидеть! |
|
12.04.2013, 18:11 | #14 |
Участник
|
Как я уже написал, джобик я подправил.
Попробуйте так: X++: print (salesUnits.toString())
__________________
http://www.axdevposts.blogspot.com Пришел, уведел.... отойди, дай другому увидеть! |
|
12.04.2013, 18:12 | #15 |
Участник
|
|
|
12.04.2013, 18:11 | #16 |
Участник
|
Благодарю, поправил.
Хотел посмотреть дочерние элементы Отдела продаж, но почему-то не вывел, или это необходимо делать в цикле? X++: salesUnitId = "Отдел продаж"; salesUnits = getChildSalesUnit(salesUnitId); print (salesUnitId); pause; |
|
12.04.2013, 18:20 | #17 |
Участник
|
Можно про запрос по-подробнее?
Ели вам нужен этот список, как источник данных, переберите весь List итератором/энумератором, и повставляейте записи во временную таблицу. Тогда я еще бы посоветовал создавать List с типом элементов Record: не пришлось бы потом по ключу перевыбирать записи. Удачи!
__________________
http://www.axdevposts.blogspot.com Пришел, уведел.... отойди, дай другому увидеть! |
|
15.04.2013, 09:40 | #18 |
Участник
|
Цитата:
Сообщение от plumbum
Можно про запрос по-подробнее?
Ели вам нужен этот список, как источник данных, переберите весь List итератором/энумератором, и повставляейте записи во временную таблицу. Тогда я еще бы посоветовал создавать List с типом элементов Record: не пришлось бы потом по ключу перевыбирать записи. Удачи! По поводу enumerator читал, попробую, спасибо. Вы имеете ввиду Types::Record ? |
|
15.04.2013, 12:14 | #19 |
Участник
|
Теперь проблема иного характера.
Рекурсивный метод отрабатывает верно и выбирает все дочерние значения по отношению к выбранному. Объявил строковую переменную в методе выборки данных, присвоил ей результат, который возвращает метод (строка строк), в условии выборки пишу X++: salesQuotationTable.SalesUnitId like salesunitid X++: <"Отдел продаж трансф.", "БП", "ДЗАТ", "ДЗБВА", "ДЗЕА", "РФ", "СРАЗ", "УБМ"> Есть ли какие-то особенности лайка аксаптовского? Искал на форуме, ничего толкового не нашёл. Переменная, в которую попадает результирующая строка ограничена 500 символами. Буду благодарен за любую подсказку |
|
15.04.2013, 12:31 | #20 |
Участник
|
|
|