Steps through each record in the current table, executing specified statements on each record that meets specified conditions.


SCAN [<scope>] [FOR <condition 1>] [WHILE <condition 2>]


FOR <condition 1>
WHILE <condition 2>

The scope of the command. The default scope is ALL.


Statements to execute for each record visited.


A required keyword that marks the end of the SCAN loop.


Use SCAN to process the current table record by record. With no scope options, SCAN starts with the first record in the table in the current index order and visits all the records, stopping at the end-of-file. You may specify a different <scope> and a WHILE condition to control the range of records, and a FOR condition that each record must pass for the <statements> to be executed.

At the end of each loop, dBASE Plus. automatically moves the record pointer forward one record in the table before returning to the beginning of the loop; therefore, don't include a SKIP command. You may use the EXIT command to exit out of the loop and the LOOP command to go to the next record, skipping all remaining commands in the loop.

You may nest SCAN loops, except that you cannot nest SCAN loops for the same table.

SCAN works like a DO WHILE .NOT. EOF( )...SKIP...ENDDO construct; however, with SCAN you can specify conditions with FOR, WHILE, and <scope>. SCAN also requires fewer lines of code than DO WHILE.

When using SCAN with an indexed table, don't change the value of a field that is (or is part of) the master index key. When you change the value of such a field, dBASE Plus repositions the record in the index file, which might cause unintended results. For example, if you change a key field that causes its record to move to the end of the index, that record might have the SCAN...ENDSCAN statements executed on it a second time.

If you change work areas within a SCAN loop, select the work area containing the table being scanned before control passes back to the first statement in the SCAN loop.


This example opens a table named FOO and traverses all the records, copying the value of the character field C1 to a throw-away variable, using a SCAN loop and the OODML equivalent:

use FOO


x = C1 



local q, r

q = new Query( "select * from FOO" )

r = q.rowset

if r.first( )


x = r.fields[ "C1" ].value 

until not ) 



A "SELECT * FROM" query is equivalent to a plain USE command.

A reference to the query’s rowset is assigned to another variable as shorthand. It also executes a bit quicker.

A SCAN—without any scope qualifiers like REST or NEXT—always starts at the beginning of the table, so a call to the first( ) method is needed.

If first( ) returns false, there’s nothing to do

A DO...UNTIL loop is used so that the navigation happens after processing the current row. Since the first( ) method returned true to get into the loop, there must be at least one row to process.

When next( ) returns false, you’ve hit the EOF, which terminates the loop.