This appendix describes certain features of User Language which, while still supported, are generally considered obsolete. They have been superseded by other, more efficient features or techniques. Rocket Software does not recommend using these features in newly written requests and procedures.
Rocket Software strongly recommends that you use statement labels (see Statement labels) rather than statement numbers. Although statement numbers are still supported, this section is included primarily as documentation for applications developed using earlier releases of Model 204.
The setting of the FOPT (File Options) parameter determines whether procedures within a file must be labeled or numbered.
Rules for using statement numbers
The rules for specifying statement numbers in User Language statements are summarized below.
- A statement number is made up of the digits 0-9 and an optional period (.). The number must begin with a digit and cannot contain blanks, although blanks preceding or following it are optional.
- A statement number can start in any column up to but not including column INCCC.
- Any statement can be numbered, but some statements must be numbered. In particular, a statement must be numbered if:
It immediately follows a STORE RECORD or a FIND statement, in which case the statement number indicates the end of the preceding statement.
It is referred to by later statements. In most requests, COUNT RECORDS IN n, COUNT RECORD ON LIST m, NOTE, FIND, FOR EACH VALUE, and FOR EACH OCCURRENCE are referred to later and should therefore be numbered.
It is the first statement after a loop, in which case a number is needed to indicate the end of the loop. An END statement following a loop does not require a number.
It is the statement following a THEN or ELSE clause which is to be executed if the condition is false.
- The retrieval conditions of a FIND statement, the subexpressions of an IF statement, and the fields of a STORE RECORD statement must not be numbered, even if they start new lines.
- A statement number can have any number of parts, which are delimited by periods. Thus, 2.3 and 0.1 are two part numbers, and 0.05.4 is a three part number.
- A period (.) following a statement number is optional, but the periods separating the parts are required.
are both legal and are interpreted as the same number.
This rule also applies when referring to statements by number. Thus:
FOR EACH RECORD IN 1.
FOR EACH RECORD IN 1
refer to the same statement.
- Any part of a statement number can be arbitrarily large.
- The number of parts in a statement number must be the same as the level on which the statement is nested. For example, the following sequence is illegal because 2.1.1 has three parts but is nested at the second level:
2. FOR EACH RECORD IN 1 2.1.1 PRINT ALL INFORMATION
- If a statement is not numbered, it is assigned a default level of nesting. The default level is the same as the level of the previous statement. If there is no previous statement, the default is the first level. If the previous statement starts a loop or a THEN, ELSE, or ELSEIF clause, or is a SUBROUTINE statement, the default level is one greater than the level of the previous statement.
- Any part of a statement number can have leading zeros. However, a number with leading zeros is not equivalent to one without. Thus 01 and 1 are both legal but not equivalent; the same is true of 1.1 and 1.01.
- Statements need not be numbered in sequential order. The statement number is just a label for the statement; its numerical value has no significance.
The following, for instance, is a legal request:
BEGIN 3. FIND ALL RECORDS FOR WHICH COMPANY = ROCKET 1. FOR EACH RECORD IN 3. 3.1 PRINT ALL INFORMATION 2.6. SKIP 1 LINE END
- Within a request, statement numbers should be unique. If not, Model 204 prints the message:
M204.0223: STATEMENT LABEL MULTIPLY DEFINED
This is a warning message; the request can still be run.
- A statement number followed by a label is allowed with or without a space between the number and the label. If a statement number is followed by a label and there is no space between them, User Language separates them into statement number and label. Although a statement number can be followed by a label, it is strongly recommended that you avoid placing statement numbers and labels on the same line.
The following request addresses an automated library card catalogue. Each record in the file contains information that would normally appear on a single card in the catalogue, such as AUTHOR, TITLE, SUBJECT, and CATALOGUE NUMBER.
BEGIN 1. FIND ALL RECORDS FOR WHICH AUTHOR = PAULING 2. FOR EACH RECORD IN 1 2.1 NOTE SUBJECT 2.2 FIND ALL RECORDS FOR WHICH SUBJECT = VALUE IN 2.1 2.3 FOR EACH RECORD IN 2.2 2.3.1 PRINT TITLE 3. COUNT RECORDS IN 1 PRINT COUNT IN 3 END
The following request uses a subroutine to validate full-screen input entries. A screen named DATA is defined with input areas named ITEM6, ITEM7, etc. Values entered during the READ SCREEN statement are validated one at a time by subroutine 900. Each screen item is assigned to the argument variable %A before the subroutine is called. If the item fails the validation, the subroutine sets %TAG to a nonzero value before returning. The request sets a tag on the screen for each incorrect item. The REREAD statement is issued if a screen item fails the validity tests.
BEGIN SCREEN DATA . . . END SCREEN READ SCREEN DATA NO REREAD *VALIDATE DATA ITEMS 1. %A = %DATA:ITEM6 CALL 900 IF %TAG THEN TAG %DATA:ITEM6 2. %A = DATA:ITEM7 CALL 900 . . . 50. IF $chktag('DATA') THEN REREAD SCREEN DATA JUMP TO 1 51. *PROCESS DATA . . . *SUBROUTINE TO PERFORM VALIDATION BY TABLE LOOKUP * IN: %A VALUE * OUT: %TAG NONZERO IF INVALID 900. SUBROUTINE . . . END
The $Dscr function interprets its character string argument as a field name. It returns a variable-length character string describing the specified field.
New application development should incorporate $FDef that supplanted the $Dscr function. The following discussion is provided to maintain existing code.
Each letter in the returned string represents a particular field attribute.
|P||UPDATE IN PLACE|
How $Dscr works
When $Dscr is invoked in file context, the returned string represents the description of the specified field in the current file.
Each letter that appears in the return value corresponds to an attribute in the field description. For example, if K is one of the letters in the returned string, then the field is KEY.
If a particular letter does not appear in the result of a $Dscr call, then the corresponding attribute does not apply, or the attribute's opposite is in effect. For example, if
M (many-valued) does not appear, the field is NON-CODED and NON-FRV, in which case
M does not apply, or it is FEW-VALUED. You can resolve this by looking for
F in the returned string.
When $Dscr is invoked in group context, the returned string represents a composite description of the field in all of the files of the current group. Some of the letters imply that the corresponding field attribute is present in all of the files in the group; others imply that the attribute is present in some (at least one) file in the group. If the field specified as the $Dscr argument is not defined in the current file or group, $Dscr returns the character string
U (undefined). The following table lists the individual letters and their meanings in group context.
|A||ORDERED CHARACTER in some|
|C||CODED in all|
|D||DEFERRABLE in some|
|F||FRV in some|
|I||INVISIBLE in all|
|K||KEY in all|
|L||LEVEL in some|
|M||MANY-VALUED in all|
|N||ORDERED NUMERIC in some|
|O||OCCURS in some|
|P||UPDATE IN PLACE in some|
|Q||UNIQUE in some|
|R||NUMERIC RANGE in all|
|S||Not BINARY in any|
|T||FLOAT in some|
|W||AT-MOST-ONE in all|
This request determines the attributes of a field and performs one of three types of searches, depending on the results of $Dscr.
BEGIN %A = $READ ('FIELD NAME') %B = $READ ('FIELD VALUE') %C = $DSCR (%A) IF %C EQ 'U' THEN PRINT 'ILLEGAL FIELD' JUMP TO STOP END IF *CHECK FOR NON-KEY IF $INDEX (%C, 'K') EQ 0 THEN JUMP TO NUM.RNG.CHK END IF FIND AND PRINT COUNT %%A = %B END FIND JUMP TO STOP *CHECK FOR NUMERIC RANGE NUM.RNG.CHK: IF $INDEX (%C, 'R') EQ 0 THEN JUMP TO ALL.RECS END IF FIND AND PRINT COUNT %%A IS %B END FIND JUMP TO STOP *NEITHER KEY FOR NUMERIC RANGE ALL.RECS: FIND ALL RECORDS END FIND FOR EACH RECORD IN ALL.RECS IF %%A = %B THEN PLACE RECORD ON LIST OK END IF END FOR OKS: COUNT RECORDS ON LIST OK PRINT COUNT IN OKS STOP: END END