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.
ASCAN()
This function searches for a specified value in an array. It returns the element number if the value is found and 0 otherwise.
nResult = ASCAN( ArrayName, uExpression [, nStart
[, nNumElems [, nColumn [, nFlags ] ] ] ] )
Parameter |
Value |
Meaning |
ArrayName |
Array Name |
The array in which to search. |
uExpression |
Any type except Memo, General, Picture, Screen or Object |
The item for which to search. |
nStart |
Numeric |
The element with which to start searching. |
–1 or omitted |
Search the entire array. |
|
nNumElems |
Numeric |
The number of elements starting with nStart to search. |
–1 or omitted |
Search all elements beginning with nStart. |
|
nColumn |
Numeric |
Search only the specified column. If nStart is specified, search the column starting with the specified element. If nNumElems is specified, search the column only until the specified number of elements beginning with nStart have been searched. Note that both nStart and nNumElems refer to elements of the entire array, not just the specified column. |
–1 or omitted |
Search all columns. |
|
nFlags |
Numeric |
Modifies the search or the result. See the table below. |
nResult |
Positive number |
If nFlags does not include 8 or the array is one-dimensional, the element number of the first element (starting from nStart) where uExpression can be found. If nFlags includes 8 and the array is two-dimensional, the row number of the first element (starting from nStart) where uExpression can be found. |
0 |
uExpression can't be found in the specified part of aArray. |
As with ASORT()
, to specify the number of elements, you also specify the starting element. nStart is an element number—use AELEMENT()
to convert from row, column format.
This function was significantly enhanced in VFP 7, adding several long-desired capabilities. The first is the ability to search a particular column. Prior to VFP 7, it was easy to search a single row, but searching a column required lots of code. (If you need that code, see the earlier versions of this book.) Now, it takes just a single parameter.
The nFlags parameter adds several capabilities: case-insensitive searching, the ability to control partial matching at the function level, and the ability to return the row number rather than the element number. (We can’t tell you how often we’ve forgotten to apply ASUBSCRIPT()
to the result of ASCAN()
.)
Like pretty much every function parameter called nFlags, this one is additive. You choose the items you want, and add the specified values together to get a single value that you pass. (If you’re into binary, think of each choice as a bit.)
At present, there are four options, as follows:
Value |
Meaning |
1 |
Make search case-insensitive. |
2 |
Set EXACT on locally. Applies only if 4 is also added to nFlags. |
4 |
Control EXACT locally. |
8 |
Return the row number. |
The business with controlling EXACT definitely calls for explanation. By default, ASCAN()
uses the current EXACT setting. So, previously, to be sure to do an exact search (rather than partial matching of strings), you had to SET EXACT
ON before ASCAN()
and reset it to its previous value afterwards. The exactness flags let you control EXACT for just the individual function call. To do so, you must add 4 to the nFlags value—that says the function is in control. Then, either add 2 to specify EXACT ON or add 0 to specify EXACT OFF.
DIMENSION a2DTest[5, 3]
* Fill array with nums 101 to 115.
FOR nCnt = 1 TO 15
a2DTest[ nCnt ] = nCnt + 100
ENDFOR
? ASCAN(a2DTest, 105) && Returns 5
? ASCAN(a2DTest, 100) && Returns 0
? ASCAN(a2DTest, 102, 4) && Returns 0 because 102 doesn't appear
&& When starting from element 4
? ASCAN(a2DTest, 107, 4, 5) && Returns 7
? ASCAN(a2DTest, 108, -1, -1, 2) && Returns 8
? ASCAN(a2Dtest, 108, -1, -1, 2, 8) && Returns 3
OPEN DATABASE HOME(2) + "TasTrade\Data\TasTrade"
* Get relation information
ADBOBJECTS( aDB, "RELATION")
SET EXACT OFF
? ASCAN( aDB, "PROD" ) && Returns 2
SET EXACT ON
? ASCAN( aDB, "PROD" ) && Returns 0
SET EXACT OFF
* Now control exactness locally
? ASCAN( aDB, "PROD", -1, -1, -1, 4) && Exact off, returns 2
? ASCAN( aDB, "PROD", -1, -1, -1, 6) && Exact on, returns 0
* Now case-insensitive
? ASCAN( aDB, "prod" ) && Returns 0
? ASCAN( aDB, "prod", -1, -1, -1, 1) && Returns 2
* Combine case-insensitive and return row
? ASCAN( aDB, "prod", -1, -1, -1, 9) && Returns 1