Страница 1 из 3
Определение родителя в дереве
Добавлено: 13 май 2008, 10:19
aw
Добрый день.
Подскажите, как найти родителя не ближайшего, а скажем на несколько уровней вверх. Сложность заключается в том, что объект входит сразу в несколько других объектов и по заданию, необходимо найти родителя, который должен присутствовать в текущем открытом дереве.
Пример дерева:
родитель1-|
|-объект 11-|
... (куча других объектов)
|- потомок
родитель2-|
|-объект 22-|
...
|- потомок
Для выделенного жирным объекта "потомок" (мышкой выбрали) надо найти "родитель2".
Мож как нить через запрос в базе можно сделать?
Щас я смог только сделать что бы выдавал
множество объектов (родитель1, родитель2 ... ), а нужен только "родитель2".
PS
Функция
Obj_current = LinkGetParent ( a_TLinkID ) ищет родителя только от a_Object, и если руками поменять значение a_Object эта функция всё равно введёт тоже значение что и раньше.
То есть искать с помощью её на несколько уровней вверх нельзя.
Добавлено: 13 май 2008, 10:48
Александр
родителя - точнее любой объект по критериям по связи и т.д. ищите своим SQL запросом к базе
по поводу PS
все работает на любое количество вверх(вниз), делаете цикл
нашли родителя
id=set(родитель)
a_Object=setbyid(id)
где id - просто числовая переменная...
и по кругу
но лучше конечно сразу найти нужный объект своим запросом
а дальше также
id=set(number( f_execsqlselect/_2/3 ('ваш запрос возвращающий id нужного вам объекта', '', '') ))
ваш объект = setbyid(id)
и т.д.
Дешево и сердито

поверьте...

Добавлено: 13 май 2008, 11:33
aw
В версии 4.12 не работает.
Добавлено: 13 май 2008, 11:38
aw
Obj = LinkGetParent ( a_TLinkID )
a_Object = SetByID ( Obj )
Obj_current = LinkGetParent ( a_TLinkID )
Obj и Obj_current получаются одинаковые.
проверенно. (версия 4.12)
Но всё таки интересует по поводу самого верхнего вопроса.
Возможно ли так сделать?
Добавлено: 13 май 2008, 12:19
Александр
не получается потому что вы выходите на объект с одной и той же связью - ведь a_TLinkID не что иное как id связи с родителем - соответственно так как вы ее не переопределяли то...
к сожалению сейчас нет времени разбираться

просто потому что мы этим не пользуемся
но сделайте пока так что то на основе вот этого
Код: Выделить всё
SELECT tl.id,
tl.parent_id
FROM LSDBO.object_reference_view rw,
lsdbo.tree_link_view tl
WHERE rw.id=100004639500000 (это id текущего объекта) and
tl.link_id =rw.id and
tl.link_type_id = 1
где
tl.id - код связи с родителем
tl.parent_id - id родителя
соответственно чтобы уйти вверх по типу связи 1 (дерево)
вам надо нарисовать цикл
Код: Выделить всё
id = Set ( a_Object )
Parent = SetByID ( number( f_execsqlselect_2 ('SELECT tl.parent_id FROM LSDBO.object_reference_view rw, lsdbo.tree_link_view tl WHERE rw.id='+string(id)+ 'and tl.link_id =rw.id and tl.link_type_id = 1', '', '') ) )
WndTree ( Parent , a_LinkType )
a_Object = SetByID ( Parent )
что то в этом духе, это работает т.к. я знаю - есть связь знаю какого она типа и знаю что она одна
НО объект может иметь
несколько связей и не одного а
разных типов - так что SQL и вперед

Добавлено: 13 май 2008, 12:56
aw
Так в этом и суть вопроса
скрипт в указанном мной случае в самом первом посте выдаст
2 записи
Код: Выделить всё
SELECT tl.id,
tl.parent_id
FROM LSDBO.object_reference_view rw,
lsdbo.tree_link_view tl
WHERE rw.id="потомок" (это id текущего объекта) and
tl.link_id =rw.id and
tl.link_type_id = 1
tl.id, объект 11
tl.id, объект 22
соответственно
Код: Выделить всё
id = Set ( a_Object )
Parent = SetByID ( number( f_execsqlselect_2 ('SELECT tl.parent_id FROM LSDBO.object_reference_view rw, lsdbo.tree_link_view tl WHERE rw.id='+string(id)+ 'and tl.link_id =rw.id and tl.link_type_id = 1', '', '') ) )
WndTree ( Parent , a_LinkType )
a_Object = SetByID ( Parent )
выдаёт ошибку.
Суть вопроса в том, можно ли как-либо просмотреть ветку дерева, именно в которой выбран объект "потомок"?
ЗЫ
Вопрос задаю, так на данный момент это является задачей. которую нужно реализовывать.[/code]
Добавлено: 13 май 2008, 13:05
Александр
ну это же очевидно

