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.
These are two of the original commands in the Xbase language, useful for jumping to specific records while working interactively, but other commands have replaced their utility within programs in most cases.
[ GO | GOTO ] [ RECORD ] nRecordNumber | TOP | BOTTOM
[ IN nWorkArea | cAlias ]
Yes, you read the syntax diagram above correctly. This is the only command in the language where the command itself is optional. Type a record number all by itself into the command window, and the record pointer moves there. This trick works only with record numbers, and does not support the new IN syntax. Issuing just the record number works in programs, as well, but add the optional GO to keep from confusing people. Lines like:
&cRecNo
won’t make sense to many people. The keywords TOP and BOTTOM go to the first and last records, respectively, in the current index order, or in the natural record order if the table doesn’t have a current active index, obeying any filter in place. The IN clause allows you to move the record pointer in another area by specifying either the work area number or the alias of the table open in that area.
GO is not Rushmore-optimizable. Rather than using GO TOP or BOTTOM, use LOCATE instead—see the trick to it in “Faster Than a Speeding Bullet.”
Many of us have used the trick of storing the record number to a memory variable, doing some processing, and then restoring the record pointer to its original position with GO. This still works fine in Visual FoxPro, but a common extension of the trick may not. If the record pointer was at the “phantom record,” beyond the last true record in the file, issuing GO (nRecNo) would result in a “Record is out of range” error, so the trick was to store –1 as the record number if the record pointer was at the end of the file, and place the record pointer back there if so. This is a clever trick, but beware: If you are working on tables with table buffering enabled, Visual FoxPro actually does use negative record numbers for uncommitted buffered records. Consider using 0 (zero) instead.
VFP 7 Service Pack 1 fixes a bug that crashes VFP: using GOTO to move to a buffered record in a view for which you've created an index. That's a fairly obscure situation—in fact, we only heard of this when we saw it on the list of bugs fixed in the service pack. |
nRecNo() = IIF( EOF(), 0, RecNo() )
* Do your processing here
CASE RECCOUNT() = 0
* DO NOTHING
CASE nRecNo = 0
GO BOTTOM
SKIP
OTHERWISE
GO (nRecno)
ENDCASE
SKIP [ nHowMany ] [ IN nWorkArea | cAlias ]
SKIP is used to move the record pointer manually a specified number of records. Like many commands that depend on the actual physical ordering of records, this command used to be far more popular than it needs to be today. If your applications require you to do a lot of SKIPping around, you may need to review your database schema for design problems.
nHowMany can specify a positive or negative number, and the record pointer is moved by that many records. Usually, this movement takes place in the current table and work area, but there are two situations under which it will occur in another area. The first is illustrated in the syntax diagram above, where a table alias or work area number is explicitly given. The second is the case where there is a SET SKIP
in effect. SET SKIP
defines a one-to-many relationship where skipping takes place in the child (many) side of the relation, and the parent record pointer is moved if necessary to match that of the child.
SKIP is not Rushmore-optimizable. Even in the case of large tables with complex indexes, FoxPro can usually buffer enough of the table that the slowdown is not obvious, but in repetitive processes, the deficit can become apparent. Use SCAN … ENDSCAN if a large number of records need to be processed, or even a LOCATE and CONTINUE pair of commands rather than slogging through the whole file.
SKIP -2 && Go back two records