Using variables and values in computation: Difference between revisions
No edit summary |
m (→Declaring %variables and %variable arrays: insert ID) |
||
(46 intermediate revisions by 7 users not shown) | |||
Line 1: | Line 1: | ||
===Overview | <div class="toclimit-3"> | ||
<p> | |||
<p>You can declare %variables for a single value or as an array. For the purposes of discussing | ==Overview== | ||
<p> | |||
<p>In addition to the basic %variables (and variable arrays) discussed in this | SOUL lets you use variables to represent values. You can use a SOUL variable, called percent variable (%variable), because variable names must start with a percent sign, any place in a SOUL statement that requires a value.</p> | ||
<p> | |||
You can declare %variables for a single value or as an array. For the purposes of discussing SOUL, the term %variable is used to mean both a %variable and an element of a %variable array. | |||
The features discussed in this article enable you to generate additional information based on data in the file.</p> | |||
===Special types of variables=== | |||
<p> | |||
In addition to the basic %variables (and variable arrays) discussed in this article, SOUL provides the following types of variables:</p> | |||
<table> | <table> | ||
<tr class="head"> | <tr class="head"> | ||
Line 9: | Line 16: | ||
<th>See...</th> | <th>See...</th> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>Field name </td> | <td>Field name </td> | ||
<td> [[#Field name variables|Field name variables]]</td> | <td> [[#Field name variables|Field name variables]]</td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>Screen variables </td> | <td>Screen variables </td> | ||
<td>[[Full- | <td>[[Full-screen feature#Full-screen variables|Full-screen variables]]</td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>Image variables </td> | <td>Image variables </td> | ||
<td>[[Images#Defining image items|Defining image items]] and the sections that follow describing types of images</td> | <td>[[Images#Defining image items|Defining image items]] and the sections that follow describing types of images</td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>%Variables as parameters </td> | <td>%Variables as parameters </td> | ||
<td>[[Flow of | <td>[[Flow of control in User Language]]</td> | ||
</tr> | </tr> | ||
</table> | </table> | ||
<p>You can specify | ===Values=== | ||
<p> | |||
You can specify SOUL values by using:</p> | |||
<ul> | <ul> | ||
<li>Literals (quoted strings)</li> | <li>Literals (quoted strings)</li> | ||
<li>Numeric constants </li> | <li>Numeric constants </li> | ||
<li>Field values (values derived from field retrievals)</li> | <li>Field values (values derived from field retrievals)</li> | ||
<li>%Variables</li> | <li>%Variables</li> | ||
</ul> | </ul> | ||
<p> | <p> | ||
SOUL performs value conversions on values, as described in this article.</p> | |||
<p>Using values and/or %variables, you can construct expressions to perform arithmetic operations, which are discussed in this | |||
===Arithmetic operations=== | |||
<p> | |||
<p>[[#Model 204 parameters that set default attributes for variables|Model 204 parameters that set default attributes for variables]] lists three <var class="product">Model 204</var> parameters that establish the default type, length, and number of decimal places for all types of | Using values and/or %variables, you can construct expressions to perform arithmetic operations, which are discussed in this article.</p> | ||
==Default variable attributes== | |||
===Model 204 parameters that set default attributes for variables=== | |||
<p> | |||
[[#Model 204 parameters that set default attributes for variables|Model 204 parameters that set default attributes for variables]] lists three <var class="product">Model 204</var> parameters that establish the default type, length, and number of decimal places for all types of SOUL variables:</p> | |||
<table> | <table> | ||
<caption>%variable parameters</caption> | <caption>%variable parameters</caption> | ||
Line 51: | Line 69: | ||
<th>Default</th> | <th>Default</th> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>VTYPE</td> | <td>VTYPE</td> | ||
<td>Type: | <td>Type: <var>Fixed</var>, <var>Float</var>, <var>String</var>, or <var>Undefined</var></td> | ||
<td> | <td><var>String</var></td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>VLEN</td> | <td>VLEN</td> | ||
<td>Length of | <td>Length of <var>String</var> variables</td> | ||
<td align="right">20</td> | <td align="right">20</td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>VDP</td> | <td>VDP</td> | ||
<td>Number of decimal places in | <td>Number of decimal places in <var>Fixed</var> or <var>String</var> variables</td> | ||
<td align="right">0</td> | <td align="right">0</td> | ||
</tr> | </tr> | ||
</table> | </table> | ||
<p>You can change the defaults established by these parameters as follows:</p> | <p> | ||
You can change the defaults established by these parameters as follows:</p> | |||
<ul> | <ul> | ||
<li>The values of VTYPE, VLEN, and/or VDP can be changed by any user for the duration of the terminal session with the RESET command.</li> | <li>The values of VTYPE, VLEN, and/or VDP can be changed by any user for the duration of the terminal session with the <var>RESET</var> command.</li> | ||
<li>The value of any of these parameters can be overridden for the duration of a request with the | <li>The value of any of these parameters can be overridden for the duration of a request with the <var>Variables Are</var> statement.</li> | ||
<li>The variable type, length, and/or number of decimal places for any given variable can be explicitly specified in the declaration statement for that variable. This has the effect of overriding the respective values established by VTYPE, VLEN, and VDP, as well as the values established by the | <li>The variable type, length, and/or number of decimal places for any given variable can be explicitly specified in the declaration statement for that variable. This has the effect of overriding the respective values established by VTYPE, VLEN, and VDP, as well as the values established by the <var>Variables Are</var> statement. </li> | ||
</li> | |||
</ul> | </ul> | ||
<p>VTYPE, VLEN, and VDP are discussed where relevant elsewhere in this | <p> | ||
VTYPE, VLEN, and VDP are discussed where relevant elsewhere in this article. Also, refer to the | |||
<p>A variable can be declared:</p> | [[List of Model 204 parameters]] and [[List of Model 204 commands]] for more on user parameters.</p> | ||
===Relationship between default values and variable declarations=== | |||
<p> | |||
A variable can be declared:</p> | |||
<ul> | <ul> | ||
<li>Explicitly, in a declaration statement (see [[#DECLARE statements for %variables|DECLARE statements for %variables]])</li> | <li>Explicitly, in a declaration statement (see [[#DECLARE statements for %variables|DECLARE statements for %variables]])</li> | ||
<li>Implicitly, in an assignment statement (see [[#Assignment statements|Assignment statements]]). When a variable is declared implicitly, it takes on the attributes established by the VTYPE, VLEN, and VDP parameters (as modified by any | <li>Implicitly, in an assignment statement (see [[#Assignment statements|Assignment statements]]). When a variable is declared implicitly, it takes on the attributes established by the VTYPE, VLEN, and VDP parameters (as modified by any <var>Variables Are</var> statement that may precede the assignment statement).</li> | ||
</li> | |||
</ul> | </ul> | ||
=== | |||
<p>The | ===Variables Are statement=== | ||
<p>A | <p> | ||
The <var>Variables Are</var> statement overrides, for the remainder of the current request, the default variable type, length, and/or number of decimal places established by the VTYPE, VLEN, and/or VDP parameters, or by an earlier <var>Variables Are</var> statement. It is particularly useful if you don't want to rely on VTYPE, VLEN, and VDP, and when most of the %variables used in a request are of the same type and length.</p> | |||
<p>The format of the | <p> | ||
<p class="code"> | A <var>Variables Are</var> declaration has no effect on variables which have been declared (either implicitly or explicitly) earlier in the request. The defaults established by a <var>Variables Are</var> statement remain in effect until the next <var>Variables Are</var> declaration or until the end of the request, whichever comes first.</p> | ||
{ | ====Syntax==== | ||
<p> | |||
| | The format of the <var>Variables Are</var> statement is:</p> | ||
<p class="code">Variables Are | |||
{Fixed [Dp <span class="term">n</span>] | Float | String [Len <span class="term">n</span>] [Dp {<span class="term">n</span> | *}] | |||
| Undefined} | |||
</p> | </p> | ||
< | |||
< | ====Variables Are Undefined statement==== | ||
<p>The | <p> | ||
===Declaring %variables and %variable arrays | The <var>Variables Are Undefined</var> statement forces you to explicitly declare all variables. If this statement is used in a request and <var class="product">Model 204</var> encounters an undeclared variable, an error message is issued.</p> | ||
<p>You can declare a variable and subsequently assign and reset that variable any number of times during a | <p> | ||
The <var>Variables Are Undefined</var> statement sets both the default <var>Len</var> and <var>Dp</var> options to 0. Therefore, when <var>Variables Are Undefined</var> is in effect, %variables declared as <var>String</var> must have the <var>Len</var> specified or an error message is issued.</p> | |||
==<b id="Declaring"></b>Declaring %variables and %variable arrays== | |||
<p> | |||
You can declare a variable and subsequently assign and reset that variable any number of times during a SOUL request. You can use a variable declaration statement to specify:</p> | |||
<ul> | <ul> | ||
<li>Type of variable</li> | <li>Type of variable</li> | ||
Line 107: | Line 139: | ||
<li>Use of the optional field save feature </li> | <li>Use of the optional field save feature </li> | ||
</ul> | </ul> | ||
<p>Variables also can be declared to be arrays of up to three dimensions. An element of a %variable array is equivalent to a %variable that is not part of an array. It can be used anywhere that a %variable can be used.</p> | ===Variable arrays=== | ||
=== | <p> | ||
<p>To temporarily set or reset the default variable type, length, and number of decimal places for a particular %variable or %variable array in a request, use the | Variables also can be declared to be arrays of up to three dimensions. An element of a %variable array is equivalent to a %variable that is not part of an array. It can be used anywhere that a %variable can be used.</p> | ||
<p>In the following syntax diagrams, the first declaration statement is for numeric %variables and the second declaration statement is for string %variables</p> | ===Declare statements for %variables=== | ||
<p> | |||
To temporarily set or reset the default variable type, length, and number of decimal places for a particular %variable or %variable array in a request, use the <var>Declare</var> statement.</p> | |||
====Syntax==== | |||
<p> | |||
In the following syntax diagrams, the first declaration statement is for numeric %variables and the second declaration statement is for string %variables</p> | |||
<ul> | <ul> | ||
<li>Syntax for numeric %variables: | <li>Syntax for numeric %variables: | ||
<p class=" | <p class="syntax">[Declare] <span class="term">%variable</span> [Is] {Fixed [Dp <span class="term">n</span>] | Float} | ||
[Array(<span class="term">d1</span> [,<span class="term">d2</span> [,<span class="term">d3</span>]])] | |||
[ | [[[Initial clause in %variable declaration|Initial]](<span class="term">numeric-expression</span>)] [Static] | ||
[Common] | |||
[ | </p></li> | ||
[ | <li>Syntax for string %variables: | ||
<p class="syntax">[Declare] <span class="term">%variable</span> [Is] String [Len <span class="term">n</span>] | |||
[Dp [<span class="term">n</span> |*}] | |||
[Array(<span class="term">d1</span> [,<span class="term">d2</span> [,<span class="term">d3</span>]])] [No Field Save] | |||
[[[Initial clause in %variable declaration|Initial]]('<span class="term">EBCDIC-string</span>' | <span class="term">expression</span>)] [Static] | |||
[Common] | |||
</p></li> | </p></li> | ||
<li> | </ul> | ||
< | Where: | ||
<ul> | |||
<li>The keyword <var>Declare</var> is optional. </li> | |||
<li>The <var>[[Initial clause in %variable declaration|Initial]]</var> attribute assigns an initial value to a %variable at compilation time, without using any excess QTBL, STBL, or VTBL space and CPU usage. The <var>Initial</var> attribute is permitted only for numeric expressions or EBCDIC string variables, and not for arrays of any type or DBCS variables.</li> | |||
<li>The <var>Static</var> attribute limits assignment to a %variable to the <var>Initial</var> attribute and requires the <var>Initial</var> attribute to set the %variable's initial (and only) value.</li> | |||
<li>The various other components of this statement, except for <var>Common</var>, are described later in this article; <var>Common</var> is discussed in [[Subroutines#Common elements|Common elements]]. | |||
<p> | |||
If you want to use the <var>Common</var> attribute on a %variable declaration with the <var>Initial</var> and <var>Static</var> attributes, the <var>Common</var> attribute must be the last token in the statement. For example:</p> | |||
<p class="code">%x is float initial (3) static common | |||
</p></li> | </p></li> | ||
</ul> | </ul> | ||
====Usage==== | |||
====%Variable Initial value assignment==== | |||
<p> | |||
An <var>Initial</var> value longer than the maximum length results in a compilation warning message:</p> | |||
< | |||
< | |||
<p class="code">M204.2493: VARIABLE TOO SMALL FOR INITIAL VALUE | <p class="code">M204.2493: VARIABLE TOO SMALL FOR INITIAL VALUE | ||
</p> | </p> | ||
<p>The following examples use the | ====Examples==== | ||
<p> | |||
The following examples use the <var>Static</var> or <var>Initial</var> attribute. </p> | |||
<ul> | <ul> | ||
<li>In the first example, set %X to the value ABC, using the | <li>In the first example, set %X to the value ABC, using the <var>Static</var> attribute. The value cannot be changed during request evaluation: | ||
<p class="code">%X IS STRING LEN 3 INITIAL('ABC') STATIC | <p class="code">%X IS STRING LEN 3 INITIAL('ABC') STATIC | ||
</p></li> | </p></li> | ||
<li>The next example uses a %variable that can be changed during request evaluation: | |||
<li>The next example uses a %variable that can be changed during request evaluation: | |||
<p class="code">%Y IS STRING LEN 3 INITIAL('ABC') | <p class="code">%Y IS STRING LEN 3 INITIAL('ABC') | ||
</p></li> | </p></li> | ||
<li>The following compiler error message is displayed if you attempt to assign a value to a %variable that has been declared | |||
<li>The following compiler error message is displayed if you attempt to assign a value to a %variable that has been declared <var>Static</var>: | |||
<p class="code"><b></b>*** M204.0542: EDIT COMPLETE - GO | <p class="code"><b></b>*** M204.0542: EDIT COMPLETE - GO | ||
<b></b>*** 1 M204.2490: ILLEGAL ASSIGNMENT TO STATIC %VARIABLE | <b></b>*** 1 M204.2490: ILLEGAL ASSIGNMENT TO STATIC %VARIABLE | ||
%X=5 | %X=5 | ||
(FILE=CCATEMP, PROCEDURE=0, LINE=3) | (FILE=CCATEMP, PROCEDURE=0, LINE=3) | ||
==5 | ==5 | ||
Line 171: | Line 211: | ||
<b></b>*** M204.1042: COMPILATION ERRORS | <b></b>*** M204.1042: COMPILATION ERRORS | ||
</p></li> | </p></li> | ||
<li> | |||
<li>The next example illustrates using the <var>Static</var> attribute and an expression with the <var>Initial</var> attribute. | |||
<p class="code">BEGIN | <p class="code">BEGIN | ||
%X IS STRING LEN 3 INITIAL('ABC') STATIC | %X IS STRING LEN 3 INITIAL('ABC') STATIC | ||
Line 179: | Line 220: | ||
PRINT %ALPHA | PRINT %ALPHA | ||
END | END | ||
<b></b>***M204.0542:EDIT COMPLETE - GO | <b></b>***M204.0542:EDIT COMPLETE - GO | ||
BE | BE | ||
</p></li> | </p></li> | ||
</ul> | </ul> | ||
===%Variable names=== | |||
A variable name can consist of any number of letters, numbers, and some special characters (for example, underscore). | |||
The first character of the name must be a percent sign (<tt>%</tt>). | |||
The <tt>.</tt> (period) character is not allowed in the name of a variable that is declared as a <var>[[Json class|Json]]</var> object. | |||
A variable name can have no embedded blanks, colons, or any of the following <var class="product">Model 204</var> reserved characters: | |||
<table> | <table> | ||
<tr> | <tr> | ||
<td>=</td> | <td><b>=</b></td> | ||
<td>$</td> | <td><b>+</b></td> | ||
</tr> | <td><b>$</b></td></tr> | ||
<tr> | <tr> | ||
<td>(</td> | <td><b>(</b></td> | ||
<td>></td> | <td><b>*</b></td> | ||
<td><b>,</b> (not sign — see Note below)</td> | |||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>)</td> | <td><b>)</b></td> | ||
<td><</td> | <td><b>'</b></td> | ||
<td><b>-</b> (minus sign/hyphen)</td> | |||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>;</td> | <td><b>;</b></td> | ||
<td> | <td><b><</b></td> | ||
<td><b>/</b></td> | |||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>,</ | <td><b>,</b></td> | ||
<td><b>></b></td> | |||
< | <td><b>:</b></td> | ||
< | |||
<td> | |||
</tr> | </tr> | ||
</table> | |||
<p class="note"><b>Note:</b> The <code>,</code> reserved character is the EBCDIC "not sign," which has the hexadecimal value <code>5f</code>.</p> | |||
< | <p> | ||
The following guidelines apply to certain special characters that are allowed in %variable names:</p> | |||
<ul> | <ul> | ||
<li>The @ and # characters also are reserved unless they are reset by the user through the FLUSH and ERASE parameters. | <li>The @ and # characters also are reserved, unless they are reset by the user through the FLUSH and ERASE parameters. | ||
</li> | </li> | ||
<li>Dummy string characters (??, ?$, ?&) can be used in variable names, but they perform dummy string substitution, as described in [[Procedures#Using ?$ and ?& dummy strings|Using ?$ and ?& dummy strings]].</li> | |||
</ul> | </ul> | ||
===Relationship to Variables Are statement=== | |||
<p>The type, length, and decimal place settings established for a particular %variable by a DECLARE %variable statement are not overridden by a | <p> | ||
<p class="code">DECLARE %NAME STRING LEN 30 | The type, length, and decimal place settings established for a particular %variable by a DECLARE %variable statement are not overridden by a <var>Variables Are</var> statement. For example, if the statement:</p> | ||
<p class="code">DECLARE %NAME STRING LEN 30 | |||
</p> | </p> | ||
<p>is followed by the statement:</p> | <p> | ||
<p class="code">VARIABLES ARE FIXED | is followed by the statement:</p> | ||
<p class="code">VARIABLES ARE FIXED | |||
</p> | </p> | ||
<p>then %NAME remains a string of length 30.</p> | <p> | ||
then <code>%NAME</code> remains a string of length 30.</p> | |||
<p>A %variable can be declared as one of | |||
==%Variable types== | |||
<p> | |||
A %variable can be declared as one of several distinct types:</p> | |||
<ul> | <ul> | ||
<li> | <li><var>Fixed</var> (fixed-point numeric)</li> | ||
<li> | |||
<li> | <li><var>Float</var> (floating-point numeric)</li> | ||
<li><var>String</var> (alphanumeric string)</li> | |||
</ul> | |||
And these, as of Version 7.5 of Model 204: | |||
<ul> | |||
<li><var>[[Unicode#The SOUL Unicode type|Unicode]]</var> (Unicode string)</li> | |||
<li><var>[[Longstrings|Longstring]]</var> (string with very large maximum size) </li> | |||
<li><var>[[Object variables|Object]]</var> (reference to an instance of a class) </li> | |||
<li>A [[Method variables|method variable]] (a variable that references a method)</li> | |||
</ul> | </ul> | ||
<p>Defining %variables as | ===Using Fixed or Float for arithmetic statements=== | ||
<p>Arithmetic operations are performed most efficiently if all %variables are defined with matching options: either as | <p> | ||
<p>An arithmetic operation where both operands are | Defining %variables as <var>Fixed</var> or <var>Float</var> improves the performance of arithmetic statements. If the result of an arithmetic operation is being assigned to a %variable, the result is not converted before assignment if the arithmetic operands are of the same type.</p> | ||
<p> | |||
<p>[[#Arithmetic result types|Arithmetic result types]] shows the types and the results for various combinations of operands in an arithmetic statement. The result described in the table refers to the result of an arithmetic operation, which might be an intermediate result. If the final result is being assigned to a %variable of a different type, it is converted to match.</p> | Arithmetic operations are performed most efficiently if all %variables are defined with matching options: either as <var>Float</var> or as <var>Fixed</var>, and with no decimal places or the same number of decimal places. To operate <var class="product">Model 204</var> as efficiently as possible, avoid mixed-type arithmetic. Use <var>String</var> variables only when string manipulations are required.</p> | ||
<p> | |||
An arithmetic operation where both operands are <var>Fixed</var> requires rules to determine the scale (number of decimal places) of the result. See [[#Fixed precision arithmetic|Fixed precision arithmetic]] for detailed information on the way <var class="product">Model 204</var> handles <var>Fixed</var> arithmetic operations.</p> | |||
===Arithmetic result types=== | |||
<p> | |||
[[#Arithmetic result types|Arithmetic result types]] shows the types and the results for various combinations of operands in an arithmetic statement. The result described in the table refers to the result of an arithmetic operation, which might be an intermediate result. If the final result is being assigned to a %variable of a different type, it is converted to match.</p> | |||
<table> | <table> | ||
<caption>%Variable types for arithmetic results</caption> | <caption>%Variable types for arithmetic results</caption> | ||
Line 258: | Line 327: | ||
<th>Arithmetic result type</th> | <th>Arithmetic result type</th> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td> | <td><var>Float</var></td> | ||
<td> | <td><var>Float</var></td> | ||
<td> | <td><var>Float</var></td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td> | <td><var>Float</var></td> | ||
<td> | <td><var>Fixed</var></td> | ||
<td> | <td><var>Float</var></td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td> | <td><var>String</var></td> | ||
<td> | <td><var>Float</var></td> | ||
<td> | <td><var>Float</var></td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td> | <td><var>String</var></td> | ||
<td> | <td><var>String</var></td> | ||
<td> | <td><var>Float</var></td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td> | <td><var>String</var></td> | ||
<td> | <td><var>Fixed</var></td> | ||
<td> | <td><var>Fixed</var></td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td> | <td><var>Fixed</var></td> | ||
<td> | <td><var>Fixed</var></td> | ||
<td> | <td><var>Fixed</var></td> | ||
</tr> | </tr> | ||
</table> | </table> | ||
=== | ==%Variable lengths== | ||
<p>%Variables declared as | |||
<p class="code"> | ===Fixed %variables=== | ||
<p> | |||
%Variables declared as <var>Fixed</var> can have a decimal place specification associated with them. For example:</p> | |||
<p class="code">Declare %total Fixed dp 2 | |||
</p> | </p> | ||
<p>represents a dollar total. A | <p> | ||
=== | represents a dollar total. A <var>Fixed</var> %variable can contain as many as 15 significant digits, including decimal places. There can be as many as 9 decimal places.</p> | ||
<p>Variables declared as | |||
===Float %variables=== | |||
<p> | |||
Variables declared as <var>Float</var> are stored as double-precision floating-point numbers. Precision is guaranteed to 15 decimal digits; the exponent must be between 75 and -74. </p> | |||
===String %variables=== | |||
<p> | |||
Variables declared as <var>String</var> can have a maximum length as well as an optional decimal place specification associated with them. For example:</p> | |||
<p>Variables declared as | |||
<p class="code">DECLARE %NAME STRING LEN 20 DP 2 | <p class="code">DECLARE %NAME STRING LEN 20 DP 2 | ||
VARIABLES ARE STRING LEN 7 | VARIABLES ARE STRING LEN 7 | ||
</p> | </p> | ||
<p>The first statement (above) declares the %NAME variable as | <p> | ||
<p>Additionally, the decimal place for | The first statement (above) declares the %NAME variable as <var>String</var>, with a maximum length of 20 and two decimal places. The second statement sets the defaults for %variables not explicitly declared: <var>String</var> with a maximum length of 7 and no decimal places.</p> | ||
<p> | |||
Additionally, the decimal place for <var>String</var> %variables can be variable by specifying DP *. This causes all decimal digits to be placed in the string. For example:</p> | |||
<p class="code">BEGIN | <p class="code">BEGIN | ||
%AMOUNT IS STRING LEN 10 DP * | %AMOUNT IS STRING LEN 10 DP * | ||
Line 321: | Line 392: | ||
%AMOUNT = 1.234 | %AMOUNT = 1.234 | ||
PRINT %AMOUNT | PRINT %AMOUNT | ||
END | END | ||
</p> | </p> | ||
<p>Yields: </p> | <p> | ||
Yields: </p> | |||
<p class="code">1.2 | <p class="code">1.2 | ||
1.23 | 1.23 | ||
1.234 | 1.234 | ||
</p> | </p> | ||
<p>The maximum length of a | <p> | ||
<p>The current length of a | The maximum length of a <var>String</var> variable is 255 characters. Decimal places, and the decimal point itself, are included in the specified length. Alternatively, the default values for length and decimal places can be used. An attempt to store a value longer than the declared or default length results in truncation.</p> | ||
<p>If the | <p> | ||
The current length of a <var>String</var> variable is determined by the value put into the <var>String</var> variable. You can use the <var>[[$Len#$Len|$Len]]</var> function to find the current length of a <var>String</var> variable.</p> | |||
<p>You can define %variables as arrays of one, two, or three dimensions with the | <p> | ||
<p class="code">DECLARE %CODES STRING LEN 5 ARRAY(100) | If the <var>Variables Are Undefined</var> statement is used, the values for length and decimal places must be specified with each <var>String</var> %variable declaration. </p> | ||
==%Variable arrays== | |||
<p> | |||
You can define %variables as arrays of one, two, or three dimensions with the <var>Declare <i>%variable</i></var> statement. For example:</p> | |||
<p class="code">DECLARE %CODES STRING LEN 5 ARRAY(100) | |||
</p> | </p> | ||
<p>defines a one-dimensional array of up to 100 message codes, each five characters in length.</p> | <p> | ||
<p class="code">DECLARE %TRANSACTION FIXED DP 2 ARRAY(12,10000) | defines a one-dimensional array of up to 100 message codes, each five characters in length.</p> | ||
<p class="code">DECLARE %TRANSACTION FIXED DP 2 ARRAY(12,10000) | |||
</p> | </p> | ||
<p>defines a two-dimensional array of dollar transactions for a store. The array contains up to 10,000 transactions for each of 12 departments.</p> | <p> | ||
<p class="code">DECLARE %READINGS FLOAT ARRAY(3,10,80) | defines a two-dimensional array of dollar transactions for a store. The array contains up to 10,000 transactions for each of 12 departments.</p> | ||
<p class="code">DECLARE %READINGS FLOAT ARRAY(3,10,80) | |||
</p> | </p> | ||
<p>defines a three-dimensional array consisting of up to 80 atmospheric readings of three distinct types from 10 monitoring stations.</p> | <p> | ||
defines a three-dimensional array consisting of up to 80 atmospheric readings of three distinct types from 10 monitoring stations.</p> | |||
<p>All elements of an array must have the same type ( | |||
===Array elements must be of one type=== | |||
<p>An array can be referred to only after it has been declared in an array can have as many as three declared dimensions. A subscript value must be supplied for each dimension. </p> | <p> | ||
<p>If a variable is declared as an array, it must always be referenced with subscripts.</p> | All elements of an array must have the same type (<var>Fixed</var>, <var>Float</var>, or <var>String</var>) and element length.</p> | ||
<p>Each of the subscript values that refers to a dimension can be a number or an expression. For example:</p> | |||
===%Variable array references=== | |||
<p> | |||
An array can be referred to only after it has been declared in an array can have as many as three declared dimensions. A subscript value must be supplied for each dimension. </p> | |||
<p> | |||
If a variable is declared as an array, it must always be referenced with subscripts.</p> | |||
<p> | |||
Each of the subscript values that refers to a dimension can be a number or an expression. For example:</p> | |||
<p class="code">%CODE(2) | <p class="code">%CODE(2) | ||
%READING(3,200-%A/%B,%N) | %READING(3,200-%A/%B,%N) | ||
</p> | </p> | ||
<p>As shown in the examples, the expression can contain references to other %variables. The subscript value is converted to an integer. Any fraction is truncated before the subscript value is used as the array subscript. The subscript value must fall within the declared range of dimensions.</p> | <p> | ||
=== | As shown in the examples, the expression can contain references to other %variables. The subscript value is converted to an integer. Any fraction is truncated before the subscript value is used as the array subscript. The subscript value must fall within the declared range of dimensions.</p> | ||
<p>When a | |||
<p class="code"> | ===No Field Save option=== | ||
<p> | |||
When a <var>String</var> %variable array is declared, you can specify:</p> | |||
<p class="code">No Field Save | |||
</p> | </p> | ||
<p>If you do not intend to use any of the | <p> | ||
<p>An element of a | If you do not intend to use any of the <var>String</var> array elements as field name variables, you should select the <var>No Field Save</var> option, to save space in the user work areas described in [[Large request considerations#STBL (character string table)|STBL (character string table)]]. (Field name variables are discussed in detail on [[#Field name variables|Field name variables]].)</p> | ||
<p> | |||
An element of a <var>String</var> array can be used as a field name variable even if <var>No Field Save</var> is specified. However, when the value of the element is referred to as a field name, extra processing and additional disk I/O are required for each reference after the first.</p> | |||
<p>The format of the statement used to calculate and assign the value of %variables is:</p> | ==Assigning values to %variables== | ||
<p class=" | |||
===Assignment statements=== | |||
====Syntax==== | |||
<p> | |||
The format of the statement used to calculate and assign the value of %variables is:</p> | |||
<p class="syntax"><span class="term">%variablename</span> = <span class="term">expression</span> | |||
</p> | </p> | ||
<p>The name of the %variable to be set appears to the left of the equal sign and the expression to whose value the %variable is to be set is at the right. (See also [[#Expressions|Expressions]].)</p> | <p> | ||
<p>For Large Object data, a compiler error is issued when the right side of the equal sign is expected to contain a BUFFER expression and it does not.</p> | The name of the %variable to be set appears to the left of the equal sign and the expression to whose value the %variable is to be set is at the right. (See also [[#Expressions|Expressions]].)</p> | ||
<p> | |||
For Large Object data, a compiler error is issued when the right side of the equal sign is expected to contain a BUFFER expression and it does not.</p> | |||
<p class="code">M204.2691: BUFFER ASSIGNMENT MUST REFERENCE LARGE OBJECT FIELD | <p class="code">M204.2691: BUFFER ASSIGNMENT MUST REFERENCE LARGE OBJECT FIELD | ||
</p> | </p> | ||
<p>and/or</p> | <p> | ||
and/or</p> | |||
<p class="code">M204.2704: BUFFER REFERENCE REQUIRES LOB FIELD | <p class="code">M204.2704: BUFFER REFERENCE REQUIRES LOB FIELD | ||
</p> | </p> | ||
<p>These statements are valid assignments:</p> | ====Example==== | ||
<p> | |||
These statements are valid assignments:</p> | |||
<p class="code">%AGENT = AGENT | <p class="code">%AGENT = AGENT | ||
%NAME = 'DALE STERN' | %NAME = 'DALE STERN' | ||
%RESULT = (%INCREASE + TOTAL PREMIUM) * .01 | %RESULT = (%INCREASE + TOTAL PREMIUM) * .01 | ||
</p> | </p> | ||
<p>Note that %AGENT is legal as a variable name even if AGENT is a field name in the file. The variable and the field are not related to each other.</p> | <p> | ||
Note that <code>%AGENT</code> is legal as a variable name even if <code>AGENT</code> is a field name in the file. The variable and the field are not related to each other.</p> | |||
<p>Normally, an assignment statement precedes a %variable reference in another statement. If a %variable is going to be declared with the | |||
===Relationship between %variable assignment and declaration=== | |||
<p> | <p> | ||
Normally, an assignment statement precedes a %variable reference in another statement. If a %variable is going to be declared with the <var>Declare <i>%variable</i></var> statement, the declaration must precede the first use of the %variable. If an assignment statement does not precede the %variable reference, or the variable has not been declared, then default values (null values for <var>String</var> types, 0 for <var>Fixed</var> and <var>Float</var>) are assigned to the %variable.</p> | |||
===Truncation vs. rounding on assignment=== | |||
<p> | |||
In an assignment statement, it is possible for the length of the assigned value to exceed the maximum length for that %variable (as determined in the variable declaration statement, the <var>Variables Are</var> statement, or the value of the VLEN or VDP parameter). The way <var class="product">Model 204</var> treats this situation depends on the %variable type.</p> | |||
<ul> | <ul> | ||
<li>For | <li>For <var>Float</var> %variables, the assigned value is rounded to 15 significant digits. </li> | ||
< | |||
< | <li>For <var>Fixed</var> %variables, if the number of places to the left of the decimal point in the assigned value, plus the number of decimal places declared (not assigned) exceeds 15, <var class="product">Model 204</var> returns an error message and assigns a value of zero. Otherwise, if the number of decimal places assigned exceeds the number declared, <var class="product">Model 204</var> truncates the assigned value to the number of decimal places declared. For example, the following request: | ||
<p class="code">BEGIN | <p class="code">BEGIN | ||
%X IS FIXED DP 0 | %X IS FIXED DP 0 | ||
Line 398: | Line 503: | ||
END | END | ||
</p> | </p> | ||
<p>results in this output:</p> | <p> | ||
results in this output:</p> | |||
<p class="code">%X = 1 | <p class="code">%X = 1 | ||
%Y = 5 | %Y = 5 | ||
%X * %Y = 5 | %X * %Y = 5 | ||
</p> | </p> | ||
<p>The value of %X is truncated from 1.9 to 1 upon assignment for both display and computation.</p | <p> | ||
The value of %X is truncated from 1.9 to 1 upon assignment for both display and computation.</p> | |||
</li> | </li> | ||
<li>For <var>String</var> %variables, if the number of characters in the assigned value exceeds the maximum declared length (or, if not declared, the default length set by the VLEN parameter), the assigned value is truncated to the maximum length allowed.</li> | |||
</ul> | </ul> | ||
<p>You can change the value of a %variable at any point in a request by using an assignment statement. The variable is stored for the duration of the request that assigns it, including any continuations, and is then deleted. </p> | ===Changing %variable values=== | ||
<p>At the beginning of a request, all %variables are set equal to a null string, or to zero, depending on their types. </p> | <p> | ||
<p>During a request, a %variable can be set equal to another %variable, a quoted string, a number, a field value, a noted value, a function, a count of records or field occurrences, an occurrence number, a null value, or the result of a computation.</p> | You can change the value of a %variable at any point in a request by using an assignment statement. The variable is stored for the duration of the request that assigns it, including any continuations, and is then deleted. </p> | ||
====Understanding | <p> | ||
<p>Code written using an | At the beginning of a request, all %variables are set equal to a null string, or to zero, depending on their types. </p> | ||
<p class="code">BEGIN | <p> | ||
During a request, a %variable can be set equal to another %variable, a quoted string, a number, a field value, a noted value, a function, a count of records or field occurrences, an occurrence number, a null value, or the result of a computation.</p> | |||
%X IS STRING | |||
===<b id="initial"></b>Understanding Initial processing=== | |||
<!-- #.QA The following two requests are in QASHR regression test SOUL.SVT.001.QA --> | |||
<p> | |||
Code written using an <var>Initial</var> assignment for both %variables results in the assigned value of <code>%X</code> as the <var>Initial</var> value assigned for <code>%Y</code> as both assignments are resolved at compilation. For example:</p> | |||
<p class="code">BEGIN | |||
%X IS STRING LEN 1 INITIAL(1) | |||
* %X assigned the INITIAL value of 1, at compilation | |||
%Y IS FIXED INITIAL(%X) | %Y IS FIXED INITIAL(%X) | ||
* %Y assigned the INITIAL value of %X, at compilation | |||
PRINT 'Y = ' %Y | PRINT 'Y = ' %Y | ||
END | END | ||
Y = 1 | Y = 1 | ||
</p> | </p> | ||
<p>An | <p> | ||
<p>The following code reflects this processing:</p> | An <var>Initial</var> value assignment in the format <code>%Y IS FIXED INITIAL (%X)</code>, will not resolve to the value of <code>%X</code>, if <code>%X</code> was assigned in the format <code>%X=1</code>. <code>%X=1</code> format variable assignments are resolved at evaluation, subsequent to compilation. <var>Initial</var> value assignments are resolved at compilation. </p> | ||
<p> | |||
The following code reflects this processing:</p> | |||
<p class="code">BEGIN | <p class="code">BEGIN | ||
%X IS STRING LEN 1 | |||
%X = 1 | %X = 1 | ||
* %X assigned the value of 1 at evaluation | |||
%Y IS FIXED INITIAL(%X) | %Y IS FIXED INITIAL(%X) | ||
* %Y assigned the INITIAL value at compilation | |||
PRINT 'Y = ' %Y | PRINT 'Y = ' %Y | ||
END | END | ||
Y = 0 | Y = 0 | ||
</p> | </p> | ||
<p>The %X value is assigned at evaluation. The | <p> | ||
The <code>%X</code> value is assigned at evaluation. The <var>Initial</var> value is assigned at compilation, prior to the evaluation of <code>%X=1</code>. The result is that <code>%Y</code> is assigned the default value, zero (0), for its type of <var>Fixed</var>.</p> | |||
[operator {operand | (expression)}]... | ==Expressions== | ||
<p> | |||
Expressions are evaluated by <var class="product">Model 204</var> and used to assign values to %variables and function arguments, or included as operands in computation or conditional statements.</p> | |||
====Syntax==== | |||
<p> | |||
An expression has this format:</p> | |||
<p class="code">{<span class="term">operand</span> | (<span class="term">expression</span>)} [<span class="term">operator</span> {<span class="term">operand</span> | (<span class="term">expression</span>)}]... | |||
</p> | </p> | ||
< | Where: | ||
< | <ul> | ||
<li><var class="term">operand</var> is one of the following: | |||
<ul> | <ul> | ||
<li>%%variable (field name variable)</li> | <li>%%variable (field name variable)</li> | ||
<li>%variable or element of %variable array</li> | <li>%variable or element of %variable array</li> | ||
< | |||
< | <li><var>Count In <i>label</i></var></li> | ||
</li> | |||
<li>Field name</li> | <li>Field name</li> | ||
<li>Function </li> | <li>Function </li> | ||
<li>Number</li> | <li>Number</li> | ||
< | |||
< | <li><var>Occurrence In <i>label</i></var></li> | ||
</li> | |||
<li>Quoted string</li> | <li>Quoted string</li> | ||
</li> | |||
< | <li><var>Value In <i>label</i></var></li> | ||
</li> | </ul></li> | ||
<li><var class="term">operator</var> can be arithmetic, Boolean, comparison, or concatenation.</li> | |||
</ul> | </ul> | ||
===Operator order of precedence=== | |||
<p> | <p> | ||
The following table lists the operators used within expressions in order of precedence. Parentheses can be used to override the order.</p> | |||
<table> | <table> | ||
<caption> | <caption>Operator order of precedence in expressions</caption> | ||
<tr class="head"> | <tr class="head"> | ||
<th>Order of precedence</th> | <th>Order of precedence</th> | ||
<th>Operator</th> | <th>Operator</th> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td> First</td> | <td> First</td> | ||
<td>IS PRESENT, IS NOT PRESENT</td> | <td>IS PRESENT, IS NOT PRESENT</td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td> Second</td> | <td> Second</td> | ||
<td>- (unary minus)</td> | <td>- (unary minus)</td></tr> | ||
</tr> | |||
<tr> | <tr> | ||
<td> Third</td> | <td> Third</td> | ||
<td>*,/</td> | <td>*,/</td></tr> | ||
</tr> | |||
<tr> | <tr> | ||
<td> Fourth</td> | <td> Fourth</td> | ||
<td>+,-</td> | <td>+,-</td></tr> | ||
</tr> | |||
<tr> | <tr> | ||
<td> Fifth</td> | <td> Fifth</td> | ||
<td>WITH</td> | <td>WITH</td></tr> | ||
</tr> | |||
<tr> | <tr> | ||
<td> Sixth</td> | <td> Sixth</td> | ||
<td>EQ, =, LE, <=, GT, >, GE, >=, NE, | <td>EQ, =, LE, <=, GT, >, GE, >=, NE, ,=, LT, IS [NOT] LIKE</td></tr> | ||
</tr> | |||
<tr> | <tr> | ||
<td> Seventh</td> | <td> Seventh</td> | ||
<td>NOT</td> | <td>NOT</td></tr> | ||
</tr> | |||
<tr> | <tr> | ||
<td> Eighth</td> | <td> Eighth</td> | ||
<td>AND</td> | <td>AND</td></tr> | ||
</tr> | |||
<tr> | <tr> | ||
<td> Ninth</td> | <td> Ninth</td> | ||
<td>OR</td> | <td>OR</td></tr> | ||
</tr> | |||
<tr> | <tr> | ||
<td> Tenth</td> | <td> Tenth</td> | ||
<td>AND (implied by a new line; occurs only in an | <td>AND (implied by a new line; occurs only in an <var>If</var> statement) </td></tr> | ||
</tr> | |||
</table> | </table> | ||
< | <blockquote class="note"><b>Notes:</b> | ||
<li>For a description of the <code>IS [NOT] LIKE</code> clauses, see the syntax of [[Is Like pattern matching|Is Like patterns]]. | <ul> | ||
<li>The first character (<code>,</code>) of the inequality test above is the EBCDIC "not sign", which has the hexadecimal value <code>5f</code>. </li> | |||
<li>For a description of the <code>IS [NOT] LIKE</code> clauses, see the syntax of [[Is Like pattern matching#likeSyntax|Is Like patterns]]. </li> | |||
</ul> | </ul> | ||
</ | </blockquote> | ||
===Incomplete expressions=== | |||
<p>Incomplete expressions, such as the following: </p> | <p> | ||
Incomplete expressions, such as the following: </p> | |||
<p class="code">IF %X = 10 OR %Y > 40 AND %A = %B WITH | <p class="code">IF %X = 10 OR %Y > 40 AND %A = %B WITH | ||
</p> | </p> | ||
<p>produce this message: </p> | <p> | ||
produce this message: </p> | |||
<p class="code">M204.0052 ILLEGAL TERM | <p class="code">M204.0052 ILLEGAL TERM | ||
</p> | </p> | ||
<p>Compilation does not succeed and the procedure does not run. </p> | <p> | ||
Compilation does not succeed and the procedure does not run. </p> | |||
<p>You can use expressions for value retrieval in the following | |||
===Using expressions for value retrieval=== | |||
<p> | |||
You can use expressions for value retrieval in the following SOUL statements:</p> | |||
<ul> | <ul> | ||
<li>Update statements ( | <li>Update statements (<var>Store Record</var>, <var>Add</var>, <var>Change</var>, <var>Delete</var>, <var>Insert</var>) </li> | ||
< | |||
< | <li><var>File Records</var> </li> | ||
</li> | |||
<li> | <li><var>Find</var> </li> | ||
</li> | |||
<li> | <li><var>Find...Point$</var> condition </li> | ||
< | |||
< | <li><var>Find...Sfl$</var> and <var>Find...Sfge$</var> conditions </li> | ||
< | |||
< | <li><var>For Each Record In Order By</var> </li> | ||
</li> | |||
<li> | <li><var>For Each Record Where</var> </li> | ||
</li> | |||
<li> | <li><var>Find All Values</var> </li> | ||
</li> | |||
<li> | <li><var>For Each Value</var> </li> | ||
</li> | |||
<li> | <li><var>For Record Number</var> </li> | ||
</li> | |||
</ul> | </ul> | ||
<p>The following table provides examples of the types of expressions that you can use to supply retrieval values for statements. </p> | ====Expression types supported in SOUL statements==== | ||
<p> | |||
The following table provides examples of the types of expressions that you can use to supply retrieval values for statements. </p> | |||
<table> | <table> | ||
<caption>Expression types supported in statements</caption> | <caption>Expression types supported in statements</caption> | ||
Line 563: | Line 696: | ||
<th>Example</th> | <th>Example</th> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>Function call</td> | <td>Function call</td> | ||
<td> | <td><p class="codeInTable">In ?&File Fd ORDER.DATE Eq Value(<b>$Date(1,'')</b>)</p></td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>String concatenation</td> | <td>String concatenation</td> | ||
<td> | <td><p class="codeInTable">In ?&File Fd BIRTH.DATE Eq Value(<b>%yyyy With %mm With %dd</b>)</p></td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>Arithmetic operation</td> | <td>Arithmetic operation</td> | ||
<td> | <td><p class="codeInTable">In ?&File Fd SALES.VALUE Eq Value(<b>%item.value * %item.sales</b>)</p></td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td> | <td>SOUL construct</td> | ||
<td> | <td><p class="codeInTable">In ?&File Fd NUM.ORDERS Eq Value(<b>Count In FD.ORDERS</b>)</p></td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>Boolean expression</td> | <td>Boolean expression</td> | ||
<td> | <td><p class="codeInTable">In ?&File Fd ORDER.STATUS Eq Value(<b>%status Is Like 'A*'</b>)</p></td> | ||
</tr> | </tr> | ||
</table> | </table> | ||
<p>The following example shows these different types of expressions used as values.</p | |||
====Example==== | |||
<p> | |||
The following example shows these different types of expressions used as values.</p> | |||
<p class="code">B | <p class="code">B | ||
%MM IS STRING LEN 2 | %MM IS STRING LEN 2 | ||
Line 597: | Line 737: | ||
FD1: | FD1: | ||
IN CLIENTS FPC INCIDENT DATE EQ - | IN CLIENTS FPC INCIDENT DATE EQ - | ||
VALUE($DATECHG('YYYYMMDD',$DATE(1, | VALUE($DATECHG('YYYYMMDD',$DATE(1,''),-3169)) | ||
END FIND | END FIND | ||
FR FD1 | FR FD1 | ||
Line 655: | Line 795: | ||
END | END | ||
</p> | </p> | ||
<p>This section describes the use of four types of operators:</p> | ==Operators== | ||
<p> | |||
This section describes the use of four types of operators:</p> | |||
<ul> | <ul> | ||
<li>Arithmetic</li> | <li>Arithmetic</li> | ||
<li>Comparison</li> | <li>Comparison</li> | ||
<li>Boolean</li> | <li>Boolean</li> | ||
<li> | <li><var>With</var></li> | ||
</ul> | </ul> | ||
<p>See the previous section for a discussion of expressions, and the next section for a discussion of operands. See [[# | <p> | ||
See the previous section for a discussion of expressions, and the next section for a discussion of operands. See [[#Fixed precision arithmetic|Fixed precision arithmetic]] for a more detailed discussion.</p> | |||
<p> | |||
<table | ===Arithmetic operators=== | ||
<p> | |||
<tr | The following table lists the arithmetic operators:</p> | ||
<table class="thJustBold"> | |||
<tr> | |||
<th>+</th> | <th>+</th> | ||
< | <td>Addition</td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
< | <th>-</th> | ||
<td>Subtraction, unary minus</td> | <td>Subtraction, unary minus</td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
< | <th>*</th> | ||
<td>Multiplication</td> | <td>Multiplication</td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
< | <th>/</th> | ||
<td>Division </td> | <td>Division </td> | ||
</tr> | </tr> | ||
</table> | </table> | ||
<p>The arithmetic operators are used to compute the value of a %variable or they can be included in an expression. When an expression contains several arithmetic operations, the operations are performed in the order shown in [[#Operator order of precedence|Operator order of precedence]]. Operators of equal precedence are evaluated in order of appearance, from left to right. For example:</p> | ====Order of operations==== | ||
<p class="code">% | <p> | ||
The arithmetic operators are used to compute the value of a %variable or they can be included in an expression. When an expression contains several arithmetic operations, the operations are performed in the order shown in [[#Operator order of precedence|Operator order of precedence]]. Operators of equal precedence are evaluated in order of appearance, from left to right. For example:</p> | |||
sets % | <p class="code">%result = 8*7 + 4 </p> | ||
< | sets <code>%result</code> to 60. | ||
<p> | |||
Parentheses change the order of operations; expressions within parentheses are compiled first. For example:</p> | |||
<p class="code">4-5*2*3 = -26 | <p class="code">4-5*2*3 = -26 | ||
(4-5)*(2*3) = -6 | (4-5)*(2*3) = -6 | ||
(4-(5*2))*3 = -18 | (4-(5*2))*3 = -18 | ||
</p> | </p> | ||
<p>An arithmetic overflow might occur during evaluation of a computation statement. If such an overflow occurs, the request is cancelled and an appropriate error message is issued.</p> | ====Arithmetic overflow==== | ||
<p> | |||
<p>The following comparison operators are used to compare two objects, two strings, two numbers, or a string and a number:</p> | An arithmetic overflow might occur during evaluation of a computation statement. If such an overflow occurs, the request is cancelled and an appropriate error message is issued.</p> | ||
<table> | |||
===Comparison operators=== | |||
<p> | |||
The following comparison operators are used to compare two objects, two strings, two numbers, or a string and a number:</p> | |||
<table class="thJustBold"> | |||
<tr class="head"> | <tr class="head"> | ||
<th>Operator</th> | <th>Operator</th> | ||
<th>Meaning</th> | <th>Meaning</th> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
< | <th>EQ, = </th> | ||
<td>Equal</td> | <td>Equal</td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
< | <th>NE, ^= </th> | ||
<td>Not equal</td> | <td>Not equal</td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
< | <th>GT, > </th> | ||
<td>Greater than</td> | <td>Greater than</td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
< | <th>LT, < </th> | ||
<td>Less than</td> | <td>Less than</td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
< | <th>GE, >= </th> | ||
<td>Greater than or equal to</td> | <td>Greater than or equal to</td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
< | <th>LE, <= </th> | ||
<td>Less than or equal to</td> | <td>Less than or equal to</td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
< | <th>IS [NOT] LIKE</th> | ||
<td>Pattern matching equivalents</td> | <td>Pattern matching equivalents</td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
< | <th>IS [NOT] PRESENT</th> | ||
<td>Field existence</td> | <td>Field existence</td> | ||
</tr> | </tr> | ||
</table> | </table> | ||
<p>When a comparison operator is included in an expression, a value of 1 results if the stated relation between operands is true; a value of 0 | <p> | ||
< | |||
<li>Either %A or %B (or both) is declared as | When a comparison operator is included in an expression, a value of 1 results if the stated relation between operands is true; if false, a value of 0, provided that <i>one</i> of the following conditions apply (using the expression <code>%I = (%A<=%B)</code> to illustrate): </p> | ||
<ul> | |||
<li>Either %A or %B (or both) is declared as <var>Fixed</var> or <var>Float</var>.</li> | |||
<li>Either %A or %B (or both) is signed in the expression; for example, | <li>Either %A or %B (or both) is signed in the expression; for example, | ||
%I = (+%A <=%B)</li> | <code>%I = (+%A <=%B)</code>.</li> | ||
<li>VTYPE = FLOAT or FIXED and VLEN is greater than zero.</li> | |||
</ | <li>VTYPE = FLOAT or FIXED, and VLEN is greater than zero.</li> | ||
<p>The resulting value returned from the expression might be invalid if all the following conditions apply:</p> | </ul> | ||
< | <p> | ||
<li>Neither %A nor %B is declared</li> | |||
<li>The expression does not sign the variable</li> | The resulting value returned from the expression might be invalid if <i>all</i> the following conditions apply:</p> | ||
<li>The system default for VTYPE is | <ul> | ||
<li>Neither %A nor %B is declared.</li> | |||
<li>The expression does not sign the variable.</li> | |||
<li>The system default for VTYPE is <var>String</var> and VLEN is greater than zero.</li> | |||
</ul> | </ul> | ||
</ | |||
<blockquote class="note"><b>Notes:</b> | |||
<ul> | |||
<li>See the discussion about the conditional statement in [[Flow of control in User Language#Comparison operators|Comparison operators]] for a description of these operators in conditional statements. </li> | |||
<li>The first character (<code>,</code>) of the inequality test above is the EBCDIC "not sign", which has the hexadecimal value <code>5f</code>.</li> | |||
<li>For a description of the <code>IS [NOT] LIKE</code> clauses, see the syntax of [[Is Like pattern matching#likeSyntax|Is Like patterns]].</li> | |||
<p>Use the Boolean operators listed in | </ul> | ||
<table> | </blockquote> | ||
===Boolean operators=== | |||
<p> | |||
Use the Boolean operators listed in the following table to modify or link together comparison expressions. (See the discussion about [[Flow of control in User Language#Boolean operators|Boolean operators and conditional statements]] for information on comparisons.)</p> | |||
<table class="thJustBold"> | |||
<caption>Boolean operators</caption> | <caption>Boolean operators</caption> | ||
<tr class="head"> | <tr class="head"> | ||
Line 766: | Line 938: | ||
<th>Meaning</th> | <th>Meaning</th> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
< | <th>Not</th> | ||
<td>The value of the comparison is reversed.</td> | <td>The value of the comparison is reversed.</td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
< | <th>And</th> | ||
<td>Both comparisons must be true.</td> | <td>Both comparisons must be true.</td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
< | <th>Or</th> | ||
<td>Either comparison must be true. </td> | <td>Either comparison must be true. </td> | ||
</tr> | </tr> | ||
</table> | </table> | ||
<p>Boolean operators are not restricted to comparisons. They also can be used in the middle of expressions (for example, 1 AND 2).</p> | <p> | ||
=== | Boolean operators are not restricted to comparisons. They also can be used in the middle of expressions (for example, <code>1 AND 2</code>).</p> | ||
<p> | |||
===With operator=== | |||
<p> | |||
<var>With</var> can be used in an expression to concatenate two strings. For example:</p> | |||
<p class="code">%A = '$' WITH TOTAL PREMIUM | <p class="code">%A = '$' WITH TOTAL PREMIUM | ||
PRINT %A TO COLUMN 10 | PRINT %A TO COLUMN 10 | ||
</p> | </p> | ||
<p>results in:</p> | <p> | ||
results in:</p> | |||
<p class="code">$550 | <p class="code">$550 | ||
$1092 | $1092 | ||
$605 | $605 | ||
</p> | </p> | ||
<p>This section describes the use of four types of operands: </p> | ==Operands== | ||
<p> | |||
This section describes the use of four types of operands: </p> | |||
<ul> | <ul> | ||
<li>%variables</li> | <li>%variables</li> | ||
Line 798: | Line 979: | ||
<li>Fields</li> | <li>Fields</li> | ||
</ul> | </ul> | ||
<p>See also</p> | <p> | ||
See also</p> | |||
<ul> | <ul> | ||
<li>[[#Expressions|Expressions]] </li> | <li>[[#Expressions|Expressions]] </li> | ||
<li>[[#Operators|Operators]]</li> | <li>[[#Operators|Operators]]</li> | ||
<li>[[# | <li>[[#Fixed precision arithmetic|Fixed precision arithmetic]] </li> | ||
</ul> | </ul> | ||
<p>After you define a %variable, you can use it to change other %variables. For example: </p> | ===Variables as operands=== | ||
<p class="code">%COUNT = %NUM | <p> | ||
After you define a %variable, you can use it to change other %variables. For example: </p> | |||
<p class="code">%COUNT = %NUM | |||
</p> | </p> | ||
<p>sets %COUNT, and:</p> | <p> | ||
<p class="code">%COUNT = %COUNT + 1 | sets <code>%COUNT</code>, and:</p> | ||
<p class="code">%COUNT = %COUNT + 1 | |||
</p> | </p> | ||
<p>replaces the value of %COUNT by its former value plus 1. </p> | <p> | ||
replaces the value of %COUNT<code>%COUNT</code> by its former value plus 1. </p> | |||
<p>Examples of %variables set to quoted strings are provided here: </p> | |||
===Quoted strings=== | |||
<p> | |||
Examples of %variables set to quoted strings are provided here: </p> | |||
<p class="code">%NAME = 'TETLEY' | <p class="code">%NAME = 'TETLEY' | ||
%AGE = '53' | %AGE = '53' | ||
%TITLE = 'QUARTERLY REPORT' | %TITLE = 'QUARTERLY REPORT' | ||
%SPOUSE = '' | %SPOUSE = '' | ||
</p> | </p> | ||
<p>In the preceding example, %SPOUSE is a quoted string that has a length of 0. </p> | <p> | ||
<p>Additional information about the use of quotation marks is provided in [[Request | In the preceding example, <code>%SPOUSE</code> is a quoted string that has a length of 0. </p> | ||
<p> | |||
<p>A number used as the value of a %variable or as a term in an expression can be a string of digits containing an optional sign and an embedded decimal point.</p> | Additional information about the use of quotation marks is provided in [[Request composition rules#Quotation marks|Quotation marks]].</p> | ||
<p>For example:</p> | |||
===Numbers=== | |||
<p> | |||
A number used as the value of a %variable or as a term in an expression can be a string of digits containing an optional sign and an embedded decimal point.</p> | |||
<p> | |||
For example:</p> | |||
<p class="code">3 +0.002 | <p class="code">3 +0.002 | ||
45.7 -37 | 45.7 -37 | ||
</p> | </p> | ||
<p>The magnitude of the number is limited by the magnitude of the largest number that can be represented in a floating point number. Therefore the number's exponent (if the number is expressed in exponent notation) must be between 75 and -74. </p> | <p> | ||
The magnitude of the number is limited by the magnitude of the largest number that can be represented in a floating point number. Therefore the number's exponent (if the number is expressed in exponent notation) must be between 75 and -74. </p> | |||
<p>Field values, referred to by field name, can be used in an assignment statement, but only inside a FOR EACH RECORD loop. To evaluate an expression, <var class="product">Model 204</var> uses the value of the field for the current record each time through the loop. For example: </p> | |||
===Fields=== | |||
<p> | |||
Field values, referred to by field name, can be used in an assignment statement, but only inside a FOR EACH RECORD loop. To evaluate an expression, <var class="product">Model 204</var> uses the value of the field for the current record each time through the loop. For example: </p> | |||
<p class="code">FOR EACH RECORD IN FIND.RECS | <p class="code">FOR EACH RECORD IN FIND.RECS | ||
%PROFIT = %INCREASE - TOTAL PREMIUM | %PROFIT = %INCREASE - TOTAL PREMIUM | ||
PRINT %PROFIT | PRINT %PROFIT | ||
END FOR | END FOR | ||
</p> | </p> | ||
<p>calculates profit from the data in each record and prints it. %PROFIT changes for each record.</p> | <p> | ||
<p>In expressions, the values of most types of fields are treated as character strings. The values of fields defined with the FLOAT attribute are treated as numbers. If a field is missing from a record being processed, the value used is a null string. </p> | calculates profit from the data in each record and prints it. <code>%PROFIT</code> changes for each record.</p> | ||
== | <p> | ||
<p>An arithmetic operation where both operands are | In expressions, the values of most types of fields are treated as character strings. The values of fields defined with the FLOAT attribute are treated as numbers. If a field is missing from a record being processed, the value used is a null string. </p> | ||
<p><var class="product">Model 204</var> determines the scale of intermediate results (the number of decimal places) using the following rules.</p> | ==Fixed precision arithmetic== | ||
<p> | |||
<p>When an expression requires either addition or subtraction, the scale of the temporary variable containing the result equals the larger of the scales of the two operands. For example, the scale for the result of the following expression is 3:</p> | An arithmetic operation where both operands are <var>Fixed</var> requires rules to determine the scale (maximum numbers of digits and decimal places) of the result.</p> | ||
===Scale of intermediate results=== | |||
<p> | |||
<var class="product">Model 204</var> determines the scale of intermediate results (the number of decimal places) using the following rules.</p> | |||
====Addition and subtraction==== | |||
<p> | |||
When an expression requires either addition or subtraction, the scale of the temporary variable containing the result equals the larger of the scales of the two operands. For example, the scale for the result of the following expression is 3:</p> | |||
<p class="code">12.345 + 3.6 | <p class="code">12.345 + 3.6 | ||
</p> | </p> | ||
<p>If the result exceeds 15 digits, decimal places are dropped from the right to produce the largest possible scale that fits in 15 digits. If a 15 digit number cannot be produced even by dropping all decimal places, an overflow condition is indicated.</p> | <p> | ||
If the result exceeds 15 digits, decimal places are dropped from the right to produce the largest possible scale that fits in 15 digits. If a 15 digit number cannot be produced even by dropping all decimal places, an overflow condition is indicated.</p> | |||
<p>When an expression requires multiplication, the scale of the temporary variable containing the result is equal to the sum of the scales of the two operands. For example, the scale for the result of the following expression is 5 (3+2):</p> | |||
====Multiplication==== | |||
<p> | |||
When an expression requires multiplication, the scale of the temporary variable containing the result is equal to the sum of the scales of the two operands. For example, the scale for the result of the following expression is 5 (3+2):</p> | |||
<p class="code">12.345 * 3.64 | <p class="code">12.345 * 3.64 | ||
</p> | </p> | ||
<p>If the sum of the scales of the operands exceeds 9 or if the result is larger than 15 digits, decimal places are dropped from the right to produce the largest possible scale that fits in 15 digits. As with addition and subtraction, if the result has more than 15 digits with all decimal places discarded, an overflow condition is indicated.</p> | <p> | ||
If the sum of the scales of the operands exceeds 9 or if the result is larger than 15 digits, decimal places are dropped from the right to produce the largest possible scale that fits in 15 digits. As with addition and subtraction, if the result has more than 15 digits with all decimal places discarded, an overflow condition is indicated.</p> | |||
<p>When an expression requires division, the scale of the temporary variable containing the result is equal to the larger of:</p> | |||
====Division==== | |||
<p> | |||
When an expression requires division, the scale of the temporary variable containing the result is equal to the larger of:</p> | |||
<ul> | <ul> | ||
<li>9</li> | <li>9</li> | ||
<li>the largest possible scale that fits in 15 digits</li> | <li>the largest possible scale that fits in 15 digits</li> | ||
</ul> | </ul> | ||
<p>For example, the scale for the result of this expression is 9 (the calculated result is 3.529411764):</p> | <p> | ||
For example, the scale for the result of this expression is 9 (the calculated result is 3.529411764):</p> | |||
<p class="code">12 / 3.4 | <p class="code">12 / 3.4 | ||
</p> | </p> | ||
<p>The following situations are treated as overflow conditions:</p> | ===Causes of overflow conditions=== | ||
<p> | |||
The following situations are treated as overflow conditions:</p> | |||
<ul> | <ul> | ||
<li>When the integer portion of any intermediate or final result is larger than 15 digits.</li> | <li>When the integer portion of any intermediate or final result is larger than 15 digits.</li> | ||
<li>For addition and multiplication, when the scale of the final result variable is so large that the integer portion of the result cannot fit into the maximum allotted size. For example: | <li>For addition and multiplication, when the scale of the final result variable is so large that the integer portion of the result cannot fit into the maximum allotted size. For example: | ||
<p class="code">BEGIN | <p class="code">BEGIN | ||
%A IS FIXED DP 0 | %A IS FIXED DP 0 | ||
Line 877: | Line 1,089: | ||
PRINT 'C = ' %C | PRINT 'C = ' %C | ||
END | END | ||
<b></b>*** M204.0542: EDIT COMPLETE - GO | <b></b>*** M204.0542: EDIT COMPLETE - GO | ||
<b></b>*** M204.0552: VARIABLE TOO SMALL FOR RESULT | <b></b>*** M204.0552: VARIABLE TOO SMALL FOR RESULT | ||
Line 883: | Line 1,095: | ||
</p></li> | </p></li> | ||
</ul> | </ul> | ||
<p>Because the scale of the variable which contains the final result (%C) is 9, the integer portion of the result is limited to no more than 6 digits. Because the integer portion of the result requires 7 digits, an overflow condition is triggered.</p> | <p> | ||
<p>This example illustrates that <var class="product">Model 204</var> takes into consideration the scale of the final result variable. The example below is identical to the one above except that the scale of %C is set to 8. The request executes successfully because this frees the required 7 digits for the integer portion of the result:</p> | Because the scale of the variable which contains the final result (%C) is 9, the integer portion of the result is limited to no more than 6 digits. Because the integer portion of the result requires 7 digits, an overflow condition is triggered.</p> | ||
<p> | |||
This example illustrates that <var class="product">Model 204</var> takes into consideration the scale of the final result variable. The example below is identical to the one above except that the scale of %C is set to 8. The request executes successfully because this frees the required 7 digits for the integer portion of the result:</p> | |||
<p class="code">BEGIN | <p class="code">BEGIN | ||
%A IS FIXED DP 0 | %A IS FIXED DP 0 | ||
Line 894: | Line 1,108: | ||
PRINT 'C = ' %C | PRINT 'C = ' %C | ||
END | END | ||
<b></b>*** M204.0542: EDIT COMPLETE - GO | <b></b>*** M204.0542: EDIT COMPLETE - GO | ||
C = 1000000.00000000 | C = 1000000.00000000 | ||
</p> | </p> | ||
===How Model 204 responds to overflow conditions=== | |||
<p>When <var class="product">Model 204</var> detects an overflow condition, the intermediate result is set to 1015. Since this is a 16-digit number, it is illegal in | |||
====Overflowing to zero==== | |||
<p> | |||
When <var class="product">Model 204</var> detects an overflow condition, the intermediate result is set to 1015. Since this is a 16-digit number, it is illegal in SOUL and tends to cause a cascade of overflow conditions in a complex expression, which can generate the following error message:</p> | |||
<p class="code">M204.0552: VARIABLE TOO SMALL FOR RESULT | <p class="code">M204.0552: VARIABLE TOO SMALL FOR RESULT | ||
</p> | </p> | ||
<p>The final result of the expression is usually 0, which lets you see that an overflow error might have occurred. </p> | <p> | ||
The final result of the expression is usually 0, which lets you see that an overflow error might have occurred. </p> | |||
<p>An exception to the rule of a 0 final result is the case where an overflow occurs in an intermediate step and the next step (whether intermediate or final) involves subtracting a value whose scale is 0 so that the result is less than 1015. In this case, you get a large, incorrect, result. For example:</p> | |||
====Overflowing to very large, obviously incorrect number==== | |||
<p> | |||
An exception to the rule of a 0 final result is the case where an overflow occurs in an intermediate step and the next step (whether intermediate or final) involves subtracting a value whose scale is 0 so that the result is less than 1015. In this case, you get a large, incorrect, result. For example:</p> | |||
<p class="code">BEGIN | <p class="code">BEGIN | ||
%X IS FIXED DP 0 | %X IS FIXED DP 0 | ||
Line 917: | Line 1,137: | ||
PRINT 'X =' %X | PRINT 'X =' %X | ||
END | END | ||
<b></b>*** M204.0542: EDIT COMPLETE - GO | <b></b>*** M204.0542: EDIT COMPLETE - GO | ||
<b></b>*** 1 M204.0563: ARITHMETIC OVERFLOW | <b></b>*** 1 M204.0563: ARITHMETIC OVERFLOW | ||
X = 999999999999990 | X = 999999999999990 | ||
</p> | </p> | ||
== | |||
<p>You can set a %variable value based on the following elements of a | ==Value In, Count In, and Occurrence In phrases== | ||
<p> | |||
You can set a %variable value based on the following elements of a SOUL request:</p> | |||
<ul> | <ul> | ||
<li> | <li><var>Value In</var> phrase | ||
</ | <p> | ||
<p>A %variable can be set equal to a noted value, as illustrated below:</p> | A %variable can be set equal to a noted value, as illustrated below:</p> | ||
<p class="code">%DRIVER = VALUE IN NOTE.DRIVER | <p class="code">%DRIVER = VALUE IN NOTE.DRIVER | ||
</p> | |||
<p> | |||
This phrase also can be included in an expression or used to include the current value in a <var>For Each Occurrence</var> or <var>For Each Value</var> loop.</p></li> | |||
<li>COUNT IN phrase | |||
<p> | |||
A %variable can be set equal to the number of records counted, as in:</p> | |||
<p class="code">%COUNT = COUNT IN NO.OF.VINS | |||
</p> | </p> | ||
<p>This phrase also can be included in an expression | <p> | ||
< | This phrase also can be included in an expression. </p></li> | ||
<li> | |||
< | <li>OCCURRENCE IN phrase | ||
<p> | |||
<p class="code">% | A %variable can be set equal to the subscript value of the current occurrence of a field in a record, as in:</p> | ||
<p class="code">%OCCUR = OCCURRENCE IN INCIDENT.TYPE | |||
</p> | </p> | ||
<p>This phrase also can be included in an expression. </p> | <p> | ||
where INCIDENT.TYPE is the statement label of a <var>For Each Occurrence</var> statement. This phrase also can be included in an arithmetic expression.</p></li> | |||
</ul> | </ul> | ||
==Conversions and significant digits== | |||
===Numeric terms=== | |||
<p> | |||
The following expression terms are considered numeric:</p> | |||
<p>The following expression terms are considered numeric:</p> | |||
<ul> | <ul> | ||
<li>Literal (unquoted) numbers: -3, .0079</li> | <li>Literal (unquoted) numbers: -3, .0079</li> | ||
< | |||
< | <li><var>Count In</var> phrases</li> | ||
< | |||
< | <li><var>Occurrence In</var> phrases</li> | ||
</li> | |||
<li>Some functions (see [[ | <li>Some functions (see [[List of mathematical $functions]])</li> | ||
<li>Results of numeric expressions</li> | <li>Results of numeric expressions</li> | ||
< | |||
< | <li><var>Fixed</var> or <var>Float</var> %variables</li> | ||
<li>FLOAT fields </li> | <li>FLOAT fields </li> | ||
</ul> | </ul> | ||
<p>The following expression terms are considered character:</p> | ===Character terms=== | ||
<p> | |||
The following expression terms are considered character:</p> | |||
<ul> | <ul> | ||
<li>Quoted strings: 'SMITH', '.0079'</li> | <li>Quoted strings: 'SMITH', '.0079'</li> | ||
<li>Non-FLOAT fields: NAME, ADDRESS</li> | <li>Non-FLOAT fields: NAME, ADDRESS</li> | ||
< | |||
< | <li><var>Value In</var> phrases</li> | ||
</li> | |||
<li>Some functions (see | <li>Some functions (see [[M204wiki main page#$Functions|$Functions]])</li> | ||
< | |||
< | <li><var>String</var> %variables </li> | ||
</li> | |||
</ul> | </ul> | ||
<p>In the expression AGE + 10, the value of the field AGE (character) is added to a literal number (numeric). <var class="product">Model 204</var> converts the value of AGE to a number. If the value is a proper number (for example, 5, -3.943, +.0003), the conversion is obvious; if not, the value is not a proper number (for example, FIVE, ", ABCD) or a number with too many digits, it is converted to a zero.</p> | ===Conversion=== | ||
<p>In the expression 'NUMBER' WITH -3.8, a quoted string is to be concatenated with a number. <var class="product">Model 204</var> first converts the number to a character string. In such a conversion, all decimal places are lost; the number is truncated to an integer and the result is NUMBER-3.</p> | <p> | ||
In the expression <code>AGE + 10</code>, the value of the field AGE (character) is added to a literal number (numeric). <var class="product">Model 204</var> converts the value of AGE to a number. If the value is a proper number (for example, 5, -3.943, +.0003), the conversion is obvious; if not, the value is not a proper number (for example, FIVE, ", ABCD) or a number with too many digits, it is converted to a zero.</p> | |||
<p> | <p> | ||
<p>However, all results contain at most 15 significant decimal digits, with zeros in the low-order positions. <var class="product">Model 204</var> preserves 15 digits in all intermediate results, rounding each result to 15 digits before going on to the next intermediate calculation. </p> | In the expression <code>'NUMBER' WITH -3.8</code>, a quoted string is to be concatenated with a number. <var class="product">Model 204</var> first converts the number to a character string. In such a conversion, all decimal places are lost; the number is truncated to an integer and the result is NUMBER-3.</p> | ||
<p>If the final result is assigned to a | |||
===Significant digits in computations=== | |||
<p>The following request illustrates an assignment statement. The request computes the total settlement amount for each claim type within a file. Output consists of a 2-column table, giving a total amount for each type as well as a grand total settlement amount. </p> | <p> | ||
<p>For example:</p> | SOUL can accept as input to computations the largest floating point number that can be expressed in exponent notation and can produce results of that magnitude. </p> | ||
<p> | |||
However, all results contain at most 15 significant decimal digits, with zeros in the low-order positions. <var class="product">Model 204</var> preserves 15 digits in all intermediate results, rounding each result to 15 digits before going on to the next intermediate calculation. </p> | |||
<p> | |||
If the final result is assigned to a <var>String</var> %variable, that result is truncated on the right to the maximum length specified for the %variable. </p> | |||
==Sample request using %variables== | |||
<p> | |||
The following request illustrates an assignment statement. The request computes the total settlement amount for each claim type within a file. Output consists of a 2-column table, giving a total amount for each type as well as a grand total settlement amount. </p> | |||
<p> | |||
For example:</p> | |||
<p class="code">BEGIN | <p class="code">BEGIN | ||
VARIABLES ARE STRING DP 2 | VARIABLES ARE STRING DP 2 | ||
Line 1,010: | Line 1,249: | ||
%GRANDTOT = '$' WITH %GRANDTOT | %GRANDTOT = '$' WITH %GRANDTOT | ||
PRINT 'GRAND TOTAL:' WITH %GRANDTOT TO COLUMN 36 | PRINT 'GRAND TOTAL:' WITH %GRANDTOT TO COLUMN 36 | ||
END | END | ||
</p> | </p> | ||
<p>Note that the user resets the value of %TOT to 0 after each pass through the value loop. Because %variables retain their values until explicitly reset, the user is responsible for clearing %variables that are to be reused. <var class="product">Model 204</var> does not perform this type of housekeeping routine automatically.</p> | <p> | ||
<p>The output resulting from the preceding request is:</p> | Note that the user resets the value of <code>%TOT</code> to 0 after each pass through the value loop. Because %variables retain their values until explicitly reset, the user is responsible for clearing %variables that are to be reused. <var class="product">Model 204</var> does not perform this type of housekeeping routine automatically.</p> | ||
<p> | |||
The output resulting from the preceding request is:</p> | |||
<p class="code"> TOTAL | <p class="code"> TOTAL | ||
CLAIM TYPE SETTLEMENT AMOUNT | CLAIM TYPE SETTLEMENT AMOUNT | ||
O 52905.00 | O 52905.00 | ||
C 53310.00 | C 53310.00 | ||
L 51773.00 | L 51773.00 | ||
GRAND TOTAL: $157988.00 | GRAND TOTAL: $157988.00 | ||
</p> | </p> | ||
<p>In most cases the | ==Using %variables in place of the Note statement== | ||
<p> | |||
<p>In this example, POLICY NO is assigned to a variable rather than a | In most cases the <var>Note</var> statement can be replaced with an assignment statement to achieve the same results. </p> | ||
====Example==== | |||
<p> | |||
In this example, <code>POLICY NO</code> is assigned to a variable rather than a <var>Note</var> statement:</p> | |||
<p class="code">BEGIN | <p class="code">BEGIN | ||
POL.HOLDERS: FIND ALL RECORDS FOR WHICH | POL.HOLDERS: FIND ALL RECORDS FOR WHICH | ||
Line 1,041: | Line 1,286: | ||
END FOR | END FOR | ||
END FOR | END FOR | ||
END | END | ||
</p> | </p> | ||
<p class="note"><b>Caution:</b> Some caution is required when substituting %variables for | <p class="note"><b>Caution:</b> Some caution is required when substituting %variables for <var>Note</var> statement values. The <var>Note</var> statement retains up to 255 characters, while an undeclared %variable retains only the default length set by the <var>VLEN</var> parameter. If a %variable is used for a long field value, the length parameter for the %variable must be reset to avoid truncation.</p> | ||
<p>Another difference between %variables and | ===Impact on STBL space=== | ||
<p> | |||
<p>Field name variables permit indirect reference to field names, thereby permitting many procedures and requests to be generalized without using dummy strings (refer to [[Procedures#Dummy strings in procedures|Dummy strings in procedures]] for a discussion). The actual field names used in a particular procedure or request are specified when the request is executed. Field name variables are extensions of the %variables described in the preceding section. </p> | Another difference between %variables and <var>Note</var> statement values is the use of space in the system work area STBL. For more information on STBL, refer to [[Large request considerations#STBL (character string table)|STBL (character string table)]].</p> | ||
<p>A field name %variable is indicated in this format:</p> | ==Field name variables== | ||
<p class="code">%%name | <p> | ||
Field name variables permit indirect reference to field names, thereby permitting many procedures and requests to be generalized without using dummy strings (refer to [[Procedures#Dummy strings in procedures|Dummy strings in procedures]] for a discussion). The actual field names used in a particular procedure or request are specified when the request is executed. Field name variables are extensions of the %variables described in the preceding section. </p> | |||
====Syntax==== | |||
<p> | |||
A field name %variable is indicated in this format:</p> | |||
<p class="code">%%name | |||
</p> | </p> | ||
<p>For example:</p> | <p> | ||
<p class="code">%%DISCOUNT | For example:</p> | ||
<p class="code">%%DISCOUNT | |||
</p> | </p> | ||
<p>During the evaluation phase of a request, a string value can be assigned to a %variable:</p> | ===Using field name variables=== | ||
<p class="code">%DISCOUNT = 'DISCOUNT' | <p> | ||
During the evaluation phase of a request, a string value can be assigned to a %variable:</p> | |||
<p class="code">%DISCOUNT = 'DISCOUNT' | |||
</p> | </p> | ||
<p>and that %variable can then be used in | <p> | ||
and that %variable can then be used in SOUL statements where field names normally appear, as in this example:</p> | |||
<p class="code">ADD.REC: STORE RECORD | <p class="code">ADD.REC: STORE RECORD | ||
%%DISCOUNT = .055 | %%DISCOUNT = .055 | ||
END STORE | END STORE | ||
</p> | </p> | ||
<p>A field name variable and a variable with identical names are actually the same variable. When the variable is used in %variable context (for example, on the left hand side of an assignment statement), it takes the usual %name form. If the same variable is used in a field name context (for example, to the left of an equal sign (=) in a FIND condition), it takes the %%name form. In the latter case, the value of the variable (when the | <p> | ||
A field name variable and a variable with identical names are actually the same variable. When the variable is used in %variable context (for example, on the left hand side of an assignment statement), it takes the usual %name form. If the same variable is used in a field name context (for example, to the left of an equal sign (=) in a FIND condition), it takes the %%name form. In the latter case, the value of the variable (when the <var>Find</var> statement is evaluated) is used as the field name. </p> | |||
====Example==== | |||
<p class="code">BEGIN | <p class="code">BEGIN | ||
START.REQUEST: %A = $READ('ENTER FIELD NAME') | START.REQUEST: %A = $READ('ENTER FIELD NAME') | ||
Line 1,081: | Line 1,338: | ||
JUMP TO START.REQUEST | JUMP TO START.REQUEST | ||
STOP.REQUEST: PRINT 'END OF REQUEST' | STOP.REQUEST: PRINT 'END OF REQUEST' | ||
END | END | ||
</p> | </p> | ||
<p>If the file consists of these two records:</p> | <p> | ||
If the file consists of these two records:</p> | |||
<p class="code">RECNO = 1 RECNO = 2 | <p class="code">RECNO = 1 RECNO = 2 | ||
AGE = 23 AGE = 1 | AGE = 23 AGE = 1 | ||
WEIGHT = 146 WEIGHT = 23 | WEIGHT = 146 WEIGHT = 23 | ||
</p> | </p> | ||
<p>and the user replies to the $READ prompts with:</p> | <p> | ||
and the user replies to the $READ prompts with:</p> | |||
<p class="code">AGE | <p class="code">AGE | ||
23 | 23 | ||
WEIGHT | WEIGHT | ||
23 | 23 | ||
QUIT | QUIT | ||
</p> | </p> | ||
<p>The output from the request is:</p> | <p> | ||
The output from the request is:</p> | |||
<p class="code">RECNO 1 AGE 23 | <p class="code">RECNO 1 AGE 23 | ||
RECNO 2 WEIGHT 23 | RECNO 2 WEIGHT 23 | ||
END OF REQUEST | END OF REQUEST | ||
</p> | </p> | ||
<p>The START.REQUEST and IF.QUIT statements use %A as a variable. When %A is used as a field name variable in the FIND condition of the MATCH.SET statement, it appears as %%A. In the PRINT.INFO statement, both %A and %%A are used. First the value of %A (the string value that represents the field name) is printed. Then %%A is used as a field name, printing the value of that field within the record.</p> | <p> | ||
The START.REQUEST and IF.QUIT statements use %A as a variable. When %A is used as a field name variable in the FIND condition of the MATCH.SET statement, it appears as %%A. In the PRINT.INFO statement, both %A and %%A are used. First the value of %A (the string value that represents the field name) is printed. Then %%A is used as a field name, printing the value of that field within the record.</p> | |||
<p>You need to be aware of the difference between the following statements:</p> | |||
<p class="code">FIELD.VAR: % | ===Assigning values to field name variables=== | ||
<p> | |||
STRING.VAR: % | You need to be aware of the difference between the following statements:</p> | ||
<p class="code">FIELD.VAR: %a = EMPLOYEE NUM | |||
STRING.VAR: %a = 'EMPLOYEE NUM' | |||
</p> | </p> | ||
<p>The FIELD.VAR statement assigns the value of the field named EMPLOYEE NUM from the current record to %variable | <p> | ||
<p>In contrast, the STRING.VAR statement assigns the character string | The FIELD.VAR statement assigns the value of the field named EMPLOYEE NUM from the current record to %variable <code>a</code>. The FIELD.VAR statement must appear within a <var>For Each Record</var> loop. </p> | ||
<p> | |||
<p>You can use subscripts with field name variables, as discussed in [[ | In contrast, the STRING.VAR statement assigns the character string <code>EMPLOYEE NUM</code> as the value of %variable <code>a</code>. If %variable <code>a</code> is to be used subsequently as a field name variable, it must contain a valid field name for the file(s) being examined by the request. </p> | ||
<p>For example, the field name variable reference:</p> | |||
<p class="code">%%DISCOUNT(5) | ===Subscripted field name variables=== | ||
<p> | |||
You can use subscripts with field name variables, as discussed in [[Processing multiply occurring fields and field groups#Subscripts|Subscripts]]. This is often useful in specifying indirect references to particular occurrences of multiply occurring fields. Any field name variable can be followed by a parenthesized expression. The value of this expression is used as a subscript that specifies the desired occurrence of the named field. </p> | |||
<p> | |||
For example, the field name variable reference:</p> | |||
<p class="code">%%DISCOUNT(5) | |||
</p> | </p> | ||
<p>refers to the fifth value of the field represented by the field name variable, %%DISCOUNT.</p> | <p> | ||
<p>The evaluation of subscript expressions is subject to the rules of assignment to an integer discussed earlier in this section.</p> | refers to the fifth value of the field represented by the field name variable, %%DISCOUNT.</p> | ||
<p>It is also possible for the field name variable being subscripted to be an element of an array. The format of such a reference is:</p> | <p> | ||
<p class="code">%%variable (a1 | The evaluation of subscript expressions is subject to the rules of assignment to an integer discussed earlier in this section.</p> | ||
<p> | |||
It is also possible for the field name variable being subscripted to be an element of an array. The format of such a reference is:</p> | |||
<p class="code">%%variable (a1 [, a2 [, a3] ]) (n) | |||
</p> | </p> | ||
<p>where a1, a2, and a3 are the subscripts of the array, and n is the occurrence subscript. For example:</p> | <p> | ||
<p class="code">%%ITEM(3,5) (4) | where a1, a2, and a3 are the subscripts of the array, and n is the occurrence subscript. For example:</p> | ||
<p class="code">%%ITEM(3,5) (4) | |||
</p> | </p> | ||
<p>indicates the fourth occurrence of the field. The actual value of the field name variable is saved as the element of the array, %ITEM, with subscripts (3,5). </p> | <p> | ||
indicates the fourth occurrence of the field. The actual value of the field name variable is saved as the element of the array, %ITEM, with subscripts (3,5). </p> | |||
<p>Some statements operate only on fields of a particular type. Such requirements usually are enforced when a request is compiled. The use of field name variables defers error checking until the request is evaluated and the values of the variables are known. The value of a field name variable is checked for the same errors as field names known at compilation time (a reference to an undefined field, an attempt to print an INVISIBLE field, a length error on a preallocated field, or a security access violation). If an error is detected the request evaluation is cancelled.</p> | |||
===Resolution of field types and levels=== | |||
<p>Cancellation of a request during a sequence of statement updates could leave a file in a logically inconsistent state. </p> | <p> | ||
<p>This occurs if a change is made before an incorrect reference to a field name variable, and also before a dependent change is made. A request that stores records using field name variables for some fields, or a request that operates on fields with security levels, could leave a file in an inconsistent state if an error occurs for one or more of the fields. The result might be a record without some or all of its fields. </p> | Some statements operate only on fields of a particular type. Such requirements usually are enforced when a request is compiled. The use of field name variables defers error checking until the request is evaluated and the values of the variables are known. The value of a field name variable is checked for the same errors as field names known at compilation time (a reference to an undefined field, an attempt to print an <var>INVISIBLE</var> field, a length error on a preallocated field, or a security access violation). If an error is detected the request evaluation is cancelled.</p> | ||
<p>The field type and security level of a variable can be checked before updating by using the $ | |||
====Possible file inconsistency==== | |||
<p> | |||
Cancellation of a request during a sequence of statement updates could leave a file in a logically inconsistent state. </p> | |||
<p> | |||
This occurs if a change is made before an incorrect reference to a field name variable, and also before a dependent change is made. A request that stores records using field name variables for some fields, or a request that operates on fields with security levels, could leave a file in an inconsistent state if an error occurs for one or more of the fields. The result might be a record without some or all of its fields. </p> | |||
<p> | |||
The field type and security level of a variable can be checked before updating by using the <var>[[$Dscr]]</var>, <var>[[$FlsAcc]]</var>, and <var>[[$FlsChk]]</var> functions.</p> | |||
</div> <!-- end of toc limit div --> | |||
[[Category:SOUL]] | [[Category:SOUL]] |
Latest revision as of 17:18, 29 May 2018
Overview
SOUL lets you use variables to represent values. You can use a SOUL variable, called percent variable (%variable), because variable names must start with a percent sign, any place in a SOUL statement that requires a value.
You can declare %variables for a single value or as an array. For the purposes of discussing SOUL, the term %variable is used to mean both a %variable and an element of a %variable array. The features discussed in this article enable you to generate additional information based on data in the file.
Special types of variables
In addition to the basic %variables (and variable arrays) discussed in this article, SOUL provides the following types of variables:
Type of variable | See... |
---|---|
Field name | Field name variables |
Screen variables | Full-screen variables |
Image variables | Defining image items and the sections that follow describing types of images |
%Variables as parameters | Flow of control in User Language |
Values
You can specify SOUL values by using:
- Literals (quoted strings)
- Numeric constants
- Field values (values derived from field retrievals)
- %Variables
SOUL performs value conversions on values, as described in this article.
Arithmetic operations
Using values and/or %variables, you can construct expressions to perform arithmetic operations, which are discussed in this article.
Default variable attributes
Model 204 parameters that set default attributes for variables
Model 204 parameters that set default attributes for variables lists three Model 204 parameters that establish the default type, length, and number of decimal places for all types of SOUL variables:
Parameter | Meaning | Default |
---|---|---|
VTYPE | Type: Fixed, Float, String, or Undefined | String |
VLEN | Length of String variables | 20 |
VDP | Number of decimal places in Fixed or String variables | 0 |
You can change the defaults established by these parameters as follows:
- The values of VTYPE, VLEN, and/or VDP can be changed by any user for the duration of the terminal session with the RESET command.
- The value of any of these parameters can be overridden for the duration of a request with the Variables Are statement.
- The variable type, length, and/or number of decimal places for any given variable can be explicitly specified in the declaration statement for that variable. This has the effect of overriding the respective values established by VTYPE, VLEN, and VDP, as well as the values established by the Variables Are statement.
VTYPE, VLEN, and VDP are discussed where relevant elsewhere in this article. Also, refer to the List of Model 204 parameters and List of Model 204 commands for more on user parameters.
Relationship between default values and variable declarations
A variable can be declared:
- Explicitly, in a declaration statement (see DECLARE statements for %variables)
- Implicitly, in an assignment statement (see Assignment statements). When a variable is declared implicitly, it takes on the attributes established by the VTYPE, VLEN, and VDP parameters (as modified by any Variables Are statement that may precede the assignment statement).
Variables Are statement
The Variables Are statement overrides, for the remainder of the current request, the default variable type, length, and/or number of decimal places established by the VTYPE, VLEN, and/or VDP parameters, or by an earlier Variables Are statement. It is particularly useful if you don't want to rely on VTYPE, VLEN, and VDP, and when most of the %variables used in a request are of the same type and length.
A Variables Are declaration has no effect on variables which have been declared (either implicitly or explicitly) earlier in the request. The defaults established by a Variables Are statement remain in effect until the next Variables Are declaration or until the end of the request, whichever comes first.
Syntax
The format of the Variables Are statement is:
Variables Are {Fixed [Dp n] | Float | String [Len n] [Dp {n | *}] | Undefined}
Variables Are Undefined statement
The Variables Are Undefined statement forces you to explicitly declare all variables. If this statement is used in a request and Model 204 encounters an undeclared variable, an error message is issued.
The Variables Are Undefined statement sets both the default Len and Dp options to 0. Therefore, when Variables Are Undefined is in effect, %variables declared as String must have the Len specified or an error message is issued.
Declaring %variables and %variable arrays
You can declare a variable and subsequently assign and reset that variable any number of times during a SOUL request. You can use a variable declaration statement to specify:
- Type of variable
- Length of the variable and number of decimal places
- Number of elements if the variable is an array
- Use of the optional field save feature
Variable arrays
Variables also can be declared to be arrays of up to three dimensions. An element of a %variable array is equivalent to a %variable that is not part of an array. It can be used anywhere that a %variable can be used.
Declare statements for %variables
To temporarily set or reset the default variable type, length, and number of decimal places for a particular %variable or %variable array in a request, use the Declare statement.
Syntax
In the following syntax diagrams, the first declaration statement is for numeric %variables and the second declaration statement is for string %variables
- Syntax for numeric %variables:
[Declare] %variable [Is] {Fixed [Dp n] | Float} [Array(d1 [,d2 [,d3]])] [Initial(numeric-expression)] [Static] [Common]
- Syntax for string %variables:
[Declare] %variable [Is] String [Len n] [Dp [n |*}] [Array(d1 [,d2 [,d3]])] [No Field Save] [Initial('EBCDIC-string' | expression)] [Static] [Common]
Where:
- The keyword Declare is optional.
- The Initial attribute assigns an initial value to a %variable at compilation time, without using any excess QTBL, STBL, or VTBL space and CPU usage. The Initial attribute is permitted only for numeric expressions or EBCDIC string variables, and not for arrays of any type or DBCS variables.
- The Static attribute limits assignment to a %variable to the Initial attribute and requires the Initial attribute to set the %variable's initial (and only) value.
- The various other components of this statement, except for Common, are described later in this article; Common is discussed in Common elements.
If you want to use the Common attribute on a %variable declaration with the Initial and Static attributes, the Common attribute must be the last token in the statement. For example:
%x is float initial (3) static common
Usage
%Variable Initial value assignment
An Initial value longer than the maximum length results in a compilation warning message:
M204.2493: VARIABLE TOO SMALL FOR INITIAL VALUE
Examples
The following examples use the Static or Initial attribute.
- In the first example, set %X to the value ABC, using the Static attribute. The value cannot be changed during request evaluation:
%X IS STRING LEN 3 INITIAL('ABC') STATIC
- The next example uses a %variable that can be changed during request evaluation:
%Y IS STRING LEN 3 INITIAL('ABC')
- The following compiler error message is displayed if you attempt to assign a value to a %variable that has been declared Static:
*** M204.0542: EDIT COMPLETE - GO *** 1 M204.2490: ILLEGAL ASSIGNMENT TO STATIC %VARIABLE %X=5 (FILE=CCATEMP, PROCEDURE=0, LINE=3) ==5 *** 2 M204.0228: PART OF STATEMENT IGNORED *** M204.1042: COMPILATION ERRORS
- The next example illustrates using the Static attribute and an expression with the Initial attribute.
BEGIN %X IS STRING LEN 3 INITIAL('ABC') STATIC %Y IS STRING LEN 3 INITIAL('DEF') STATIC %ALPHA IS STRING LEN 6 - INITIAL($SUBSTR(%X,2,1) WITH $SUBSTR(%Y,2,1)) STATIC PRINT %ALPHA END ***M204.0542:EDIT COMPLETE - GO BE
%Variable names
A variable name can consist of any number of letters, numbers, and some special characters (for example, underscore).
The first character of the name must be a percent sign (%).
The . (period) character is not allowed in the name of a variable that is declared as a Json object.
A variable name can have no embedded blanks, colons, or any of the following Model 204 reserved characters:
= | + | $ |
( | * | , (not sign — see Note below) |
) | ' | - (minus sign/hyphen) |
; | < | / |
, | > | : |
Note: The ,
reserved character is the EBCDIC "not sign," which has the hexadecimal value 5f
.
The following guidelines apply to certain special characters that are allowed in %variable names:
- The @ and # characters also are reserved, unless they are reset by the user through the FLUSH and ERASE parameters.
- Dummy string characters (??, ?$, ?&) can be used in variable names, but they perform dummy string substitution, as described in Using ?$ and ?& dummy strings.
Relationship to Variables Are statement
The type, length, and decimal place settings established for a particular %variable by a DECLARE %variable statement are not overridden by a Variables Are statement. For example, if the statement:
DECLARE %NAME STRING LEN 30
is followed by the statement:
VARIABLES ARE FIXED
then %NAME
remains a string of length 30.
%Variable types
A %variable can be declared as one of several distinct types:
- Fixed (fixed-point numeric)
- Float (floating-point numeric)
- String (alphanumeric string)
And these, as of Version 7.5 of Model 204:
- Unicode (Unicode string)
- Longstring (string with very large maximum size)
- Object (reference to an instance of a class)
- A method variable (a variable that references a method)
Using Fixed or Float for arithmetic statements
Defining %variables as Fixed or Float improves the performance of arithmetic statements. If the result of an arithmetic operation is being assigned to a %variable, the result is not converted before assignment if the arithmetic operands are of the same type.
Arithmetic operations are performed most efficiently if all %variables are defined with matching options: either as Float or as Fixed, and with no decimal places or the same number of decimal places. To operate Model 204 as efficiently as possible, avoid mixed-type arithmetic. Use String variables only when string manipulations are required.
An arithmetic operation where both operands are Fixed requires rules to determine the scale (number of decimal places) of the result. See Fixed precision arithmetic for detailed information on the way Model 204 handles Fixed arithmetic operations.
Arithmetic result types
Arithmetic result types shows the types and the results for various combinations of operands in an arithmetic statement. The result described in the table refers to the result of an arithmetic operation, which might be an intermediate result. If the final result is being assigned to a %variable of a different type, it is converted to match.
Operand 1 | Operand 2 | Arithmetic result type |
---|---|---|
Float | Float | Float |
Float | Fixed | Float |
String | Float | Float |
String | String | Float |
String | Fixed | Fixed |
Fixed | Fixed | Fixed |
%Variable lengths
Fixed %variables
%Variables declared as Fixed can have a decimal place specification associated with them. For example:
Declare %total Fixed dp 2
represents a dollar total. A Fixed %variable can contain as many as 15 significant digits, including decimal places. There can be as many as 9 decimal places.
Float %variables
Variables declared as Float are stored as double-precision floating-point numbers. Precision is guaranteed to 15 decimal digits; the exponent must be between 75 and -74.
String %variables
Variables declared as String can have a maximum length as well as an optional decimal place specification associated with them. For example:
DECLARE %NAME STRING LEN 20 DP 2 VARIABLES ARE STRING LEN 7
The first statement (above) declares the %NAME variable as String, with a maximum length of 20 and two decimal places. The second statement sets the defaults for %variables not explicitly declared: String with a maximum length of 7 and no decimal places.
Additionally, the decimal place for String %variables can be variable by specifying DP *. This causes all decimal digits to be placed in the string. For example:
BEGIN %AMOUNT IS STRING LEN 10 DP * %AMOUNT = 1.2 PRINT %AMOUNT %AMOUNT = 1.23 PRINT %AMOUNT %AMOUNT = 1.234 PRINT %AMOUNT END
Yields:
1.2 1.23 1.234
The maximum length of a String variable is 255 characters. Decimal places, and the decimal point itself, are included in the specified length. Alternatively, the default values for length and decimal places can be used. An attempt to store a value longer than the declared or default length results in truncation.
The current length of a String variable is determined by the value put into the String variable. You can use the $Len function to find the current length of a String variable.
If the Variables Are Undefined statement is used, the values for length and decimal places must be specified with each String %variable declaration.
%Variable arrays
You can define %variables as arrays of one, two, or three dimensions with the Declare %variable statement. For example:
DECLARE %CODES STRING LEN 5 ARRAY(100)
defines a one-dimensional array of up to 100 message codes, each five characters in length.
DECLARE %TRANSACTION FIXED DP 2 ARRAY(12,10000)
defines a two-dimensional array of dollar transactions for a store. The array contains up to 10,000 transactions for each of 12 departments.
DECLARE %READINGS FLOAT ARRAY(3,10,80)
defines a three-dimensional array consisting of up to 80 atmospheric readings of three distinct types from 10 monitoring stations.
Array elements must be of one type
All elements of an array must have the same type (Fixed, Float, or String) and element length.
%Variable array references
An array can be referred to only after it has been declared in an array can have as many as three declared dimensions. A subscript value must be supplied for each dimension.
If a variable is declared as an array, it must always be referenced with subscripts.
Each of the subscript values that refers to a dimension can be a number or an expression. For example:
%CODE(2) %READING(3,200-%A/%B,%N)
As shown in the examples, the expression can contain references to other %variables. The subscript value is converted to an integer. Any fraction is truncated before the subscript value is used as the array subscript. The subscript value must fall within the declared range of dimensions.
No Field Save option
When a String %variable array is declared, you can specify:
No Field Save
If you do not intend to use any of the String array elements as field name variables, you should select the No Field Save option, to save space in the user work areas described in STBL (character string table). (Field name variables are discussed in detail on Field name variables.)
An element of a String array can be used as a field name variable even if No Field Save is specified. However, when the value of the element is referred to as a field name, extra processing and additional disk I/O are required for each reference after the first.
Assigning values to %variables
Assignment statements
Syntax
The format of the statement used to calculate and assign the value of %variables is:
%variablename = expression
The name of the %variable to be set appears to the left of the equal sign and the expression to whose value the %variable is to be set is at the right. (See also Expressions.)
For Large Object data, a compiler error is issued when the right side of the equal sign is expected to contain a BUFFER expression and it does not.
M204.2691: BUFFER ASSIGNMENT MUST REFERENCE LARGE OBJECT FIELD
and/or
M204.2704: BUFFER REFERENCE REQUIRES LOB FIELD
Example
These statements are valid assignments:
%AGENT = AGENT %NAME = 'DALE STERN' %RESULT = (%INCREASE + TOTAL PREMIUM) * .01
Note that %AGENT
is legal as a variable name even if AGENT
is a field name in the file. The variable and the field are not related to each other.
Relationship between %variable assignment and declaration
Normally, an assignment statement precedes a %variable reference in another statement. If a %variable is going to be declared with the Declare %variable statement, the declaration must precede the first use of the %variable. If an assignment statement does not precede the %variable reference, or the variable has not been declared, then default values (null values for String types, 0 for Fixed and Float) are assigned to the %variable.
Truncation vs. rounding on assignment
In an assignment statement, it is possible for the length of the assigned value to exceed the maximum length for that %variable (as determined in the variable declaration statement, the Variables Are statement, or the value of the VLEN or VDP parameter). The way Model 204 treats this situation depends on the %variable type.
- For Float %variables, the assigned value is rounded to 15 significant digits.
- For Fixed %variables, if the number of places to the left of the decimal point in the assigned value, plus the number of decimal places declared (not assigned) exceeds 15, Model 204 returns an error message and assigns a value of zero. Otherwise, if the number of decimal places assigned exceeds the number declared, Model 204 truncates the assigned value to the number of decimal places declared. For example, the following request:
BEGIN %X IS FIXED DP 0 %Y IS FLOAT %Z IS FLOAT %X = 1.9 %Y = 5 %Z = %X * %Y PRINT '%X = ' WITH %X PRINT '%Y = ' WITH %Y PRINT '%X * %Y = ' WITH %Z END
results in this output:
%X = 1 %Y = 5 %X * %Y = 5
The value of %X is truncated from 1.9 to 1 upon assignment for both display and computation.
- For String %variables, if the number of characters in the assigned value exceeds the maximum declared length (or, if not declared, the default length set by the VLEN parameter), the assigned value is truncated to the maximum length allowed.
Changing %variable values
You can change the value of a %variable at any point in a request by using an assignment statement. The variable is stored for the duration of the request that assigns it, including any continuations, and is then deleted.
At the beginning of a request, all %variables are set equal to a null string, or to zero, depending on their types.
During a request, a %variable can be set equal to another %variable, a quoted string, a number, a field value, a noted value, a function, a count of records or field occurrences, an occurrence number, a null value, or the result of a computation.
Understanding Initial processing
Code written using an Initial assignment for both %variables results in the assigned value of %X
as the Initial value assigned for %Y
as both assignments are resolved at compilation. For example:
BEGIN %X IS STRING LEN 1 INITIAL(1) * %X assigned the INITIAL value of 1, at compilation %Y IS FIXED INITIAL(%X) * %Y assigned the INITIAL value of %X, at compilation PRINT 'Y = ' %Y END Y = 1
An Initial value assignment in the format %Y IS FIXED INITIAL (%X)
, will not resolve to the value of %X
, if %X
was assigned in the format %X=1
. %X=1
format variable assignments are resolved at evaluation, subsequent to compilation. Initial value assignments are resolved at compilation.
The following code reflects this processing:
BEGIN %X IS STRING LEN 1 %X = 1 * %X assigned the value of 1 at evaluation %Y IS FIXED INITIAL(%X) * %Y assigned the INITIAL value at compilation PRINT 'Y = ' %Y END Y = 0
The %X
value is assigned at evaluation. The Initial value is assigned at compilation, prior to the evaluation of %X=1
. The result is that %Y
is assigned the default value, zero (0), for its type of Fixed.
Expressions
Expressions are evaluated by Model 204 and used to assign values to %variables and function arguments, or included as operands in computation or conditional statements.
Syntax
An expression has this format:
{operand | (expression)} [operator {operand | (expression)}]...
Where:
- operand is one of the following:
- %%variable (field name variable)
- %variable or element of %variable array
- Count In label
- Field name
- Function
- Number
- Occurrence In label
- Quoted string
- Value In label
- operator can be arithmetic, Boolean, comparison, or concatenation.
Operator order of precedence
The following table lists the operators used within expressions in order of precedence. Parentheses can be used to override the order.
Order of precedence | Operator |
---|---|
First | IS PRESENT, IS NOT PRESENT |
Second | - (unary minus) |
Third | *,/ |
Fourth | +,- |
Fifth | WITH |
Sixth | EQ, =, LE, <=, GT, >, GE, >=, NE, ,=, LT, IS [NOT] LIKE |
Seventh | NOT |
Eighth | AND |
Ninth | OR |
Tenth | AND (implied by a new line; occurs only in an If statement) |
Notes:
- The first character (
,
) of the inequality test above is the EBCDIC "not sign", which has the hexadecimal value5f
.- For a description of the
IS [NOT] LIKE
clauses, see the syntax of Is Like patterns.
Incomplete expressions
Incomplete expressions, such as the following:
IF %X = 10 OR %Y > 40 AND %A = %B WITH
produce this message:
M204.0052 ILLEGAL TERM
Compilation does not succeed and the procedure does not run.
Using expressions for value retrieval
You can use expressions for value retrieval in the following SOUL statements:
- Update statements (Store Record, Add, Change, Delete, Insert)
- File Records
- Find
- Find...Point$ condition
- Find...Sfl$ and Find...Sfge$ conditions
- For Each Record In Order By
- For Each Record Where
- Find All Values
- For Each Value
- For Record Number
Expression types supported in SOUL statements
The following table provides examples of the types of expressions that you can use to supply retrieval values for statements.
Expression type | Example |
---|---|
Function call | In ?&File Fd ORDER.DATE Eq Value($Date(1,'')) |
String concatenation | In ?&File Fd BIRTH.DATE Eq Value(%yyyy With %mm With %dd) |
Arithmetic operation | In ?&File Fd SALES.VALUE Eq Value(%item.value * %item.sales) |
SOUL construct | In ?&File Fd NUM.ORDERS Eq Value(Count In FD.ORDERS) |
Boolean expression | In ?&File Fd ORDER.STATUS Eq Value(%status Is Like 'A*') |
Example
The following example shows these different types of expressions used as values.
B %MM IS STRING LEN 2 %DD IS STRING LEN 2 %BASE.PREMIUM IS FLOAT %PCT.INCREASE IS FLOAT * * function call expression * PRINT 'FD1' FD1: IN CLIENTS FPC INCIDENT DATE EQ - VALUE($DATECHG('YYYYMMDD',$DATE(1,''),-3169)) END FIND FR FD1 PAI PRINT END FOR * * string concatenation expression * PRINT 'FD2' %MM = '09' %DD = '17' FD2: IN CLIENTS FPC ANNIV DATE EQ VALUE(%MM WITH %DD) END FIND FR FD2 PAI PRINT END FOR * * arithmetic operation expression * PRINT 'FD3' %BASE.PREMIUM = 1280 %PCT.INCREASE = 1.25 FD3: IN CLIENTS FPC TOTAL PREMIUM EQ VALUE(%BASE.PREMIUM * %PCT.INCREASE) END FIND FR FD3 PAI FEO1: FEO VIN * * UL syntax expression * PRINT 'FD4' FD4: IN VEHICLES FPC VIN EQ VALUE(VALUE IN FEO1) END FIND FR FD4 PAI PRINT END FOR END FOR END FOR * * boolean expression * PRINT 'FD5' FD5: IN CLIENTS FPC INCIDENT EQ VALUE('T' WITH (%DD IS LIKE '1*')) END FIND FR FD5 PAI PRINT END FOR END
Operators
This section describes the use of four types of operators:
- Arithmetic
- Comparison
- Boolean
- With
See the previous section for a discussion of expressions, and the next section for a discussion of operands. See Fixed precision arithmetic for a more detailed discussion.
Arithmetic operators
The following table lists the arithmetic operators:
+ | Addition |
---|---|
- | Subtraction, unary minus |
* | Multiplication |
/ | Division |
Order of operations
The arithmetic operators are used to compute the value of a %variable or they can be included in an expression. When an expression contains several arithmetic operations, the operations are performed in the order shown in Operator order of precedence. Operators of equal precedence are evaluated in order of appearance, from left to right. For example:
%result = 8*7 + 4
sets %result
to 60.
Parentheses change the order of operations; expressions within parentheses are compiled first. For example:
4-5*2*3 = -26 (4-5)*(2*3) = -6 (4-(5*2))*3 = -18
Arithmetic overflow
An arithmetic overflow might occur during evaluation of a computation statement. If such an overflow occurs, the request is cancelled and an appropriate error message is issued.
Comparison operators
The following comparison operators are used to compare two objects, two strings, two numbers, or a string and a number:
Operator | Meaning |
---|---|
EQ, = | Equal |
NE, ^= | Not equal |
GT, > | Greater than |
LT, < | Less than |
GE, >= | Greater than or equal to |
LE, <= | Less than or equal to |
IS [NOT] LIKE | Pattern matching equivalents |
IS [NOT] PRESENT | Field existence |
When a comparison operator is included in an expression, a value of 1 results if the stated relation between operands is true; if false, a value of 0, provided that one of the following conditions apply (using the expression %I = (%A<=%B)
to illustrate):
- Either %A or %B (or both) is declared as Fixed or Float.
- Either %A or %B (or both) is signed in the expression; for example,
%I = (+%A <=%B)
. - VTYPE = FLOAT or FIXED, and VLEN is greater than zero.
The resulting value returned from the expression might be invalid if all the following conditions apply:
- Neither %A nor %B is declared.
- The expression does not sign the variable.
- The system default for VTYPE is String and VLEN is greater than zero.
Notes:
- See the discussion about the conditional statement in Comparison operators for a description of these operators in conditional statements.
- The first character (
,
) of the inequality test above is the EBCDIC "not sign", which has the hexadecimal value5f
.- For a description of the
IS [NOT] LIKE
clauses, see the syntax of Is Like patterns.
Boolean operators
Use the Boolean operators listed in the following table to modify or link together comparison expressions. (See the discussion about Boolean operators and conditional statements for information on comparisons.)
Operator | Meaning |
---|---|
Not | The value of the comparison is reversed. |
And | Both comparisons must be true. |
Or | Either comparison must be true. |
Boolean operators are not restricted to comparisons. They also can be used in the middle of expressions (for example, 1 AND 2
).
With operator
With can be used in an expression to concatenate two strings. For example:
%A = '$' WITH TOTAL PREMIUM PRINT %A TO COLUMN 10
results in:
$550 $1092 $605
Operands
This section describes the use of four types of operands:
- %variables
- Quoted strings
- Numbers
- Fields
See also
Variables as operands
After you define a %variable, you can use it to change other %variables. For example:
%COUNT = %NUM
sets %COUNT
, and:
%COUNT = %COUNT + 1
replaces the value of %COUNT%COUNT
by its former value plus 1.
Quoted strings
Examples of %variables set to quoted strings are provided here:
%NAME = 'TETLEY' %AGE = '53' %TITLE = 'QUARTERLY REPORT' %SPOUSE =
In the preceding example, %SPOUSE
is a quoted string that has a length of 0.
Additional information about the use of quotation marks is provided in Quotation marks.
Numbers
A number used as the value of a %variable or as a term in an expression can be a string of digits containing an optional sign and an embedded decimal point.
For example:
3 +0.002 45.7 -37
The magnitude of the number is limited by the magnitude of the largest number that can be represented in a floating point number. Therefore the number's exponent (if the number is expressed in exponent notation) must be between 75 and -74.
Fields
Field values, referred to by field name, can be used in an assignment statement, but only inside a FOR EACH RECORD loop. To evaluate an expression, Model 204 uses the value of the field for the current record each time through the loop. For example:
FOR EACH RECORD IN FIND.RECS %PROFIT = %INCREASE - TOTAL PREMIUM PRINT %PROFIT END FOR
calculates profit from the data in each record and prints it. %PROFIT
changes for each record.
In expressions, the values of most types of fields are treated as character strings. The values of fields defined with the FLOAT attribute are treated as numbers. If a field is missing from a record being processed, the value used is a null string.
Fixed precision arithmetic
An arithmetic operation where both operands are Fixed requires rules to determine the scale (maximum numbers of digits and decimal places) of the result.
Scale of intermediate results
Model 204 determines the scale of intermediate results (the number of decimal places) using the following rules.
Addition and subtraction
When an expression requires either addition or subtraction, the scale of the temporary variable containing the result equals the larger of the scales of the two operands. For example, the scale for the result of the following expression is 3:
12.345 + 3.6
If the result exceeds 15 digits, decimal places are dropped from the right to produce the largest possible scale that fits in 15 digits. If a 15 digit number cannot be produced even by dropping all decimal places, an overflow condition is indicated.
Multiplication
When an expression requires multiplication, the scale of the temporary variable containing the result is equal to the sum of the scales of the two operands. For example, the scale for the result of the following expression is 5 (3+2):
12.345 * 3.64
If the sum of the scales of the operands exceeds 9 or if the result is larger than 15 digits, decimal places are dropped from the right to produce the largest possible scale that fits in 15 digits. As with addition and subtraction, if the result has more than 15 digits with all decimal places discarded, an overflow condition is indicated.
Division
When an expression requires division, the scale of the temporary variable containing the result is equal to the larger of:
- 9
- the largest possible scale that fits in 15 digits
For example, the scale for the result of this expression is 9 (the calculated result is 3.529411764):
12 / 3.4
Causes of overflow conditions
The following situations are treated as overflow conditions:
- When the integer portion of any intermediate or final result is larger than 15 digits.
- For addition and multiplication, when the scale of the final result variable is so large that the integer portion of the result cannot fit into the maximum allotted size. For example:
BEGIN %A IS FIXED DP 0 %B IS FIXED DP 0 %C IS FIXED DP 9 %A = 999999 %B = 1 %C = %A + %B PRINT 'C = ' %C END *** M204.0542: EDIT COMPLETE - GO *** M204.0552: VARIABLE TOO SMALL FOR RESULT C = 0.000000000
Because the scale of the variable which contains the final result (%C) is 9, the integer portion of the result is limited to no more than 6 digits. Because the integer portion of the result requires 7 digits, an overflow condition is triggered.
This example illustrates that Model 204 takes into consideration the scale of the final result variable. The example below is identical to the one above except that the scale of %C is set to 8. The request executes successfully because this frees the required 7 digits for the integer portion of the result:
BEGIN %A IS FIXED DP 0 %B IS FIXED DP 0 %C IS FIXED DP 8 %A = 999999 %B = 1 %C = %A + %B PRINT 'C = ' %C END *** M204.0542: EDIT COMPLETE - GO C = 1000000.00000000
How Model 204 responds to overflow conditions
Overflowing to zero
When Model 204 detects an overflow condition, the intermediate result is set to 1015. Since this is a 16-digit number, it is illegal in SOUL and tends to cause a cascade of overflow conditions in a complex expression, which can generate the following error message:
M204.0552: VARIABLE TOO SMALL FOR RESULT
The final result of the expression is usually 0, which lets you see that an overflow error might have occurred.
Overflowing to very large, obviously incorrect number
An exception to the rule of a 0 final result is the case where an overflow occurs in an intermediate step and the next step (whether intermediate or final) involves subtracting a value whose scale is 0 so that the result is less than 1015. In this case, you get a large, incorrect, result. For example:
BEGIN %X IS FIXED DP 0 %Y IS FIXED DP 0 %Z IS FIXED DP 0 %X = 10E13 %Y = 350000 %Z = 10 * (%X * %Y) WILL OVERFLOW AND BECOME 10E15 %X = (%X * %Y) - %Z PRINT 'X =' %X END *** M204.0542: EDIT COMPLETE - GO *** 1 M204.0563: ARITHMETIC OVERFLOW X = 999999999999990
Value In, Count In, and Occurrence In phrases
You can set a %variable value based on the following elements of a SOUL request:
- Value In phrase
A %variable can be set equal to a noted value, as illustrated below:
%DRIVER = VALUE IN NOTE.DRIVER
This phrase also can be included in an expression or used to include the current value in a For Each Occurrence or For Each Value loop.
- COUNT IN phrase
A %variable can be set equal to the number of records counted, as in:
%COUNT = COUNT IN NO.OF.VINS
This phrase also can be included in an expression.
- OCCURRENCE IN phrase
A %variable can be set equal to the subscript value of the current occurrence of a field in a record, as in:
%OCCUR = OCCURRENCE IN INCIDENT.TYPE
where INCIDENT.TYPE is the statement label of a For Each Occurrence statement. This phrase also can be included in an arithmetic expression.
Conversions and significant digits
Numeric terms
The following expression terms are considered numeric:
- Literal (unquoted) numbers: -3, .0079
- Count In phrases
- Occurrence In phrases
- Some functions (see List of mathematical $functions)
- Results of numeric expressions
- Fixed or Float %variables
- FLOAT fields
Character terms
The following expression terms are considered character:
- Quoted strings: 'SMITH', '.0079'
- Non-FLOAT fields: NAME, ADDRESS
- Value In phrases
- Some functions (see $Functions)
- String %variables
Conversion
In the expression AGE + 10
, the value of the field AGE (character) is added to a literal number (numeric). Model 204 converts the value of AGE to a number. If the value is a proper number (for example, 5, -3.943, +.0003), the conversion is obvious; if not, the value is not a proper number (for example, FIVE, ", ABCD) or a number with too many digits, it is converted to a zero.
In the expression 'NUMBER' WITH -3.8
, a quoted string is to be concatenated with a number. Model 204 first converts the number to a character string. In such a conversion, all decimal places are lost; the number is truncated to an integer and the result is NUMBER-3.
Significant digits in computations
SOUL can accept as input to computations the largest floating point number that can be expressed in exponent notation and can produce results of that magnitude.
However, all results contain at most 15 significant decimal digits, with zeros in the low-order positions. Model 204 preserves 15 digits in all intermediate results, rounding each result to 15 digits before going on to the next intermediate calculation.
If the final result is assigned to a String %variable, that result is truncated on the right to the maximum length specified for the %variable.
Sample request using %variables
The following request illustrates an assignment statement. The request computes the total settlement amount for each claim type within a file. Output consists of a 2-column table, giving a total amount for each type as well as a grand total settlement amount.
For example:
BEGIN VARIABLES ARE STRING DP 2 SET HEADER 2 'TOTAL' TO COLUMN 34 SET HEADER 3 'CLAIM TYPE' - WITH 'SETTLEMENT AMOUNT' TO COLUMN 40 SET HEADER 4 NEW PAGE EACH.TYPE: FOR EACH VALUE OF CLAIM TYPE TYPE.MATCH: FIND ALL RECORDS FOR WHICH CLAIM TYPE = VALUE IN EACH.TYPE END FIND FOR EACH RECORD IN TYPE.MATCH %TOT = %TOT + SETTLEMENT AMOUNT END FOR PRINT VALUE IN EACH.TYPE AT COLUMN 6 - WITH %TOT TO COLUMN 36 %GRANDTOT = %GRANDTOT + %TOT %TOT = 0 END FOR SKIP 1 LINE %GRANDTOT = '$' WITH %GRANDTOT PRINT 'GRAND TOTAL:' WITH %GRANDTOT TO COLUMN 36 END
Note that the user resets the value of %TOT
to 0 after each pass through the value loop. Because %variables retain their values until explicitly reset, the user is responsible for clearing %variables that are to be reused. Model 204 does not perform this type of housekeeping routine automatically.
The output resulting from the preceding request is:
TOTAL CLAIM TYPE SETTLEMENT AMOUNT O 52905.00 C 53310.00 L 51773.00 GRAND TOTAL: $157988.00
Using %variables in place of the Note statement
In most cases the Note statement can be replaced with an assignment statement to achieve the same results.
Example
In this example, POLICY NO
is assigned to a variable rather than a Note statement:
BEGIN POL.HOLDERS: FIND ALL RECORDS FOR WHICH RECTYPE = POLICYHOLDER END FIND FOR EACH RECORD IN POL.HOLDERS %POLICY.NO = POLICY NO EACH.POL.NO: FIND ALL RECORDS FOR WHICH POLICY NO = %POLICY.NO RECTYPE = DRIVER END FIND FOR EACH RECORD IN EACH.POL.NO PRINT %POLICY.NO AND FULLNAME END FOR END FOR END
Caution: Some caution is required when substituting %variables for Note statement values. The Note statement retains up to 255 characters, while an undeclared %variable retains only the default length set by the VLEN parameter. If a %variable is used for a long field value, the length parameter for the %variable must be reset to avoid truncation.
Impact on STBL space
Another difference between %variables and Note statement values is the use of space in the system work area STBL. For more information on STBL, refer to STBL (character string table).
Field name variables
Field name variables permit indirect reference to field names, thereby permitting many procedures and requests to be generalized without using dummy strings (refer to Dummy strings in procedures for a discussion). The actual field names used in a particular procedure or request are specified when the request is executed. Field name variables are extensions of the %variables described in the preceding section.
Syntax
A field name %variable is indicated in this format:
%%name
For example:
%%DISCOUNT
Using field name variables
During the evaluation phase of a request, a string value can be assigned to a %variable:
%DISCOUNT = 'DISCOUNT'
and that %variable can then be used in SOUL statements where field names normally appear, as in this example:
ADD.REC: STORE RECORD %%DISCOUNT = .055 END STORE
A field name variable and a variable with identical names are actually the same variable. When the variable is used in %variable context (for example, on the left hand side of an assignment statement), it takes the usual %name form. If the same variable is used in a field name context (for example, to the left of an equal sign (=) in a FIND condition), it takes the %%name form. In the latter case, the value of the variable (when the Find statement is evaluated) is used as the field name.
Example
BEGIN START.REQUEST: %A = $READ('ENTER FIELD NAME') IF.QUIT: IF %A EQ 'QUIT' THEN JUMP TO STOP.REQUEST END IF %B = $READ('ENTER VALUE') MATCH.SET: FIND ALL RECORDS FOR WHICH %%A = %B END FIND FOR EACH RECORD IN MATCH.SET PRINT.INFO: PRINT 'RECNO ' WITH RECNO - WITH %A AT COLUMN 15 AND %%A END FOR JUMP TO START.REQUEST STOP.REQUEST: PRINT 'END OF REQUEST' END
If the file consists of these two records:
RECNO = 1 RECNO = 2 AGE = 23 AGE = 1 WEIGHT = 146 WEIGHT = 23
and the user replies to the $READ prompts with:
AGE 23 WEIGHT 23 QUIT
The output from the request is:
RECNO 1 AGE 23 RECNO 2 WEIGHT 23 END OF REQUEST
The START.REQUEST and IF.QUIT statements use %A as a variable. When %A is used as a field name variable in the FIND condition of the MATCH.SET statement, it appears as %%A. In the PRINT.INFO statement, both %A and %%A are used. First the value of %A (the string value that represents the field name) is printed. Then %%A is used as a field name, printing the value of that field within the record.
Assigning values to field name variables
You need to be aware of the difference between the following statements:
FIELD.VAR: %a = EMPLOYEE NUM STRING.VAR: %a = 'EMPLOYEE NUM'
The FIELD.VAR statement assigns the value of the field named EMPLOYEE NUM from the current record to %variable a
. The FIELD.VAR statement must appear within a For Each Record loop.
In contrast, the STRING.VAR statement assigns the character string EMPLOYEE NUM
as the value of %variable a
. If %variable a
is to be used subsequently as a field name variable, it must contain a valid field name for the file(s) being examined by the request.
Subscripted field name variables
You can use subscripts with field name variables, as discussed in Subscripts. This is often useful in specifying indirect references to particular occurrences of multiply occurring fields. Any field name variable can be followed by a parenthesized expression. The value of this expression is used as a subscript that specifies the desired occurrence of the named field.
For example, the field name variable reference:
%%DISCOUNT(5)
refers to the fifth value of the field represented by the field name variable, %%DISCOUNT.
The evaluation of subscript expressions is subject to the rules of assignment to an integer discussed earlier in this section.
It is also possible for the field name variable being subscripted to be an element of an array. The format of such a reference is:
%%variable (a1 [, a2 [, a3] ]) (n)
where a1, a2, and a3 are the subscripts of the array, and n is the occurrence subscript. For example:
%%ITEM(3,5) (4)
indicates the fourth occurrence of the field. The actual value of the field name variable is saved as the element of the array, %ITEM, with subscripts (3,5).
Resolution of field types and levels
Some statements operate only on fields of a particular type. Such requirements usually are enforced when a request is compiled. The use of field name variables defers error checking until the request is evaluated and the values of the variables are known. The value of a field name variable is checked for the same errors as field names known at compilation time (a reference to an undefined field, an attempt to print an INVISIBLE field, a length error on a preallocated field, or a security access violation). If an error is detected the request evaluation is cancelled.
Possible file inconsistency
Cancellation of a request during a sequence of statement updates could leave a file in a logically inconsistent state.
This occurs if a change is made before an incorrect reference to a field name variable, and also before a dependent change is made. A request that stores records using field name variables for some fields, or a request that operates on fields with security levels, could leave a file in an inconsistent state if an error occurs for one or more of the fields. The result might be a record without some or all of its fields.
The field type and security level of a variable can be checked before updating by using the $Dscr, $FlsAcc, and $FlsChk functions.