если под веткой мы понимаем текущего родителя - то можем явно задать поиск по нему, по нужной ветке
типа
Код: Выделить всё
SELECT count(*)
FROM LSDBO.object_reference_view rw,
lsdbo.tree_link_view tl
WHERE rw.id="потомок" (это id текущего объекта) and
tl.link_id =rw.id and
tl.link_type_id = 1 and
tl.parent_id=(id родителя который нам известен или который мы до этого определили)
и понять есть эта связь или нет т.е. входит не входит
или
вот здесь получить всех родителей в виде строки с разделителем
типа
Код: Выделить всё
MyStr = Set ( f_execsqlselect_2 ('SELECT tl.parent_id FROM LSDBO.object_reference_view rw, lsdbo.tree_link_view tl WHERE rw.id='+string(id)+ 'and tl.link_id =rw.id and tl.link_type_id = 1', ',', ',') )
по моему так, ну или где там разделитель правильно ставить в хелпе написано
короче получаем строку где через запятую нарисованы все id родителей - нарезаем ее - ориентируемся
короче просто отвлекись и посмотри с разных сторон что и как тебе нужно получить - в Лоции все решения элементарные - просто нужно отвлечься

Добавлено: 13 май 2008, 13:12
Александр
кстати, вспомнил, по моему стандартные функции лоции по выходу на родителей работают в связке c настройкой переменной объект - список- условия отбора - связь - тут нужно явно указать направление поиска (вверх/вниз)
т.е. те-же самые запросы прикрытие сверху интерфейсом - для тех кто не хочет рисовать запросы в явном виде
ps
что характерно - довольно скоро упираешься в скорость - и вот тут то уже и начинается самое интересное - и запросы и хп и API и что душе угодно

открытая среда разработки - делай что хочешь

.... и как хочешь

Добавлено: 13 май 2008, 13:43
aw
Так это и есть основная проблема.
надо и найти родителя, родитель то нам не известен и нам надо его определить. tl.parent_id - и нужно найти, по одной ветке, которая раскрыа в Лоции.
Код: Выделить всё
SELECT сщгте(*)
FROM LSDBO.object_reference_view rw,
lsdbo.tree_link_view tl
WHERE rw.id="потомок" (это id текущего объекта) and
tl.link_id =rw.id and
tl.link_type_id = 1 and
tl.parent_id=(id родителя который нам известен или который мы до этого определили)
Пример дерева:
родитель1-|
.................|-объект 11-|
........................... (куча других объектов)
....................................|- потомок
родитель2-|
.................|-объект 22-|
...................................
....................................|-
потомок
Для выделенного жирным объекта "потомок" (мышкой выбрали) надо найти "родитель2".
Как получть множество родительских объектов понятно.
Я же и пытаюсь выяснить, как получить именно в текущей ветке родителя (так как это дерево, то родитель для каждого потомка в одной ветке должен быть один).
Запрос же будет выдавать, для моего примера всегда несколько записей, но нужна-то только одна,
которая и находится в текущей, раскрытой в Лоции ветке.
Код: Выделить всё
SELECT tl.parent_id
FROM LSDBO.object_reference_view rw,
lsdbo.tree_link_view tl
WHERE rw.id="потомок" (это id текущего объекта) and
tl.link_id =rw.id and
tl.link_type_id = 1 and
tl.parent_id=(id родителя который нам известен или который мы до этого определили)
LinkGetParent возвращает как раз родителя, находящегося на уровень выше, для потомка , который находится в открытой ветке дерева, но дальше для более высоких уровней LinkGetParent не работает.
Может есть какие-нибудь другие средства в Лоции, которые позволяют это сделать?
Добавлено: 13 май 2008, 13:45
Александр
смотри закладку переменной объекта - условия отбора - связь и используй стандартные функции лоции
Добавлено: 13 май 2008, 13:53
aw
Как получть множество родительских объектов понятно.
Как получить один объект, который и находится в текущей, раскрытой в Лоции ветке.
В указанной вкладке не достаточно параметров.
Вот если бы там был бы параметр
"Объект принадлежит текущей раскрытой ветке", тогда бы вопросов не возникало.
Я пока никак не смог реализовать данную возможность.

Добавлено: 13 май 2008, 13:57
Александр
стоп
делаем так
искомый объект Parent - тип список
условия отбора связи - исходящие
связанный объект a_Object
тип связи - a_LinkType
2 шага
1й
пустой просто шаг свободная форма на форме одна переменная Parent
2шаг
a_Object = SetByID ( Parent )
Parent = Null ( )
GoTo ( 'первый шаг' )
все работает
Добавлено: 13 май 2008, 14:07
Александр
кстати чтобы небыло таких проблем - мы сразу заложили в свою структуру данных адресные атрибуты
т.е. когда создается дочерний объект - мы к нему сразу прикладываем адрес родителя.
да и вообще мы придерживаемся идеологии когда каждый объект имеет точки входа и выхода и знает кто он и где находится - скорость как никак, а главное проблем с переходами поиском и т.д. вообще нет
Добавлено: 13 май 2008, 14:32
aw
Вы наверное так до конца и не поняли мой вопрос.
Вопрос мой звучит так.
Как получить один объект, который и находится в текущей, раскрытой в Лоции ветке?
Предложенный скрипт решает немного другую задачу.
Он находит ВСЕХ родителей потомка, а мне нужен только ОДИН, который и находится в текущей, раскрытой в Лоции ветке.
Что этот скрипт рабочий не возникает вопросов, только он делает немного не то, о чём я спрашивал.
Детально, разбирая работу скрипта на первом же шаге будут выбраны сразу несколько объектов удовлетворяющие условиям.
На следующем шаге будет выдана ошибка.
Я написал и запустил данный скрипт. Указанная ошибка и появилась.
Добавлено: 13 май 2008, 14:44
Александр