Use modified CL program source code to avoid the mismatched parameter problem.
It is common for a CL program to submit a CALL command
to a job queue for batch processing. That is, the programmer places a CALL
command in the CMD parameter of the Submit Job (SBMJOB) command. Submitting a
CALL command is risky because the command interpreter makes certain assumptions
about parameter formats when loading and executing the called program. Numeric
values are assumed to be 15-digit numbers with five decimal positions. Character
values of 32 bytes or less in length are padded with trailing blanks to a length
of 32. Trailing blanks are removed from character values longer than 32 bytes,
potentially causing the submitted program to receive garbage in the rightmost
part of a long character parameter.
Several methods exist to work around
this problem, but my favorite by far is to write a CL command to run the
program. I reference this command, rather than a CALL, in the CMD parameter of
SBMJOB. While I occasionally see this method recommended in an online forum, I
have found that many iSeries professionals have worked with the iSeries and/or
AS/400 for years, yet have never written a command!
It is very easy to
create command source code from CL program source code. Let me illustrate.
Assume you have a CL program, CALLEDPGM, that is to be submitted to batch from
another program, CALLER.
The first step is to provide a place to store
command source code. You can use any source physical file you wish. For this
illustration, I use a file called QCMDSRC, which is IBM's default name for
command source. If necessary, create a source physical file.
CRTSRCPF MYLIB/QCMDSRC
Replace MYLIB with the name of one of your libraries.
Next, create
a source physical file member to contain the command source. In this example, I
use PDM and SEU because everybody has them and knows how to use them. From the
Work with Members Using PDM panel, press F6 to create a new member. Name it
CALLEDCMD and select CMD as the source member type. SEU creates an empty work
member.
On the first line of the empty member, type CMD. Press F15 and
enter CALLEDPGM and the name of the CL program's source file and library in the
Browse/copy member entry fields. This permits you to view the CL program source
as you build the command source code. At this point, you have a split display,
with CALLEDCMD at the top and CALLEDPGM at the bottom.
Notice the PGM
command that begins program CALLEDPGM. For this illustration, assume it looks
like this:
PGM PARM(&COMPANY &WAREHOUSE &SHIPDATE &COMMENT)
There are four parameters, therefore your command will have four
parameters. Copy the DCL statements for these four variables into the command
source work member in the order in which they are listed on the PGM command. It
is unlikely that any variable declaration has a VALUE parameter, since
parameters receive their values from the caller, but if the VALUE parameter
exists, remove it. The command source will look like this:
CMD DCL VAR(&COMPANY) TYPE(*DEC) LEN(3) DCL VAR(&WAREHOUSE) TYPE(*CHAR) LEN(1) DCL VAR(&SHIPDATE) TYPE(*DEC) LEN(6) DCL VAR(&COMMENT) TYPE(*CHAR) LEN(40)
You are finished with the CL program source code and can close the window in
which it is displayed. SEU shows the DCL commands in reverse image because DCL
is not valid in CL command source code. SEU also sends the error message
"Command DCL not allowed in this setting." Use global search and replace
operations to change DCL to PARM and VAR(& to an empty string. You can use
SEU's CHANGE command for this purpose.
C DCL PARM A C VAR(& '' A
Even after you make these changes, SEU is still not satisfied. Remove the
closing parenthesis following each variable name and the reverse image should
disappear from the PARM commands. The command source looks like this:
CMD PARM COMPANY TYPE(*DEC) LEN(3) PARM WAREHOUSE TYPE(*CHAR) LEN(1) PARM SHIPDATE TYPE(*DEC) LEN(6) PARM COMMENT TYPE(*CHAR) LEN(40)
This is barebones command source, inadequate as a user interface but
sufficient for your purpose. Close and save the source member.
Use the
Create Command (Create Command) command to build the command object.
CRTCMD CMD(MYLIB/CALLEDCMD) + PGM(MYLIB/CALLEDPGM) + SRCFILE(MYLIB/QCMDSRC) + SRCMBR(CALLEDCMD)
Once the command has been created, you can use it in program
CALLER.
SBMJOB CMD(CALLEDCMD COMPANY(&COMP) WAREHOUSE(&WHS) + SHIPDATE(&SDATE) COMMENT('URGENT')) + JOB(MYJOB)
By submitting the command instead of CALL, OS/400 will format the
parameters as they are defined in program CALLEDPGM.
For more information
about creating your own CL commands, see Power CL, published by MC
Press.
Paul Amsden has worked with AS/400 and
iSeries systems for more than 10 years.
|