SQR Substitution Variables | KEVIN RESCHENBERG 07-26-2004 |
SQR provides an easy text-replacement feature that we can use to improve
code readability and ease of maintenance. Called "substitution variables," these
are more like the constants included in some languages or, maybe more accurately,
the preprocessor in C.
To create a substitution variable, use a #define directive:
#define SAVINGS_PLAN_TYPE '40'
Later in your code, you can use this value by enclosing it in curly braces:
if $PlanType = {SAVINGS_PLAN_TYPE}
This is exactly equivalent to:
if $PlanType = '40'
It is important to note that this is strictly a text-replacement function. We are not defining string or numeric
variables, but simply pieces of text. The example above could be rewritten without the quotes around the value "40":
#define SAVINGS_PLAN_TYPE 40
...
if $PlanType = '{SAVINGS_PLAN_TYPE}'
...
Since the defined substitution variable did not include the quotes, we provide them later. The effect is exactly
the same as in the first example.
Why do any of this at all? First, substitution variables can be used to give a name to what
would otherwise be a "magic cookie" type of value. The line if $PlanType = '40'
tells us nothing about what the value '40' represents. Calling it {SAVINGS_PLAN_TYPE} instead improves readability.
You could, of course, set a regular variable such as $SavingsPlanType to this value, but would have no guarantee that
this variable retains its value throughout the program.
Another small advantage to using substitution variables is that you can place them right at the top of the
program, where they can be modified easily as needed. They do not need to be part of a procedure. They can be
placed anywhere before they are used, even on the first line of the SQR file:
#define OUTPUT_FILE_NAME enrollment.txt
begin-program
...
begin-procedure Open-File
open '{FILEPREFIX}{OUTPUT_FILE_NAME}' as 1 for-writing ...
...
Where did {FILEPREFIX} come from? It's defined within the standard PeopleSoft-delivered SETENV.SQC, and
has a value such as C:\TEMP\ for NT or /usr/tmp/ for Unix. In this example, if SQR is running under
Unix, the program will open file /usr/tmp/enrollment.txt.
Substitution variables can also control the actual
interpretation of the program. Whenever you #define a
substitution variable, even if you don't give it a value, the SQR interpreter remembers this. We can then
use #ifdef to mark sections of code that SQR should
use or skip. We can also use #ifdef to conditionally
define other substitution variables. The standard include files delivered by PeopleSoft make extensive use
of this capability. There is also an #if directive that
can be used for control over conditional compilation. This post is running a little long, so
I'll show some of these tricks next week.
Let me close with an important point. These substitution variables are defined during the initial
scan of the program, before the program even starts to run. Their values (if any) are in effect for
all code located physically below the definition in the program. The flow of control in the program
is completely irrelevant. For example, the following code will not do what the programmer intended:
#if $RunControlOption = 'S'
#define PLAN_TYPE '40' ! Savings plan WRONG
end-if
This is incorrect because the value of {PLAN_TYPE} will be '40' regardless of the value of
$RunControlOption. The #define takes effect
before the program even starts, and the value of {PLAN_TYPE} will be '40' for every line in the
program following this one (unless it is redefined later). The following example suffers from
the same flaw:
#define PLAN_TYPE '10' ! Health
do Get-Elections
#define PLAN_TYPE '20' ! Life WRONG
do Get-Elections
#define PLAN_TYPE '40' ! Savings
do Get-Elections
Here the procedure Get-Elections will see {PLAN_TYPE} as '40' every time it runs, which is
certainly not what was intended. If procedure Get-Elections is physically located earlier
in the program, {PLAN_TYPE} won't even be defined and SQR will report a syntax error.
It is for this reason that I recommend placing #define
at column 1, out of the normal indentation of the program, to highlight the fact that it is
not part of the flow of control.
Next week we'll look at SETENV.SQC and talk about some of the other uses of these directives.
|