Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Recursive
Message
From
22/08/1999 14:42:21
 
 
To
22/08/1999 02:36:11
General information
Forum:
Visual FoxPro
Category:
Coding, syntax & commands
Title:
Miscellaneous
Thread ID:
00256374
Message ID:
00256425
Views:
29
John,

Contrary to what you might be thinking recursion is an *extremely* powerful programming technique that can give you great results - if a couple of things happen first.

First, your data should lend itself to a recursive routine. For example a multi-level structure where the numbers of, and definitions of, lower levels are unknown. Your disk drive's directory is a great example where a recursive routine might be of use.

Secondly, you need to think a little differently when creating recursive routines. I use them currently in my work and they work *very* well but writing them can give you headaches. *g*

The 128 level limitation is *no* problem _if_ your routine is written correctly. The routine only ever knows two level deep if sone right. The 'trick' is to hide prior levels from the routine. That is, it needs to back up one level before going down another.

I'll take the liberty of posting some code here if you don't mind. The first routine AGTRECUR1.PRG is a calling "top level" program. It calls GETAGENT.PRG which does all the heavy lifting. These programs are copyrighted (c) 1999 Equity First, LLC and all rights are reserved but you are free to examine the code and use it for any purpose you'd like as long as you don't compete with us! *BG*

The KEYWALK.PRG reference is justa routine that "walks down" the chain until it finds the next active agent. I did this to make the program simpler.

You'll see that GetAgent calles GetAgent - ergo recursion.

Best,

FUNCTION AgtRecur1
PARAMETERS cTopID

SET EXCLUSIVE OFF

LOCAL nLevel
STORE 1 TO nLevel

IF TYPE("cTopID") <> "C"
STORE "" TO cTopID
ENDIF

CREATE CURSOR cagents (agentid C(6), AgtName C(40), AgtLevel N(2,0), parentid C(6), agtprnt C(40))
INDEX ON STR(AgtLevel) + agentid + parentid TAG agentid
INDEX ON STR(AgtLevel) + parentid + agentid TAG parentid
SET ORDER TO 0

IF EMPTY(cTopID)
*
** Call routine for the first time
*
SELECT agentid, AgtName(agentid) ;
FROM agents ;
WHERE ACTIVE AND ;
NOT EMPTY(agentid) ;
AND EMPTY(linkid) ;
ORDER BY linkid ;
INTO ARRAY aagentid

IF _TALLY > 0 AND NOT EMPTY(aagentid[1,1])
INSERT INTO cagents ;
(agentid, AgtName, AgtLevel, parentid, agtprnt) ;
VALUES ;
(aagentid[1,1],aagentid[1,2], nLevel, "", "")

=GetAgent(aagentid[1,1],nLevel + 1)

ENDIF

ELSE
SELECT agentid, AgtName(agentid);
FROM agents ;
WHERE agents.agentid = cTopID ;
AND ACTIVE AND ;
NOT EMPTY(agentid) ;
ORDER BY linkid ;
INTO ARRAY aagentid

IF _TALLY > 0 AND NOT EMPTY(aagentid[1,1])
INSERT INTO cagents ;
(agentid, AgtName, AgtLevel, parentid, agtprnt) ;
VALUES ;
(aagentid[1,1],aagentid[1,2], nLevel, "", "")
ENDIF
=GetAgent(cTopID, nLevel + 1)
ENDIF
WAIT CLEAR

IF RECCOUNT("cAgents") > 0
SET ORDER TO parentid IN cagents
SELECT cagents
LOCATE
ENDIF



FUNCTION GetAgent
PARAMETERS cParentID, nLevel

PRIVATE ALL LIKE aP*
PRIVATE ALL LIKE nL*

IF TYPE("cMaster") <> "C" OR EMPTY(cMaster)
cMaster = cParentID
ENDIF

*
** cParentID = The LinkID of the next-lower generation
*
*
** The following SELECT statement gathers the next lower generation's information
*
* Array aParentID elements selected are:
*
** 1. Agent ID of Parent ID
** 2. Agent Name of Agent ID
** 3. Agent Name of Parent ID
** 4. Agent's Active status
** 5. Agent's Parent ID - This updates cParentID *when* the current Agent id Active
*
SELECT agentid, AgtName(agentid), AgtName(cParentID), ACTIVE, linkid;
FROM agents ;
WHERE agents.linkid = cParentID ;
AND NOT EMPTY(linkid) ;
GROUP BY agentid ;
ORDER BY linkid ;
INTO ARRAY aParentID

IF _TALLY > 0
LOCAL TheNewLevel
STORE nLevel + 1 TO TheNewLevel
FOR nloop1 = 1 TO ALEN(aParentID,1)

IF aParentID[nLoop1,4]
*
** If this is an active Agent insert information into cursor
*

*
** Display Current Agent Name
*
WAIT CLEAR
WAIT WINDOW NOWAIT ALLTRIM(aParentID[nLoop1,2])

cParentID = KeyWalk(aParentID[nLoop1,5])

IF EMPTY(cParentID)
STORE cMaster TO cParentID
ENDIF

cParentName = AgtName(cParentID)

nLevel = nLevel + 1
INSERT INTO cagents ;
(agentid, AgtName, AgtLevel, parentid, agtprnt) ;
VALUES ;
(aParentID[nLoop1,1], aParentID[nLoop1,2], nLevel, cParentID, cParentName)

ENDIF
=GetAgent(aParentID[nLoop1,1], @nLevel)
nLevel = TheNewLevel - 1
ENDFOR
RETURN
ELSE
nLevel = nLevel - 1
ENDIF
RETURN


>Hi,
> How to have recursive that nested more than 128 level? I tried to use proceudre, but not works...
>
>Thank you
Best,


DD

A man is no fool who gives up that which he cannot keep for that which he cannot lose.
Everything I don't understand must be easy!
The difficulty of any task is measured by the capacity of the agent performing the work.
Previous
Reply
Map
View

Click here to load this message in the networking platform