powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Бегание по иерархической структуре.
18 сообщений из 18, страница 1 из 1
Бегание по иерархической структуре.
    #33485578
Всех с праздниками!

Посоветуйте хороший, читабельный код для бегания по дереву.

Вот структура файла:
ParentID , KeyID , Map



За ранее спасибо )
...
Рейтинг: 0 / 0
Бегание по иерархической структуре.
    #33485703
Urri
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Люблю рекурсии в данном аспекте.
...
Рейтинг: 0 / 0
Бегание по иерархической структуре.
    #33486220
Андрей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
UrriЛюблю рекурсии в данном аспекте.
Хорошая мысль - но как рекурсия реализована в FoxPro?
...
Рейтинг: 0 / 0
Бегание по иерархической структуре.
    #33486424
Фотография Aleksey-K
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А я использую для этих целей стек. Такой структуре нет в VFP, поэтому пришлось создать класс на основе Custom, который имеет три метода:
PUSH - положить на верхушку стека
POP - снять с верхушки стека
GetNumRecord - вернуть кол-во записей с стеке.
Если интересно, могу привести код.
С уважением, Алексей
...
Рейтинг: 0 / 0
Бегание по иерархической структуре.
    #33486448
Urri
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Процедурно. ;-)

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
do x with 'c:\'

proc x
lparam pcurpath
local i
if type('spc')!='C'
  private spc
  spc = ''
endif
=adir(xzx,pcurpath+'*.*','D')
for i =  1  to alen(xzx, 1 )
  if left(xzx(i, 1 ), 1 ) != '.'
    ? pcurpath+xzx(i, 1 )
    spc = spc + '  '
    do x with pcurpath+xzx(i, 1 )+'\'
    spc = left(spc,len(spc)- 2 )
  endif
next

(Пишу набело, поэтому код скорее всего работать как есть не будет ;-))
...
Рейтинг: 0 / 0
Бегание по иерархической структуре.
    #33486463
Urri
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Aleksey-K, конечно, с удовольствием посмотрим!
...
Рейтинг: 0 / 0
Бегание по иерархической структуре.
    #33486899
Фотография Aleksey-K
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Класс Steck
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
DEFINE CLASS Steck AS Custom
	Stack_Rec =  0 
	DIMENSION Stack[ 1 ]

PROCEDURE Init
	DIMENSION THIS.Stack[ 1 ]
	THIS.Stack_Rec =  0 
ENDPROC

PROCEDURE getnumrecord
	RETURN THIS.Stack_Rec
ENDPROC

PROCEDURE push
	LPARAMETERS lnID
	*-- Помещение на верхушку стэка
	THIS.Stack_Rec = THIS.Stack_Rec +  1 
	DIMENSION THIS.Stack[THIS.Stack_Rec]
	THIS.Stack[THIS.Stack_Rec] = m.lnID
ENDPROC

PROCEDURE pop
	*-- Снимаем с верхушки стэка значение с удалением его из стэка и дикрементом указателя
	LOCAL lRet
	IF THIS.Stack_Rec =  0 
		RETURN  0 
	ENDIF
	m.lRet = THIS.Stack[THIS.Stack_Rec]
	THIS.Stack_Rec = THIS.Stack_Rec -  1 
	RETURN (m.lRet)
ENDPROC
ENDDEFINE

А так можно, например, его использовать:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
*-- Таблица TreeTabl имеет, как минимум, поля ParentID , KeyID
*--ЗАДАЧА: Найти все KeyID, который подчиняются lnKeyID и записать их
*-- в курсор Result
USE IN SELECT("Result")
CREATE CURSOR Result (KeyID I)
loSteck = CREATEOBJECT("Steck")
loSteck.Push(m.lnKeyID)
*-- Главнй цикл
DO WHILE loSteck.GetNumRecord() >  0 
	*-- Снимает с верхушки стэка
	m.lnKeyID = loSteck.Pop()
	SELECT Temp 
	LOCATE FOR KeyID = m.lnKeyID 
	IF FOUND()
		SELECT Result 
		INSERT INTO Result (KeyID) VALUES (m.lnKeyID)
	ENDIF
	*-- Находим все подразделения для m.lnKeyID 
	SELECT KeyID FROM TreeTabl  INTO CURSOR temp NOFILTER ;
		WHERE ParentID = m.lnKeyID 
	*-- Переписываем их в стэк
	SELECT temp
	GOTO TOP
	SCAN
		loSteck.Push(temp.KeyID)
	ENDSCAN
	USE IN SELECT("temp")
ENDDO
RELEASE loSteck
SELECT Result
GOTO TOP

С уважением, Алексей
...
Рейтинг: 0 / 0
Бегание по иерархической структуре.
    #33488762
Aleksey-K:

Спасибо, буду разбирать Ваш код )

А этот модуль можно использовать в качестве рекурсивной функции?
...
Рейтинг: 0 / 0
Бегание по иерархической структуре.
    #33488820
Фотография Aleksey-K
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вы про какой модуль спрашиваете?

