Hacker’s Guide to Visual FoxPro
An irreverent look at how Visual FoxPro really works. Tells you the inside scoop on every command, function, property, event and method of Visual FoxPro.
RELATION()
, TARGET()
These two functions tell you about temporary relations—the kind you set up with SET RELATION
. RELATION()
tells you the relational expression while TARGET()
tells you what alias the relation is pointing at.
cRelationalExpr = RELATION( nRelationNumber
[, cAlias | nWorkArea ] )
cTargetAlias = TARGET( nRelationNumber [, cAlias | nWorkArea ] )
Parameter |
Value |
Meaning |
nRelationNumber |
Numeric |
Which relation of this parent are we interested in? |
cAlias |
Character |
Provide information about relations for which cAlias is the parent. |
Omitted |
If nWorkArea is also omitted, provide information for relations in which the current work area is the parent. |
|
nWorkArea |
Numeric |
Provide information about relations for which the table in nWorkArea is the parent. |
Omitted |
If cAlias is also omitted, provide information about relations in which the current work area is the parent. |
RELATION()
and TARGET()
provide information from the point of view of the parent table in a relationship. TARGET()
gives the alias of the child table, while RELATION()
returns the expression from the parent table that drives the relation.
Because a single table may be parent to a number of children, you must specify which relation from the parent you’re interested in. Relations are numbered in the reverse order of creation. That is, both TARGET(1) and RELATION(1) return the information for the most recently established relation.
Both functions return the empty string if there is no relation nRelationNumber for the specified parent. This makes looping through all relations easy; just stop when you get an empty return value for either function.
There are two main reasons you’d use these functions. In both cases, the relative order of the relations isn’t terribly important, since you’ll be looping through the relations.
The first reason is to determine if a particular relation has already been established. In this case, you’d loop through TARGET()
until you run out of relations or find the one you’re looking for.
The second case is to store information on all existing relations. In this case, you’d want to loop through all the relations. (The example below shows a function, aRelns, that does this.) Interestingly, if you store the information in an array, then process the array from top to bottom, you end up reversing the order of the relations. Since each relation involves a single parent and a single child, this isn’t terribly important.
* Arelns.PRG
* Fill an array with all relations from a specified table.
* Return the number of relations.
* If there's a problem with parameters, return -1.
LPARAMETERS aRelations,cAlias
* aRelations = array to hold relation info.
* cAlias = alias of the parent. If omitted, current work area.
LOCAL nParams, nRelCnt, nOldArea
nParams = PARAMETERS()
IF nParams = 0 OR TYPE('aRelations[1]') = "U"
RETURN -1
ENDIF
IF nParams = 1
* Use current work area
IF EMPTY(ALIAS())
* No table in use
RETURN -1
ENDIF
ELSE
IF TYPE('cAlias') <> "C" OR NOT USED(cAlias)
RETURN -1
ENDIF
ENDIF
nOldArea = SELECT()
IF nParams > 1
SELECT (cAlias)
ENDIF
* Now start processing relation information
nRelCnt = 1
DO WHILE NOT EMPTY(RELATION(nRelCnt))
DIMENSION aRelations[nRelCnt, 2]
aRelations[nRelCnt, 1] = RELATION(nRelCnt)
aRelations[nRelCnt, 2] = TARGET(nRelCnt)
nRelCnt = nRelCnt + 1
ENDDO
RETURN nRelCnt - 1
The function does not determine whether the relation is one-to-one or one-to-many. That information is available as a single result for the parent. Use SET(“SKIP”) to get the list of one-to-many relations for a parent.