VA FileMan V. 22.0 Programmer Manual Banner


Main Chapter Getting Started Manual Advanced User Manual

Classic VA FileMan API

^DIR: Reader

DIR is a general purpose response reader that can be used to issue a prompt, read input interactively, perform syntax checking on the input, issue error messages or help text, and return input in a processed form. Its use is recommended to standardize user dialog and to eliminate repetitive coding.

DIR is reentrant: A DIR call may be made from within a DIR call. To reenter DIR, use the NEW command to save the DIR array (NEW DIR) before setting input variables and making the second call.

Input and Output Variables (Summary)
Input Variables-Required

Required: First character of Piece-1 (first 3 characters for DD-type)

Read type
Optional: Subsequent characters of Piece-1 Input modifiers
Optional: Piece-2 Input parameters
Optional: Piece-3 INPUT transform
Input Variables-Optional
DA For DD-type reads, can specify entry from which to retrieve default value
DIR("A") Programmer-supplied prompt to override default
DIR("A",#) Array for information to be displayed before the prompt
DIR("B") Default response
DIR("L") For set-of-code fields: programmer-specified format to display codes.
DIR("PRE") Pre-validation transform
DIR("S") Screen for pointer, set-of-code, and list/range reads
DIR("T") Time specification to be used instead of DTIME
DIR("?") Help displayed when the user enters a single question mark
DIR("??") Help displayed when the user enters a double question mark
Output Variables-Always Returned
X Unprocessed user response
Y Processed user response
Output Variables-Conditionally Returned
Y(0) External form of response for set, pointer, list, and date
DTOUT Defined if the user times out
DUOUT Defined if the user entered an up-arrow
DIRUT Defined if the user entered an up-arrow, pressed the Enter/Return key, or timed out
DIROUT Defined if the user enters two up-arrows

Required Input Variables (Full Listing)

DIR(0) is the only required input variable. It is a three piece variable. The first character of the first piece must be defined (or first 3 characters for DD-type). Additional characters of the first piece and the second two pieces are all optional.

The first character of the first up-arrow piece indicates the type of the input to be read. The second piece describes parameters, delimited by colons, to be applied to the input. Examples are maximum length for free text data or decimal digits for numeric data. The third piece is executable M code that acts on the input in the same manner as an INPUT transform. The acceptable types are shown below:

DIR(0) (Summary)
DIR(0) Read Type PIECE-1 PIECE-2 PIECE-3
First Character (required) Subsequent Characters (optional) Format Executable M code (optional)
Date D A,O Minimum date:Maximum date:%DT code
End-of-Page E A -- --
Free-Text F A,O,U,r Minimum length:Maximum length code
List or range L A,O,C Minimum:Maximum:Maximum decimals code
Numeric N A,O Minimum:Maximum:Maximum decimals code
Pointer P A,O,r Global Root or #:DIC(0) code
Set of Codes S A,O,X,B Code:Stands for;Code:stands for; code
Yes/No Y A,O -- code
DD #,# A,O,r -- code
DIR(0) (Detailed Explanation)

Piece-1 of DIR(0) (Subsequent Characters are Optional):

The first up-arrow piece of DIR(0) can contain other parameters that help to specify the nature of the input or modify the behavior of the reader. These characters must appear after the character indicating type (or after the field number if it is a DD type). They are described below and examples are provided later in this section):


Indicates that nothing should be Appended to the programmer-supplied prompt DIR("A"), which is described below. If there is no DIR("A"), then no prompt is issued.


Only applies to a set of codes; indicates that the possible choices are to be listed horizontally after the prompt.


Only applies to list reads. The values returned in Y and the Y() array are Compressed. They are not expanded to include each individual number, rather, ranges of values are returned using the hyphen syntax. This is similar to the format in which the user can enter a range of numbers.

This flag is particularly useful when a user may select many numbers, for example, when decimals are involved. The call is much faster and the possibility of the local symbol table filling up with nodes in the Y() array is eliminated.


Indicates that a response is Optional. If this is not included, then a null response is not allowed. For DD type reads, the O is automatically included if the field in question is not a required field.


