Logo

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.

Locate, Continue

These commands let you look for data in a record. You can search based on as many fields as you want. Unlike SEEK, you don’t need an index on the field or fields of interest. But if the right indexes exist, Rushmore can make this command as fast as greased lightning.

Usage

LOCATE [ FOR lForCondition ]
       [ Scope ]
       [ WHILE lWhileCondition ]
       [ NOOPTIMIZE ]
CONTINUE

For several generations of Xbase, LOCATE was one of those commands you never wanted to use. It was slooooow. Then, along came Rushmore and suddenly, not only was LOCATE usable again, it was cool.

With no Scope or WHILE clause, LOCATE finds the first record in the table that meets lForCondition. When Scope is included, only the records in the specified scope are searched and the record pointer lands up on the first matching record in the scope. WHILE behaves as it always does, short-circuiting the command as soon as a nonmatching record is found.

In spite of the documentation, the FOR clause is optional. Issuing a bare LOCATE moves the record pointer to the first visible record—that is, the first record that meets the current filter conditions. This is a much faster way of moving to the first record than issuing GO TOP when there’s a filter in use or DELETED is on.

CONTINUE continues the search—that is, it finds the next matching record.

When a match is found, FOUND() becomes .T. If no match is found, FOUND() returns .F. If no Scope or WHILE is included and SET NEAR is OFF, a failed search also leaves the record pointer at end-of-file and EOF() set to .T.

Example

USE Customer
* Find all customers in Germany for whom we have a fax number
LOCATE FOR UPPER(Country) = "GERMANY" AND NOT EMPTY(Fax)
DO WHILE FOUND()
   * do something with the record
   CONTINUE
ENDDO

As mentioned above, LOCATE is Rushmore optimizable. The example is optimized only if there are index tags for UPPER(Country) and Fax. (You can replace the LOCATE/DO WHILE/CONTINUE loop in this example with a SCAN WHILE loop, which is optimizable under the same conditions.)

Don’t use LOCATE in applications unless the condition is optimizable, at least partially, or the table or cursor has relatively few records. Consider adding indexes to take advantage of Rushmore. Otherwise, without Rushmore, LOCATE examines every single record in turn.

See Also

EOF(), Found(), Go, Seek, Seek(), Set Filter