Wiki Home

Scan For And Scan While


Namespace: VFP
Take a look at this code;
select myfile
locate for alltrim(myfile.field1)=stringx
scan for alltrim(myfile.field1)=stringx
    *process the file
    .....
    .....
endscan

No matter what I ve done to myfile, scan for ... endscan goes completely through the file,
top to bottom.
Now take a look at this code:
select myfile
locate for alltrim(myfile.field1)=stringx
scan while alltrim(myfile.field1)=stringx
   *process the file
   .....
   .....
endscan

Myfile is processed from the current record pointer to the end of the file.
Looks legit to me. The "REST" operand on the first will achieve what you get on the second.
The first example means process all records in the file where alltrim(myfile.field1) = stringx. The second example means find the first record where alltrim(myfile.field1) = stringx and then process matching records until the next non-matching record is found. In the first example, the locate for is redundant. The scan for does that for you. If you have an index on field1 and you SET ORDER to that tag, both processes will do the same thing. The question is do you want all matching records processed, or just the first few in the current index order? -- Mike Yearwood
The underlying issue is, so far as I can tell, not documented by Microsoft, but is easy enough to prove with a few minutes of testing. (I have inadvertantly proved it more than once when my code did not do what I intended it to do.) The default scope for the FoxPro SCAN command is documented to be "ALL", and indeed you can usually count on it to be "ALL" unless you specify otherwise. However, whenever you add the WHILE clause to SCAN, regardless of the contents of the WHILE clause, the default scope is changed to "REST".

This is significant if the cursor is not on the first row when you begin the SCAN:
If the cursor is, for instance, sitting on row 10, and you execute SCAN FOR, the SCAN returns every qualified row, including rows 1 through 9 if they are qualified.
On the other hand, if the cursor is sitting on row 10 and you execute SCAN WHILE, row 9 might be qualified but the SCAN will not pick it up; it acts as if you executed SCAN WHILE REST, and starts scanning at row 10. -- Ken Reeder
FOR and WHILE and REST override ALL. The two blocks of code will process the same set of records, neither of them processes the entire file. -- Mike Yearwood

I disagree that FOR overrides ALL. FOR will always start looking for the condition(s) from the top, and in the case of a non-optimized clause has to go to the end. -- Jim Nelson

Table.DBF
Field1 Field2
A 1
B 2
C 3

LOCATE FOR FIELD1 = "A"
DO WHILE FOUND()
  ?FIELD1
ENDDO

Results: A

LOCATE ALL
DO WHILE FOUND()
  ?FIELD1
ENDDO

Results: A, B, C

ALL means all records. FOR means records matching a condition. If the condition is unoptimized, it will look at all records but still only "return" the matching records. If the condition is optimized and you specify ALL, it does not look at all records. -- Mike Yearwood

Contributors Eduardo Díaz Guerrero, Mike Yearwood
Category Code Samples
( Topic last updated: 2006.08.11 11:55:13 PM )