If users do not choose to accept the default response, they must type in their entire response. They will not get the "Replace-With" prompt, regardless of how long the default response is.


Only applies to free text reads. It allows the user response to contain ^ (Up-arrow). A leading up-arrow aborts the read and sets DUOUT and DIRUT whether or not U is in DIR(0). However, the U allows ^s to be embedded in the user response.


Only applies to the set of codes. Indicates that an eXact match is requested. No lowercase to uppercase conversion is to be done.

Piece-2 of DIR(0) (Optional)

Qualifying limits on user response are as described in the summary table above.

Piece-3 of DIR(0) (Optional)

The third piece of DIR(0) is executable M code that acts like the INPUT transform of a field in a data dictionary. The value that was entered by the user is contained in the variable X. The code can examine X and, if it is not appropriate, should KILL X. If X is undefined after the execution of the third piece of DIR(0), the reader knows that the input was unacceptable, issues a help message, and re-asks for input. It is unnecessary to put checks for minimum and maximum or length in the third piece. These should be specified in the second piece of DIR(0). An example of DIR(0) with all three pieces is:

    S DIR(0)="F^3:30^K:X'?.U X"

which says that if the input is not all uppercase, then the data is unacceptable. The check for a length from 3 to 30 characters takes place automatically because of the second piece. The third piece is not executed if the specifications in the second piece are not met. If the user combines the DD data type with a third piece in DIR(0), for example:

   S DIR(0)="19,.01^^K:X'?1""DI"" X"

then the third piece of DIR(0) is not executed until after the INPUT transform has been executed and X was not KILLed by the transform.

For pointer-type reads, the third piece of DIR(0) is executed after an entry is selected from the file.

Optional Input Variables (Full Listing)

(Optional) For DD-type reads only, if DIR("B") is not set, you may retrieve a value from the database to display as a default. Identify the entry from which the value should come by setting the DA variable to its record number. If a subfile is involved, set up a DA() array where DA equals the record number for the lowest level subfile, DA(1) for the next higher, and so on.

NOTE: Although you can retrieve defaults from the database by using DA, the values in the database are not changed by ^DIR calls.


(Optional) The reader provides a generic default prompt for each type, e.g., enter a number or enter response. To issue a more meaningful prompt, DIR("A") can be set to a character string that more clearly indicates the nature of the data being requested. For example, setting the following:

S DIR(0)="NA^0:5:2"

causes the prompt to appear as:


(Optional) If you want to issue a longer message before actually reading the input, you can set the DIR("A",#) array in addition to DIR("A"). The #'s must be numeric. After the array has been displayed, DIR("A") is issued as the prompt for the read. It is necessary for DIR("A") to be set if the programmer is to use this array. For example, setting the following:

S DIR("A",1)="Enter price data with two decimal points."
S DIR("A",2)="Cost calculations require this precision."

causes the following dialog to appear to the user:

    Enter price data with two decimal points.
Cost calculations require this precision.

(Optional) Set this variable to the default response for the prompt issued. It appears after the prompt and before the // (double slashes). If the user simply presses the Enter/Return key, the default response is accepted by the reader.


(Optional) Only applies to set-of-codes fields. Lets you replace the standard vertical listing of codes that the Reader displays with your own listing. It is up to you to ensure that the contents of the DIR("L") array match the codes in the second ^-piece of DIR(0).

The format of the DIR("L") array is similar to DIR("A") and DIR("?"). The #'s must be numeric starting from 1. The numeric subscripted array nodes are written first and the DIR("L") node is written last. For example, if you code:

    S DIR(0)="SO^1:ONE;2:TWO;3:THREE;4:FOUR;5:FIVE" 
S DIR("L",1)="Select one of the following:"
S DIR("L",2)=""
S DIR("L",3)=" 1 ONE 4 FOUR"
S DIR("L",4)=" 2 TWO 5 FIVE"
S DIR("L")=" 3 THREE"

the user sees the following:

    Select one of the following: 


Enter response:

(Optional) This variable contains M code that acts as a pre-validation transform. It can either change X, in which case the reader will proceed as though the user had entered the new value in X, or kill X, in which case the reader will behave as though the user entered an illegal value. DIR("PRE") is executed almost immediately after the READ takes place, just after DTOUT is set if the READ timed out, and before any other checking is done. The only inputs are X and DTOUT, and the only outputs are X and DTOUT.


(Optional) Use the DIR("S") variable to screen the allowable responses for pointer, set of codes, and list/range reads. This variable works as the DIC("S") variable does for ^DIC calls. Set DIR("S") equal to M code containing an IF statement. After execution, if $T is set to 1, the user response is accepted; if set to 0, it is not.

For pointer reads, when DIR("S") is executed, the M naked indicator is equal to the 0 node of the entry being screened. The variable Y equals its record number.

For set of codes reads, when the DIR("S") is executed, Y equals the internal code.

For list/range reads, if you also use the C flag in piece 1 of DIR(0), your output is still compressed. Internally during the call, however, the range must be uncompressed so that each number in the range can be screened. So using DIR("S") with the C flag during list/range reads loses the C flag's advantages in speed (but the C flag's advantage in avoiding storage overflows remains).


