Commands and Statements

Command READ Foundation

Activates editing mode for the current Get objects.

The option SAVE causes the GetList array to be retained at the end of the READ command. This allows the Get objects in the array to be edited again by a later call to READ. If this option is not specified, an empty array is assigned to the GetList array when the READ terminates, and all Get objects within the array are lost.

The dialog command READ activates the Xbase++ Get system and handles keyboard input, events and cursor navigation during data entry by the user. Data input occurs using Get objects which are contained in the array GetList. The command @...GET creates Get objects and adds them to the array referenced by the variable GetList. If no array GetList is declared, Get objects are added to the array referenced by the default variable GetList, which is implicitly declared as PUBLIC.

The command READ is translated by the preprocessor as a call to the function ReadModal(). This function is passed the array referenced by the variable GetList. This array contains all Get objects created by the command @...GET and added to the GetList array since the last execution of one of the commands CLEAR, CLEAR ALL, CLEAR GETS or READ.

Global definition of Get objects is possible using the array GetList. This array forms the basis for the Xbase++ Get system. GETSYS.PRG contains the source code for the Get system. A detailed description of the Get system and a description of interactive data input using the commands @...GET and READ can be found in the discussion of the function ReadModal().

During the execution of READ, the user can move between entry fields (Get objects). Each time the user changes the entry field, data validation can be performed. If the WHEN option of the @...GET command specifies a condition, the corresponding Get object receives input focus only when this condition returns the value .T. (true). If this condition is specified and does not return the value true, the data buffer of this Get object cannot be edited and input focus is set to the next Get object. If the VALID or RANGE options of the @...GET command are used to specify a validation condition, the validation condition must return the value .T. (true) for the active Get object to lose input focus. If the data validation fails, the Get object can be exited only by using the Esc key, which discards the data input as invalid. If valid data is entered or if no validation condition is specified, the Get object can be exited using one of the termination keys listed in the table below. The Get object then loses input focus and the data in the edit buffer is assigned to the corresponding variable. If the edit buffer of any Get object is changed during the execution of the READ command, the function Updated() returns the value .T. (true).

The following table lists the keys processed during the READ command and the actions they cause:

Cursor navigation keys
Key Action
Left Arrow 1 character to the left
Right Arrow 1 character to the right
Ctrl+Left Arrow 1 word to the left
Ctrl+Right Arrow 1 word to the right
Up Arrow Previous GET
Down Arrow Next GET
Home First character
Ctrl+Home First character in the first GET
End Last character
Period | Comma Skip behind decimal point (only for numeric values)

Editing keys
Key Action
Delete Deletes character at the cursor position
Insert Turns insert mode on/off
Backspace Deletes character to the left of cursor
Ctrl+Backspace Deletes word to the left of cursor
Ctrl+T Deletes word to the right of cursor
Ctrl+Y Deletes characters from cursor to end of GET
Ctrl+U Resets the original value of the GET
ASCII characters Are placed in the edit buffer (dependent on PICTURE format)

READ termination keys
Key Action
Ctrl+W | Page Up | Terminates READ and stores the
Page Down Current GET value
Return Terminates READ (only for the last GET)
Esc Terminates READ and does not store the current GET value
Up Arrow Terminates READ (only on the first GET and when ReadExit() is .T.)
Down Arrow Terminates READ (only on the last GET and when ReadExit() is .T.)

Along with the keyboard, the mouse can be used for navigation. Mouse navigation must be activated by calling the function SetMouse(.T.). Movement from one entry field to another can occur when the user clicks the left mouse button in an entry field. If the VALID condition of the entry field being exited fails, or the WHEN condition of the clicked entry field fails, the new entry field is not activated.

The READ command can be nested if it is executed again in a user defined function or procedure specified by a SET KEY TO command or within the WHEN or VALID option of the @...GET command. For this to work correctly, a new empty GetList array must be declared in the UDF to hold the Get objects generated by @...GET. The edit mode is activated using another READ which edits the Get objects in the new GetList array. After the procedure terminates, the new GetList array is released and the original one is again visible.

When the mouse is activated for navigation using SetMouse(.T.), code blocks set with SetKey() or SET KEY TO are no longer evaluated. Instead, code blocks linked to specific events by SetAppEvent() are evaluated (see the function ReadModal()).

The READ command can be terminated at any time by executing BREAK, CLEAR, CLEAR ALL or CLEAR GETS in a user defined function or procedure. The function call can be specified by the SET KEY TO command or by the WHEN or VALID option of the @...GET command.

Instead of using the command READ, the function ReadModal( GetList, <nStartGet> ) can be called. This function call also allows specification of the entry field (Get object) to receive the input focus first. Normally, data input begins with the first Get object (GetList[1]).


// The example shows the procedure for creating a Get object using 
// @...GET and READ. Three variables can be edited. Each value is 
// automatically validated. 

   LOCAL cString := "String   " 
   LOCAL nNumber := 10 
   LOCAL dDate   := Date() 

   @ 5, 10 SAY "Character:" GET cString VALID .NOT. Empty(cString) 
   @ 6, 10 SAY "Number   :" GET nNumber RANGE 0, 100 
   @ 7, 10 SAY "Date     :" GET dDate   RANGE Date(),Date()+365 

Nested READ command
// The example shows how the READ command can be nested. 
// A new, empty GetList array is declared in a user 
// defined function. The UDF is called from the 
// VALID option. 

   LOCAL cDevice := "LPT1", lOk := .T. 

   @ 10,12 SAY     "Output to the printer [Y/N] ?" ; 
           GET     lOk ; 
           PICTURE "Y" ; 
           VALID   IIf( .NOT. lOK, ; 
                         GetFileName( @cDevice ), .T.) 
                                   // pass variable 
                                   // by reference 

   SET PRINTER TO (cDevice) 
   ? "Printer output to", cDevice 


FUNCTION GetFileName( cFileName ) 
   LOCAL GetList := {}             // declare new GetList array 
   LOCAL cBuffer := Space(12) 

   @ 11,12 SAY "Enter file name:" GET cBuffer 

   IF Updated() 
      cFilename := Trim( cBuffer ) 
RETURN .T.                          // new GetList array is 
                                    // released 

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.