С уважением, Алексей
...
Рейтинг: 0 / 0
Бегание по иерархической структуре.
    #33491384
Ну, код для поиска детей в структуре, что вы написали - разве не ответ на мой вопрос ? ))

*-- Таблица TreeTabl имеет, как минимум, поля ParentID , KeyID
*--ЗАДАЧА: Найти все KeyID, который подчиняются lnKeyID и записать их
*-- в курсор Result
USE IN SELECT("Result")
CREATE CURSOR Result (KeyID I)
loSteck = CREATEOBJECT("Steck")
loSteck.Push(m.lnKeyID)
............
...
Рейтинг: 0 / 0
Бегание по иерархической структуре.
    #33491415
Фотография Aleksey-K
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Теперь понятно, но дело в том, что я стек и применил, что-бы не связывться с рекурсией. В некоторм роде взаимоисключающие приемы.

С уважением, Алексей
...
Рейтинг: 0 / 0
Бегание по иерархической структуре.
    #33491553
Андрей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всё это работает не благодаря стеку (не в обиду сказано), а только по тому-что в FoxPro есть цикл Do While и Sql-операторы...
...
Рейтинг: 0 / 0
Бегание по иерархической структуре.
    #33491667
Фотография Aleksey-K
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей КВсё это работает не благодаря стеку (не в обиду сказано), а только по тому-что в FoxPro есть цикл Do While и Sql-операторы...
Можно и без стека
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
LOCAL lnLevel

CREATE CURSOR  Result (KeyID I, Lev I)
m.lnLevel  =  0 
INSERT INTO Result (KeyID, Lev) ;
SELECT KeyID, m.lnLevel FROM TreeTabl WHERE KeyID = m.lnKeyID
DO WHILE _TALLY >  0 
	m.lnLevel = m.lnLevel +  1 
	INSERT INTO Result (KeyID, Lev) ;
	SELECT TreeTabl.KeyID, m.lnLevel FROM TreeTabl  ;
		INNER JOIN Result ON TreeTabl.ParentID = Result.KeyID AND Result.Lev = m.lnLevel -  1 

ENDDO

В T-SQL я тоже именно такой проход по "дереву" без стека, но получается не так красиво. Стек у меня используется и для других целей, грех было его и тут не использовать.
C Уважением, Алексей.
...
Рейтинг: 0 / 0
Бегание по иерархической структуре.
    #33491878
Андрей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хороший код, Алексей.
...
Рейтинг: 0 / 0
Бегание по иерархической структуре.
    #33492376
Фотография Aleksey-K
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо, Андрей.
С уважением, Алексей
...
Рейтинг: 0 / 0
Бегание по иерархической структуре.
    #33493137
Igor Korolyov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hi Aleksey!

> Класс Steck
> DIMENSION Stack[1]

Имя самого класса искажено намеренно? Или просто описка которая "тянется
исторически" :)

Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
Бегание по иерархической структуре.
    #33493192
Val Kor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
** Заимствовано из книги Р. Пэддок по VFP8

** структура файла: ParentKey Cod Name

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
** структура файла: ParentKey Cod Name

** INIT объекта oletreeview1
SELECT UchD
SET ORDER TO PARENTKEY   && PARENTKEY+COD 
GO TOP 
thisform.loadfile ()

** Метод loadfile формы, где объект oletreeview1

This.oletreeview1.Nodes.Clear 
SCAN FOR ParentKey = Cod 
	This.oletreeview1.Nodes.Add(,,"KEY" + Cod, RTRIM(Name)) 
  IF SEEK(Cod)
    This.LoadNode(Cod)
  Endif    
ENDSCAN 

** Метод LoadNode формы, где объект oletreeview1
Lparameters lnKeyToLoad

*-- Save the work area
Local lnKod, lnRecno, lnRecno2
lnRecno = Recno()
Go Top
Scan For ParentKey = lnKeyToLoad
  lnKod = Cod
 If Parentkey # lnKod
    This.oletreeview1.Nodes.Add("KEY" + lnKeyToLoad, 4 ,"KEY" + lnKod, RTRIM(Name))
     lnRecno2 = Recno()
    *-- если эта запись родитель, то грузим её детей
    If Seek(lnKod)
      This.LoadNode(lnKod)
    Endif    
    *-- восстанавливаем местоположение в файле
    If lnRecno2 #  0 
     Goto lnRecno2
    Endif
 Endif
Endscan

If lnRecno #  0 
  Goto lnRecno
ENDIF

...
Рейтинг: 0 / 0
Бегание по иерархической структуре.
    #33493326
Фотография Aleksey-K
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Igor Korolyov
Hi Aleksey!

> Класс Steck
> DIMENSION Stack[1]

Имя самого класса искажено намеренно? Или просто описка которая "тянется
исторически" :)

Posted via ActualForum NNTP Server 1.3
Да, тяжелое наследие прошлого..... :)
Менять уже поздно...
С уважением, Алексей.
...
Рейтинг: 0 / 0
18 сообщений из 18, страница 1 из 1
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Бегание по иерархической структуре.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]