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.
ORDER()
, SET ORDER
, Set(“Order”), SET INDEX
, Set(“Index”), Sys(21), Sys(22)These commands and functions all relate to putting an index in control and finding out which one is currently in control. ORDER()
and SET ORDER
are the most up-to-date ways to do this stuff. SET ORDER
lets you specify a tag or stand-alone index to control the table. ORDER()
lets you find out which one it is. SET INDEX
lets you open stand-alone indexes and non-structural compound indexes, as well as setting one of them in control. SYS(21) and SYS(22) are antique ways to find out which index is in charge. Don’t use them because, like all the SYS() Functions
, their names give you no clue what they’re about.
When tables or indexes are opened, each stand-alone index and tag is assigned a number, based on its position. Several of these commands use that number to refer to a particular index or tag. See CANDIDATE()
for details on this numbering. Like work area numbers, we recommend you avoid these numbers whenever possible and refer to indexes by name.
cCurrentOrder = ORDER( [ cAlias | nWorkArea
[ , nIncludePath ] ] )
Parameter |
Value |
Meaning |
cAlias |
Character |
Return the current order in the work area whose alias is cAlias. |
Omitted |
If nWorkArea is also omitted, returns information for the current work area. |
|
nWorkArea |
Numeric |
Return the current order for work area nWorkArea. |
Omitted |
If cAlias is also omitted, return information for the current work area. |
|
nIncludePath |
Numeric |
Include the full path to the index file. |
Omitted |
Return just the index or tag name. |
|
cCurrentOrder |
Character |
The name of the current index or tag. If nIncludePath is specified, includes the full path to the index file. For tags with nIncludePath, returns the name of the compound index file with its path rather than the tag. |
ORDER()
is the function to use when you want to save the current order before changing it. But it can give you much more information with the optional nIncludePath parameter. With two calls, you can find out both the tag in charge and the name and path of the index file containing that tag.
SET ORDER TO [ nIndexNumber | IndexFileName
| [ TAG ] TagName [ OF CompoundIndexFile ]
[ IN cAlias | nWorkArea ]
[ ASCENDING | DESCENDING ] ]
SET INDEX TO [ IndexFileList | ?
[ ORDER nIndexNumber | IndexFileName
| [ TAG ] TagName [ OF CompoundIndexFile ]
[ ASCENDING | DESCENDING ]
[ ADDITIVE ] ]
Parameter |
Value |
Meaning |
nIndexNumber |
Numeric |
The number for the index to put in charge. |
IndexFileName |
Name |
The name of a stand-alone index to put in charge. |
TagName |
Name |
The name of a compound index tag to put in charge. |
CompoundIndexFile |
Name |
The name of the compound index file containing the specified tag. Can be omitted if the tag name is unique. |
cAlias |
Character |
Set the current order in the work area whose alias is cAlias. |
Omitted |
If nWorkArea is also omitted, set order for the current work area. |
|
nWorkArea |
Numeric |
Set the current order for work area nWorkArea. |
Omitted |
If cAlias is also omitted, set order for the current work area. |
|
IndexFileList |
List of Names |
A list of index files to open. |
SET INDEX
TO lets you specify index files to open as well as the order to set. SET ORDER
specifies just the new order. We don’t use SET INDEX
much anymore because we almost always keep all the indexes we need in a single, structural index file.
The ASCENDING/DESCENDING switch here is confusing because you can create indexes in either ascending or descending order and use them both ways as well. The key fact is that the terms “ascending” and “descending” keep their normal meanings and don’t double up. That is, if you create a tag in descending order and then SET ORDER
TO that tag DESCENDING, it doesn’t get reversed to ascending. Two descendings don’t make an ascending.
The other confusing thing is that the direction you create the tag matters only when you first open the table any given time. Once you SET ORDER TO that tag once, FoxPro remembers the last direction you used that tag in. If you omit ASCENDING and DESCENDING on a subsequent SET ORDER, you get the orientation you used last. (If you omit them initially, you get the creation direction for that tag.) This effect continues until you close and reopen the table. |
Also, keep in mind that a table can’t use the same index/tag in two different orders at the same time. That is, if you USE a table twice and SET ORDER
in each to the same tag, you can’t make one ascending and the other descending. The last one set wins—even if the table is used in different data sessions.
Like so many other SET commands, issuing SET ORDER
TO without a tag or index name clears the setting. In this case, it indicates that record-number order should be used. SET ORDER
TO 0 does the same thing as does SET ORDER
TO “”. SET INDEX
TO without any files closes open indexes except for the structural CDX.
cCurrentOrder = SET( "ORDER" )
cIndexList = SET( "INDEX" )
SET(“ORDER”) provides information in a different format than ORDER()
. It gives the name of the current tag and the name of the index file that contains it. If order is currently descending, it also includes the word “DESCENDING.” Until FoxPro 2.6 added the DESCENDING()
function, this was the only way to find out if an index was being used in descending order. Since the information is available in other forms and parsing the string returned is something of a pain, we suggest you forget about SET(“ORDER”), except for saving and restoring the current order, where it gives you exactly the information you need.
SET(“INDEX”) gives you a string that you can pass back to SET INDEX
. It’s a complete list of all the index files (with paths) open for the current table. It even includes the structural CDX. If an order is set, the ORDER clause is included, too. Oddly, SET(“INDEX”) uses lowercase for the information from your table while all the other functions in this group use uppercase.
nTagNumber = SYS( 21 [, nWorkArea ] )
cTagName = SYS( 22 [, nWorkArea ] )
Since you can get the same result as SYS(21) and SYS(22) with TAGNO()
and ORDER()
, we can’t see any reason to use these obtusely named functions.
USE Customer
SET ORDER TO Company_Na
? ORDER() && Returns "COMPANY_NA"
? ORDER("Customer", 1) && Returns something like
* "C:\PROGRAM FILES\MICROSOFT VISUAL FOXPRO\
* SAMPLES\TASTRADE\DATA\CUSTOMER.CDX"
? SET("ORDER") && Returns something like
* "TAG COMPANY_NA OF C:\PROGRAM FILES\MICROSOFT VISUAL
* FOXPRO\SAMPLES\TASTRADE\DATA\CUSTOMER.CDX"
? SYS(21) && Returns 1
? SYS(22) && Returns "COMPANY_NA"
? SET("INDEX") && Returns something like:
* " c:\program files\microsoft visual
* foxpro\samples\tastrade\data\customer.cdx ORDER TAG
* company_na OF c:\program files\microsoft visual
* foxpro\samples\tastrade\data\customer.cdx"