Statement DO WHILE Foundation
Executes a program loop until a condition evaluates to .F. (false).
[DO] WHILE <lExpression>
<SourceCode>...
[EXIT]
<SourceCode>...
[LOOP]
<SourceCode>...
END[DO]
The control structure DO WHILE...ENDDO defines a block of statements which is executed repeatedly until the logical expression <lExprssion> evaluates to .F. (false). As soon as the program encounters the ENDDO statement, it begins again with the statement DO WHILE and reevaluates the condition<lExpression>. If a LOOP statement is executed within the loop, the loop begins again immediately without the code between LOOP and ENDDO being executed. The loop can be exited immediately with the EXIT statement, without <lExpression>being evaluated again. In this case, the program continues at the first executable line following ENDDO.
DO WHILE loops can be nested to any depth, and other control structures can be used within them. An exception is BEGIN SEQUENCE in connection with the RECOVER statement: no LOOP or EXIT statement is permitted between BEGIN SEQUENCE and RECOVER.
// The example shows a simple print program which
// outputs address labels to a text file with "?".
// All records are read until the end of the file is reached.
PROCEDURE Main
USE Customer NEW
INDEX ON Upper(Customer->LastName + Customer->FirstName) ;
TO CustA
SET PRINTER ON
SET PRINTER TO Label.txt
DO WHILE .NOT. Eof()
? Trim( Customer->Salutation )
?? Trim( Customer->FirstName ) + " " + ;
Trim( Customer->LastName )
? Trim( Customer->Street )
? Trim( Customer->City ) + ", " + Customer->State + " " + ;
Customer->ZIP
EJECT
SKIP
ENDDO
SET PRINTER OFF
SET PRINTER TO
CLOSE Customer
RETURN
// The example shows a continuous loop such as might be used in the main
// procedure of an application. In this case, a menu is displayed by
// which a user can branch to different parts of the application.
PROCEDURE Main
LOCAL nMenuItem
DO WHILE .T. // Continuous loop
CLS
@ 2, 1 PROMPT " DBF file "
@ 4, 1 PROMPT " NTX file "
@ 6, 1 PROMPT " Search "
@ 8, 1 PROMPT " Quit "
MENU TO nMenuItem
SetPos( 0, 0 )
DO CASE
CASE nMenuItem == 1
? "Selects DBF file"
CASE nMenuItem == 2
? "Selects index file"
CASE nMenuItem == 3
? "Searches data records"
CASE nMenuItem == 4
EXIT // exits loop
OTHERWISE
nMenuItem := Alert( "Exit program?", ;
{" Yes "," No " } )
SetPos( 0, 0 )
DO CASE
CASE nMenuItem == 0
LOOP // Back to the beginning
CASE nMenuItem == 1
EXIT // Exits loop
CASE nMenuItem == 2
? "Continue program" // Normally continues
ENDCASE
ENDCASE
? "Press a key..."
Inkey(0) // Wait...
ENDDO
RETURN
// In this example, two user-defined commands are used to form a
// DO WHILE loop. The logical expression which causes an exit condition
// is tested at the end of the loop and not, as with DO WHILE, at
// the entrance to the loop. The loop is exited when the loop
// condition evaluates to .T. (true).
#command REPEAT => DO WHILE .T.
#command UNTIL <lExpr> => IF <lExpr> ;;
EXIT ;;
ENDIF ;;
ENDIF
#include "Inkey.ch"
PROCEDURE Main
LOCAL nKey := 0
REPEAT
? "Last pressed key has Inkey() Code:", nKey
nKey := Inkey(0)
UNTIL nKey == K_ESC
RETURN
If you see anything in the documentation that is not correct, does not match your experience with the particular feature or requires further clarification, please use this form to report a documentation issue.