MORE INFORMATION
The FoxPro documentation urges the use of name expressions (variables in parentheses) in preference to macro substitution wherever possible. The
INDEX command is one place where this appears to be, but isn't necessarily, possible.
All of the following code can be typed or pasted in the
Command window, or put together in a program. To begin, uncomment and run the code for your specific version of FoxPro:
*!* The sample data changed between each version
*!* Necessary to create an index
SET EXCLUSIVE ON
*!* *VFP 3
*!* USE HOME() + "samples\data\customer"
*!* lnTag = 5 && There are already 4 indexes on the customer table.
*!* *VFP 5
*!* USE HOME() + "samples\data\customer"
*!* lnTag = 6 && In VFP 5 and above, a "country" index was added.
*!* *VFP 6
USE HOME(2) + "data\customer"
lntag=6
lcField = "City"
INDEX ON (lcField) TAG (lcField)
Use the
TAG() function to check the
Index tag, and note that you see the following:
? TAG(lnTag)
*!* Prints "City"
This indicates that name expressions are fine for the
TAG clause. However, if you use the
SYS(14) function to check the index expression, you see the following, indicating that it did not correctly substitute "City:"
? SYS(14, lnTag)
*!* Prints "(lcCity)"
The Help file indicates that an index is created using an expression, so the INDEX command uses the valid expression
(lcField) to create the index. If you change the value of
lcField at this point, the index uses the new values to display the data in the browse window, as shown: (The currently selected record remains visible because the record pointer has not been moved.)
lcField = .F.
BROWSE
lcField = 0
BROWSE
When you remove the variable and try to use the index with this code,
RELEASE lcField
BROWSE
the following sequence of events occurs:
- FoxPro returns the error message:
"Variable 'LCFIELD' is not found."
- FoxPro returns the error message:
"Index does not match the table. Delete the index file and recreate the index."
- Index is treated as an index on "(lcField)" (that is, a character string) from here on out.
- If the table is closed and reopened, steps 1 and 3 occur.
To get your intended results, use the following command:
INDEX ON &lcField TAG (lcField)
*!* or
INDEX ON &lcField TAG &lcField
Another way to misuse macro expansion follows:
lcCity = "Seattle"
INDEX ON city TAG city FOR city = lcCity
BROWSE
That works as expected. It shows you the records where the city matches the value of lcCity. But if you want it to be Seattle every time, you might try using the following:
INDEX ON city TAG city FOR city = &lcCity.
However, this code returns the error message:
Variable 'SEATTLE' is not found.
For this to work, you need to enclose the macro expression in quotes, as follows:
INDEX ON city TAG city FOR city = "&lcCity."