All programs/modules have the following:
1) An Externally Described Data Structure which contains the "Standard
Company Definitions." Such as:
* All function keys, roll keys, enter keys, etc
* Company related variables: valid customer, invalid cust, etc
2) In the *Inzsr subr, the first thing all programs do is the
following:
Call 'STDDFNRG'
Parm STDDFN
3) The program STGDFNRG accepts the parm, and fills all variables with
the proper values:
Eval @F01 = x'31'
Eval @F02 = x'32'
and so on for Function keys, enter, roll keys, etc
Eval @Valid = 'V'
Eval @Invalid = 'I'
and so on for standard testing/validation variables.
4) This is so we don't have code like:
If CustStatus = 'IVNALID' -- where a minor typo causes undesired
results.
Here's the dilemma:
* I need to be able to set these "standard definitions" in a service
program so the subprocedures can return standard values.
* I tried to find out how to define "global variables" but couldn't
figure it out.
* See code snippet below for additional explanation.
Thanks in advance for any help you can give. I couldn't seem to find
in:
* ILE Application Development Example
* ILE Concepts
* Websphere Development Studio: ILE RPG Programmer's Guide
* Websphere Development Studio: ILE RPG Reference
(If it was in any of these, I totally missed it.)
Sample of code -- couldn't figure out how to create these "standard
definitions"
H Nomain
*=======================
D GetCustStatus PR 1A
D inCustNbr 7S 0
*=======================
P GetCustStatus B
D GetCustStatus PI 1A
D inCustNbr 7S 0
/free
Chain (inCustNbr) CUSMAS;
If %FOUND(CUSMAS);
Return @Valid;
Else;
Return @InValid;
EndIf;
/end-free
P GetCustStatus E
There are some completely different ways to handle this situation. See
below ("Some other ways to handle this").
First, here's how to do it in a very similar way to what you are doing
now:
You code the global variables before the P specs, in the same place you
code your prototypes.
*=======================
* Global variables
D STDDFN e ds
*=======================
*=======================
D InitStdDefs PR
*=======================
*=======================
D GetCustStatus PR 1A
D inCustNbr 7S 0
*=======================
P GetCustStatus B
D GetCustStatus PI 1A
D inCustNbr 7S 0
/free
InitStdDefs();
/end-free
P GetCustStatus E
*=======================
P InitStdDefs B
* Checks to see if the initialization is already done,
* and if not, calls the init program
*=======================
D InitDone s 1N inz(*off)
D static
D STDDFNRG pr extpgm('STDDFNRG')
D defs likeds(STDDFN)
/free
if not InitDone;
STDDFNRG (stddfn); // initialize the standard definitions
InitDone = *on;
endif;
P InitStdDefs E
Some other ways to handle this:
You could create a /COPY file that defines all those names as named
constants. You would have the same benefit of avoiding typos, but you
wouldn't need to call your program to initialize the values. Then
instead of calling your program in the *INZSR, you'd just code a /COPY
at the top of your module, before your first procedure is coded. Also,
there is no risk of someone accidentally changing the value say by
assigning something to @F01.
D @F01 c x'31'
D @F02 c x'32'
and so on for Function keys, enter, roll keys, etc
D @Valid c 'V'
D @Invalid c 'I'
If you wanted to be able to see those values in debug, you could define
them in the /copy file as data structure subfields with initialization:
D ds
D @F01 1a inz(x'31')
D @F02 1a inz(x'32')
If you have some values that need some runtime calculation to set up,
say getting something from a file, you could create a new service
program that would run in a named activation group, and be bound to all
your applications. This service program would have a procedure for each
of the values that require the complex setup. Each procedure could keep
track of whether it had already calculated the information, so it
wouldn't have to keep doing it.
For example, say everything in your standard definitions data structure
has a constant value except for the name of the system which you have to
calculate by calling an API. Then your stddefs copy file would look
like this:
* Constant definitions
D @F01 c x'31'
D @F02 c x'32'
and so on for Function keys, enter, roll keys, etc
D @Valid c 'V'
D @Invalid c 'I'
* Definitions requiring a procedure call
D @SystemName pr 10A
Then your new StdDefs module would look like this:
H nomain
/copy stddefs
P @SystemName B 10A export
* "haveInfo" keeps track of whether we have already figured out
* the value that we are going to return. Define it as "static"
* so it remembers the value from the previous call
D haveInfo S 1N inz(*off)
D static
* "sysname" is the value we will return. Also define it as static
* so it will keep the value we calculate for the first call
D sysname S 10A inz(*blanks)
D static
/free
if not haveInfo;
// call an API or a CL program to get the system name
endif;
return sysname;
/end-free
P @SystemName E
And your other modules would look like this, using the standard
definitions the same as always.
H nomain
/copy stddefs
...
P someproc B
/free
if CustStatus = @Invalid;
...
sys = @SystemName;
...
To maximize the ease of use for your other programs, you could put this
STDDEFS service program into a binding directory, say called STDDEFS.
Then your other modules would look like this, and you wouldn't have to
remember to bind in that extra service program:
H nomain bnddir('STDDEFS')
/copy stddefs
...
P someproc B
/free
if CustStatus = @Invalid;
...
sys = @SystemName;
...
For example:
D STDDS DS
D @F01 C X'31'
D @F02 C X'32'
If you really want to do it calling a program, something like this might
work:
PGetCustStatus B
DGetCustStatus PI 1A
D InCustNbr 7p 0
D
D DS_Loaded S 1a inz('N') Static
D STDDFN E DS Static
D
C if DS_Loaded = 'N'
C call 'STDDFNRG'
C parm STDDFN
C eval DS_Loaded = 'Y'
C endif
C etc
The Static keywords retain field values. I have never tried it with an
externally defined data structure, but it shouldn't be hard to test--just
put it in debug an step through it twice. You don't want to do is call
STDDFNRG every time sinced this may be a performance hit.
Sam
<cml...@gmail.com> wrote in message
news:1135891780.5...@f14g2000cwb.googlegroups.com...