(Optional) Time-out value to be used in place of DTIME. Value is represented in seconds.


(Optional) This variable contains a simple help prompt which is displayed to the user when one question mark is entered. It usually takes the place of the reader's default prompt. For example, if you code:

    S DIR(0)="F^3:10"
S DIR("?")="Enter from three to ten characters"

the user sees the following:

    Enter from three to ten characters.

NOTE: When displayed, a period (.) is added to the DIR("?") string. Periods are not appended when displaying the DIR("?",#) array, however.

When one question mark is entered in DD reads, the data dictionary's help prompt is shown before DIR("?"). For pointer reads, a list of choices from the pointed-to file is shown in addition to DIR("?").

As an alternative, you can set DIR("?") to an up-arrow followed by M code, which is executed when the user enters one question mark. An example might be:

    S DIR("?")="^D HELP^%DTC"

Execution of this M code overrides the reader's default prompt. If DIR("?") is defined in this way (a non-null second piece), the DIR("?",#) array is not displayed.


(Optional) This array allows the user to display more than one line of help when the user types a single question mark. The first up-arrow piece of DIR("?") must be set for the array to be used. The second up-arrow piece of DIR("?") must be null, otherwise the DIR("?",#) array is ignored. The #'s must be numeric starting from 1. The numbered lines are written first, that is, first DIR("?",1), then DIR("?",2), etc. The last help line written is DIR("?"). These lines are the only ones written, which means that the reader's default prompt is not issued.


(Optional) This variable, if defined, is a two-part variable. The first up-arrow piece may contain the name of a help frame. The help processor displays this help frame if the user enters two question marks.

The second part of this variable (after the first up-arrow piece) may contain M code that is executed after the help frame is displayed.

For example:


NOTE: In order to use this variable, you must have Kernel's help processor on your system.

Output Variables (Full Listing)

This is the unprocessed response entered by the user. It is always returned. If the user accepts the default in DIR("B"), it is the default. If the user up-arrows out or just presses the Enter/Return key on an optional input, X is the up-arrow or null.


Y is always defined as the processed output. The values returned are:

Type Y Returned as
Date The date/time in VA FileMan format.
End-of-Page Y=1 for continue (user pressed the Enter/Return key).
Y=0 for exit (the user pressed up-arrow).
Y="" for time out (the user timed out).
Free-Text The data typed in by the user. In this case, it is the same as X.
List or range The list of numeric values, delimited by commas and ending with a comma.

If the C flag was not included in the first piece of DIR(0), an expanded list of numbers, including each individual number in a range, is returned. If the C flag was included, a compressed list that uses the hyphen syntax to indicate a range of numbers is returned.

Any leading zeros or trailing zeros following the decimal point are removed; i.e., only canonic numbers are returned. If the list of returned numbers has more than 245 characters, integer-subscripted elements of Y [Y(1), Y(2), etc.] contain the additional numbers. Y(0) is always returned equal to Y.
Numeric The canonic value of the number entered by the user; i.e., leading zeros are deleted and trailing zeros after the decimal are deleted.
Pointer The normal value of Y from a DIC lookup, that is, Internal Entry Number^Entry Name. If the lookup was unsuccessful, Y=-1.
Set of Codes The internal value of the response.
Yes/No Y=1 for yes.
Y=0 for no
DD (#,#) The first ^-piece of Y contains the result of the variable X after it has been passed through the INPUT transform of the field specified. Depending on the data type involved, subsequent ^-pieces may contain additional information.

The following list summarizes the values of Y upon timeout, up-arrows, or pressing the Enter/Return keys for all reads. Exceptions are noted.

Condition Value of Y Comments
Timeout Y="" --
Up-arrow (^) Y=^ in all cases except end-of-page reads.
Y=0 upon end-of-page reads. --
Double Up-arrow (^^) Y=^^ in all cases except end-of-page reads.
Return Y="" for optional reads (reads allowing a null response).
Y=-1 for pointer reads.
Y=0 for YES/NO type when NO is default.
Y=1 for YES/NO type when YES is default.
Y=1 for end-of-page reads.
Y=default when a default is provided other than for YES/NO type questions.

This is defined for the set of codes, list, pointer, date, and Yes/No reads. It is also returned for DD reads when the field has a set of codes, pointer, variable pointer, or date data type. It holds the external value of the response for set of codes or Yes/No, the zero node of the entry selected for a pointer, and the external date for a date and variable pointer. To have Y(0) returned for pointer-types, the DIC(0) string in the second piece of DIR(0) must contain a Z, for example:


For list reads, it contains the same values as the Y variable. There may be additional nodes in the Y() array depending on the size of the list selected by the user.


If the read has timed-out, then DTOUT is defined.


If the user entered a leading up-arrow, DUOUT is defined.


If the user enters a leading up-arrow, times out, or enters a null response, DIRUT is defined. A null response results from pressing the Enter/Return key at a prompt with no default or entering the at-sign (@), signifying deletion. If, however, the user presses the Enter/Return key in response to an end of page read, DIRUT is not defined. If DIRUT is defined, the user can enter the following common check to quit after a reader call:


If the user entered two up-arrows, DIROUT is defined.


Date Example

S DIR(0)="D^2880101:2880331:EX"

This tells the reader that the input must be an acceptable date. To determine that, ^%DT is invoked with the %DT variable equal to EX. If the date is a legitimate date, then it is checked to see if the date falls between January 1, 1988 and March 31, 1988. In general, both minimum and maximum are optional. If they are there, they must be in VA FileMan format. The only exceptions are that NOW and DT may be used to reference the current date/time.Remember that NOW contains a time stamp. If it is used as a minimum or maximum value, an R or T should be put into the %DT variable.

If DIR(0) is set up to expect a time in the response, you can help the user by including that requirement in the prompt. Otherwise, a response without a time stamp (such as TODAY) might unexpectedly fail.

End-of-Page Example

S DIR(0)="E"

There are no parameters. Enter/Return and up-arrow are the only acceptable responses. This DIR(0) setting causes the following prompt to be issued:

    Press the return key to continue or '^' to exit:

Free-Text Example

S DIR(0)="F^3:30"

This tells the reader that the input must be alphanumeric or punctuation, (control characters are not allowed) and that the length of input must be no fewer than 3 and no more than 30 characters. The maximum acceptable length for a free-text field is 245 characters.

NOTE: A leading up-arrow always aborts the read and sets DIRUT or DUOUT.

With DIR(0) containing U

S DIR(0)="FU^3:30"

The user can enter any response that is from 3 to 30 characters long. The response can contain embedded up-arrows. Without U, an embedded up-arrow causes the user to receive an error message.

With DIR(0) containing A

    S DIR(0)="FA^2:5",DIR("A")="INITIAL"

The prompt is set only to the word INITIAL. If the A were not included, a colon and space would be appended to the prompt and it would look like this:


List or Range Example

S DIR(0)="L^1:25"

This tells the reader that the input may be any set of numbers between 1 and 25. The numbers may be separated by commas, dashes, or a combination of both. Two acceptable responses to the example above are:


Remember that this is a numeric range or list. It can only contain positive integers and zero (no negative numbers).

With DIR(0) containing C

    >S DIR(0)="LC^1:100:2" D ^DIR

    Enter a list or range of numbers (1-100): 5,8.01,9-40,    
>ZW Y Y=5,7.03,8.01,9-40,45.9,80-100, Y(0)=5,7.03,8.01,9-40,45.9,80-100,

Here the user can enter numbers from 1 to 100 with up to two decimal places. The C flag tells the reader not to return each individual number in Y. Instead, inclusive ranges of numbers are returned. In this case, without the C flag, 137 subscripted nodes of the Y( ) array would be returned; the call would be very slow and might cause an error if the size of the Y( ) array exceeded local storage.

Numeric Example

S DIR(0)="N^20:30:3"

This tells the reader that the input must be a number between 20 and 30 with no more than three decimal digits.

NOTE: If no maximum is specified in the second ^-piece, the default maximum is 999999999999.

With DIR(0) containing O

    S DIR(0)="NO^0:120",DIR("A")="AGE"

This allows the user to press the Enter/Return key without entering any response and leave the reader. Without the O, the following messages appear:

    This is a required response.  Enter '^' to exit.

Pointer Example

S DIR(0)="P^19:EMZ"

This tells the reader to do a lookup on File 19, setting DIC(0)="EMZ" before making the call.

If the user enters a response that causes the lookup to fail, the user is prompted again for a lookup value.

A pointer read can be used to look up in a subfile. In that case, the global root must be used in place of the file number. For example, to look up in the menu subfile (stored descendent from subscript 10) for entry #2 in File 19:

   S DIR(0)="P^DIC(19,2,10,:QEM"

Remember to set any necessary variables, e.g., DA(1).

Set Example


This tells the reader to only accept one of the two members of the set. The response may be 1, 2, MARRIED, or SINGLE. When DIR("A") is included without the A modifier on the first piece, the prompting is done as follows:


Select one of the following:

With DIR(0) containing A

S DIR("A")="SEX: " D ^DIR

Whereas, with the A, it would appear as follows:


With DIR(0) containing B


When this is executed, instead of getting the vertical listing as shown above, the prompt would appear as:

    SEX: (M/F):

With DIR(0) containing X

S DIR("A")="SEX"

This would cause a lowercase M or F to be rejected. The prompting is done as follows:

    Select one of the following:
M Male
F Female
SEX: f (user's response)
Enter a code from the list.

Yes/No Example

S DIR(0)="Y",DIR("B")="YES" 

This tells the reader that the response can only be Yes or No. When using DIR("B") to provide a default response, spell out the entire word so that when the user presses the Enter/Return key to accept the default, echoing functions properly.

DD Example

S DIR(0)="19,1"

This format is different from the others in that the first number is a file number and the second is a field number in that file. The reader uses the data dictionary for field 1 in file 19 and issues the label of that field as the prompt. The input is passed through the INPUT transform in the dictionary. Help messages are also the ones contained in the dictionary for this field.

Normally, DD reads based on a free text field do not allow embedded up-arrows. However, if the field specified is positioned on the data node using the Em,n format (instead of the ^-piece format), up-arrows embedded in the user's response are accepted. (See the "Field Global Storage" section of the Advanced File Definition chapter for an explanation of locating fields on the data node.) Initial up-arrows abort the read and set DIRUT and DUOUT.

It is not possible to use this format if the field defines a subfile, i.e., the second piece of the zero node of the field definition contains a subfile number. To use the reader for a field in a subfile, do the following:

    S DIR(0)="Subfile#,field#"

It is the programmer's responsibility to set any variables necessary for the INPUT transform to execute correctly.

Always NEW or KILL DA before doing a DD type DIR call, unless you wish to use the default feature. The default feature allows you to retrieve default values from the database for DD reads by setting DA (or the DA array for subfiles) equal to the record number containing the desired default value.


Reviewed/Updated: October 2016