You are on page 1of 272

Tips n Facts

The Frequently Asked Questions


Messages
How can we copy messages from one message file to another?
Use the command MRGMSGF. For example:
MRGMSGF FROMMSGF (MYLIB1/MSGF1) TOMSGF (MYLIB1/MSGF2)
What commands can be specified in the EXEC parameter of program level MONMSG and
command level MONMSG?
GOTO is the only valid value for the EXEC parameter on the program level MONMSG.
Any CL command can be coded in the EXEC parameter of the command level MONMSG.
The action specified on the command level MONMSG overrides the action specified on the program level
MONMSG.
What message types are monitored by MONMSG command?
The MONMSG command monitors only *STATUS, *NOTIFY AND *ESCAPE messages It does not monitor *INFO
and *INQ messages.
RPG:
The messages in RPG are sent in packets and distributed thru a channel called Message Queue.
There are 2 types of MSGQ:
Program Message Queue:

Pilot

MSGQ (PGM1)
-----------------------

Prog 1

Non-Program Message Queue: QSYSOPR / USER defined Message Queue using command CRTMSGQ / MSGQ
associated with display station.
SNDPGMMSG:
The Send Program Message (SNDPGMMSG) command sends a message to a named message queue or to a call
message queue. A call message queue can be the *EXT external message queue or a message queue associated
with a call stack entry. Each time a program or procedure is called a new message queue is associated with its
call stack entry. The message queue is identified by the name of its associated program or procedure.
A program can send a message to its own message queue or to a message queue that is associated with a different
call stack entry.
Message Types:
*INFO
*INQ
Inquiry messages can be sent only to the external queue or to a named message queue specified for the TOUSR or
TOMSGQ parameters. When sending an inquiry with the TOMSGQ parameter, a second queue can be specified if
the value is *HSTLOG.
*COMP
*DIAG Provide info about the error which has occurred either in Input sent to it or those that occurred while it
was running the requested function. Must be assisted with the Notify or Escape message.
*NOTIFY - notify message describes a condition for which corrective action must be taken before the sending
program can continue. A reply message is sent back to the sending program. After corrective action is taken, the
sending program can resume running and can receive the reply message from its message queue.
*ESCAPE - describes an irrecoverable error condition.
Completion, diagnostic, escape, notify, and status messagescan be sent only to a call message queue.
Escape messages cannot be sent to the external message queue.
SNDPGMMSG MSGID(USR0001) MSGF(USRMSGR) TOPGMQ(*PRV *) MSGTYPE(*ESCAPE)
SNDPGMMSG MSGID(USR0001) MSGF(USRMSGR) TOPGMQ(*SAME ACCOUNT_FINAL_TOTALS)
MSGTYPE(*ESCAPE)
*STATUS

-1-

Tips n Facts
*RQS

What are Product libraries?


- The product libraries are used to support languages and utilities that are dependent on libraries other
than the system library, QSYS, to process their commands.
For Ex. SHWFC is of type *CMD in library GPL / ULTRA as an utility.
What is the significance of QTEMP library?
The QTEMP library is cleared when a job ends.
As SBMJOB command initiates a new routing step, QTEMP library is not passed on to the submitted job but
this submitted job will have its own QTEMP library, which is not visible to other jobs.
You can move object out of QTEMP but not in to QTEMP.
The routing data is used to determine the routing entry, that identifies the program that the job runs.
If no current library exists in which library does a Create command create the object?
The object gets created in QGPL with Create command.
Is Library list an object? In which order it is searched?
Library list is not an object.
The order in which the parts of the library list are searched is System, Product, Current and User.
There is no OS/400 command that saves the user library list. It has to be taken care of in the job description.
What is the maximum number of libraries allowed in the user part of the library list?
A maximum of 25 libraries can be present in the user part of the library list.
Please note that libraries can never be created within libraries.
What is the difference between Production and Test libraries?
Database files in Production library cannot be opened for update by a program running in debug mode if
UPDPROD (*NO) was specified on the STRDBG command.
This restriction does not apply to database files in Test library.
What is the significance of the values *LIBL, *ALLUSR and *USRLIBL for the library parameter
on any command?
*LIBL is used to search for an object in the library list.
*ALLUSR is used to search for an object in all the user-defined libraries existing on the system.
*USRLIBL is used to search for an object only in the user part of the library list.
What is a flat file?
It is a file created with out any DDS. Record length has to be given. For example:
CRTPF FILE (MYLIB1/PF1) RCDLEN (132)
The fields for this file can be described with in the program in which it is being used. Hence it is also called
program-described file.
If a CL program contains the reference to a flat file, how can the data be retrieved in the
program?
The data can be retrieved from the variable &FILENAME.
How many record-formats can a database file have, which is declared in CL?
Only database files with single record format can be used in a CL program.
Please note that the database file need not have member when it is referred to create a program.
Non Join (1PF) (2-32 PF)
Join (1PF) (2-32PF)
Multi format Logical ** must have same first keyfield for all the formats.
What commands are allowed on a database file declared in CL?
Only RCVF comparmand is allowed for database file as it can be opened for input only.

-2-

Tips n Facts
Do I need to declare the fields of a file, which is declared in a CL?
If a database file is declared in CL, the fields in the file are automatically declared in the CL program with &
prefixed to it.
Please note that the variable name in CL must begin with & followed by not more than 10 characters.
How can I define a file member?
A member is a subset of records in a physical file (PF-SRC or PF-DTA). Each member conforms to the
characteristics of the file.
- For PF-SRC members, you can define the type of a member as well. For example CLP, RPGLE, PF, LF
etc.
What happens if a file is created with expiry date less than current date?
If a file is created with EXPDATE less than current date the file gets created but member is not added on
creation. An error message is sent at the time of creation saying that the EXPDATE is invalid.
What is the significance of DYNSLT keyword in a logical file?
DYNSLT keyword does the SELECT/OMIT processing when a program reads records, rather than when records
are added or changed.
Are key fields mandatory for logical files? Can logical files be journaled?
Key fields are not mandatory for logical files. Logical files cannot be journaled.
How many column headings can be specified for a field in a physical file?
For a field in a physical file, 3 column headings of not more than 20 bytes each can be specified.
What are various types of access path maintenance?
With MAINT (*IMMED), the access path is updated each time a record is changed, added, or deleted from a
member. *IMMED must be specified for files that require unique keys.
With MAINT (*REBLD), the entire access path is rebuilt when the file is opened.
With MAINT (*DLY), the access path is changed only for records added, changed, or deleted since the last
open.
Why would you prefer OPNQRYF to LF? When would you prefer an LF?
OPNQRYF
We prefer OPNQRYF when selection criterion gets
changed frequently.
OPNQRY is a temporary file, it does not take any
space on the disk.
As it has to process the query every time, the run
time for a particular program will be more.

LF
We go for logical file, when selection criterion is
permanent.
LF is a permanent file and it takes space on the
disk.
Run time for a particular program will be relatively
less.

What is Field Reference File?


A Field Reference File contains just the field descriptions. It does not contain any data. It is used as reference
for the field description for other files. This is used to simplify record format descriptions and to ensure field
descriptions are used consistently.
What is the use of RGZPF?
The Reorganize Physical File Member (RGZPFM) command is used to compress (remove deleted records from)
the member of a physical file in the database.
Under what circumstances we will not be able to delete a PF?
When there are dependent Logical Files
When there is no authority
When the PF is locked or in use
When do we use CLOF command?
When a file is opened using either OPNQRYF or OPNDBF command, CLOF command should be used to close the
opened file.
How actually SNDRCVF works?
The command SNDRCVF is the combination of write and read in that order. It writes the record and waits for
the user input. After pressing any key it reads the data.

-3-

Tips n Facts
What is difference between Command Attention (CA**) and Command Function (CF**) keys?
A key defined with CF** causes data to be returned to the program. A key defined with CA** does not.
What would be the effect on a field with the following display attributes: reverse image,
underline, and high intensity when used together?
The field will not be displayed i.e. becomes non-display.
What is the difference between Non-display and Hidden fields?
Non-display - Causes the data in the field to be invisible to the operator. The display positions for the fields
appear to be blank. Use this attribute for passwords or other security-sensitive data. Non-display fields do
not print.
Hidden - Type H to indicate a hidden field (one that is used for both input and output but not displayed).
OVRDBF & OPNQRYF
What is the necessary command needed before OPNQRYF and why?
OVRDBF. We use this to make sure that the ODP (open data path) created by the OPNQRYF is shared by
program.
What is the significance of SECURE parameter on OVRDBF command?
Consider the following example:
OVRDBF
FILE(ACCTMAST) SHARE(*YES) SECURE(*YES)
It will prevent ACCTMAST file from being overridden to SHARE (*NO) by any program that is called from the
program in which the above command exists.
What is the significance of SEQONLY parameter on OPNQRYF command?
The SEQONLY (Sequential Only) parameter indicates that the file will be processed sequentially (Arrival
Sequence) and that one record at a time will be transferred from the database to the programs internal buffer.
What is the sequence in which PDM options are processed?
If you select more than one PDM option on a list display, the options are processed sequentially,
starting with the first option selected.
What are the groupings options on PDM?
When you select an option and press Enter, PDM first determines whether it is a grouping option.
The Copy option, the Rename option, the Delete option, and the Move option are grouping options. If
it is a grouping option, a grouping display is shown, listing all the items for which a particular option
was chosen and requesting confirmation (and, possibly, additional input).
Commands
Is there any similarity between the commands ALCOBJ and CHKOBJ?
Both the commands do checking for the existence of an object. ALCOBJ command allocates the object in
addition to performing the existence check.
What does DSPPGMREF do?
Displays the list of all objects used in the program.
What actually RCLRSC command does?
The resources that are reclaimed by this command are

Static storage
Open files of object type *FILE
User interface manager (UIM) application resources
Common Programming Interface (CPI) Communications conversations
Hierarchical file systems (HFS) resources
User-defined communications sessions.

For an original program model (OPM) program, its static storage will be reclaimed.
For an Integrated Language Environment (ILE) program, its static storage will be marked so that it
will be re-initialized on the next call.
Static storage is not affected for a service program, or any ILE program running in an activation group
other than the default activation group.
The RCLRSC command is not needed to reclaim the files and static storage of most programs, such as
CL programs that end (return) normally, RPG programs that have the last record (LR) indicator set on,
and COBOL programs.

-4-

Tips n Facts

What is the difference between the commands CALL, RETURN, TFRCTL?


In a CALL, the calling program receives the control after the called program finishes the processing at
the command after the call to called program. Control is thus returned up the program stack.
The RETURN command has no parameters and removes the program from the program stack. If no
RETURN statement is coded in a CL program, a return is performed after the last executable
statement is performed.
The TRFCTL command transfers the control to the program and removes the transferring program
from the program stack. It returns the control to the statement after the most recently run CALL
command in the program that called the transferring program. No statements after the TFRCTL in a
CL program will be executed.
Why cant retrieve commands be used on the command line?
Retrieve commands can not be used on command line, as those commands need a variable to store the
retrieved value.
Please note that retrieve commands can not be used even in a call to QCMDEXC.
Operators
What are the various concatenation operators in a CL program?
The *CAT operator concatenates two character strings. Blanks are included in the concatenation. For
example:
ABC *CAT DEF becomes ABCDEF
'ABC ' *CAT 'DEF ' becomes 'ABC DEF '
-

The *BCAT operator truncates all trailing blanks in the first character string; one blank is inserted, then the
two character strings are concatenated. Leading blanks on the second operand are not truncated. For
example:
ABC *BCAT DEF becomes ABC DEF
'ABC ' *BCAT DEF becomes 'ABC DEF'

The *TCAT operator truncates all trailing blanks in the first character string, then the two character strings are
concatenated. All leading blanks on the second operand are not truncated. For example:
ABC *TCAT DEF becomes ABCDEF
'ABC ' *TCAT DEF becomes 'ABCDEF'
ABC *TCAT ' DEF' becomes 'ABC DEF'
'ABC '*TCAT ' DEF' becomes 'ABC DEF'

All blanks that surround the concatenation operator are ignored, but at least one blank must be on each side of
the reserved value operator (*CAT, *BCAT, or *TCAT). If multiple blanks are wanted in the expression, a
quoted character string (a character string enclosed within apostrophes) must be used.

What are the various types of operators that can be used in CL?
There are four broad categories of operators. Each operator can be replaced by a special character as
shown below:

Logical operator
Special
character
Character
operator
Special
character
Arithmetic
operator
Special
character
Relational
operator
Special
character

*AND
&

*OR
|

*CAT

*BCAT

*TCAT

||

|>

|<

ADD

SUB

MULT

DIV

*EQ

*GT

*LT

*GE

*LE

*NE

*NG

*NL

>

<

>=

<=

>

<

-5-

Tips n Facts
General
What is the difference in assigning value to a character variable with apostrophes and with out
apostrophes in a CL program?
When you assign value to a character variable without apostrophes the value would be translated to
uppercase.
The value is assigned as it is in case of assigning with apostrophes.
Also observe the assignment for the variables in the following example:
DCL
DCL
CHGVAR
CHGVAR
CHGVAR
CHGVAR
CHGVAR

VAR(&RES1) TYPE(*CHAR) LEN(10)


VAR(&RES2) TYPE(*DEC) LEN(10)
VAR(&RES1)
VAR(&RES1)
VAR(&RES1)
VAR(&RES1)
VAR(&RES2)

VALUE(1) results in
1
VALUE(A) results in
A
VALUE(1) results in0000000001
VALUE(a) results inA

VALUE(1) results in
1

Is recursion allowed on CL programs?


Under any circumstances a CL program may call itself in the same manner that it calls any other program i.e.
recursion is allowed.
Do all the objects referred to in a CL program, need to exist at the time of the CL program
compilation?
For most of the objects referred to in a CL program, the object dos not have to exist when the
program is compiled.
However, Files and command definitions are exceptions to this rule.
What is the difference between continuing a source statement with a plus sign (+) and a minus
sign (-)?
The difference is that all the blanks in the next record that precede the first non-blank character are ignored
when a plus sign is coded and included when a minus sign is coded.
What is asynchronous communication?
It is the communication in which one of the commands waits for the output from another command to
get executed. This involves WAIT parameter.
In the below example the RCVMSG waits for 10 seconds to receive the message from the command
SNDPGMMSG.
SNDPGMMSG MSGID(A000004) MSGF(MYLIB1/MSGF1)
RCVMSG
PGMQ(*PRV) WAIT(10) SENDER(&SENDER)

RPG

-6-

Tips n Facts
What are the different ways to pass data between programs? Which one is the most efficient
way?
Parameters, Data area, Data queue, Message queues, Files
Data queues are the most efficient way of data transfer.
Explain about CUA and SAA?
Common User Access standards (CUA) are the standards for designing user interface of an application.
System Application Architecture standards (SAA) are the standards for coding.
What is Job Description?
The job description may contain request data that causes a program or a command to run.
Job descriptions can also specify what user profile the job should run under.
The workstation entry tells what job description will be used when a job starts at that workstation.

JOB --

SYSTEM
USER

SPOLLING (Input spooling and Output spooling)


INTERACTIVE/BATCH/AUTOSTART/ PRESTART / Communication

----

JOBD
JOBQ
SUBSYSTEM
Opt

Queue
Library
LONGBATCH
QGPL
MISCBATCH
QGPL
NIGHTBATCH
QGPL

Jobs
Subsystem
140
NUBATCH
0
NUBATCH
0
NUBATCH

Status
RLS
RLS
RLS

DSPOBJD (QGPL/QBASE)
Routing Entry:
The job queue contains a request message made up of :
Request Data
Routing Data
The Routing data of Job Queues request message is processed against the routing parameters of subsystem.
When it finds a match it starts a job, puts the request data in a request message on the new job's message queue
and calls the program associated with the routing entry. This program is typically a command processor such as
QMD (i5OS command processor) or QCL (S38 command processor). You can call these programs from the comand
line if you wish. The first thing that the default command processors do is to process any request messages on the
job's message queue, then if it is an interactive job they go to a command line, and if it is a batch job, the job
ends. Your submit does not have any request data, so if the matching routing entry pointed to QCMD or QCL it
would likely just end.

What is an authorization list?


An Authorization list contains the access rights for individual users and groups of users for the functions such
as tasks, menus, batch environments, data sets and so on. For each authorization list, 10 levels of
authorization rights can be defined (0 to 9). Level 0 means no authorization and a level greater than 0 means
authorization. You can secure an object by the authorization list.
What are the valid data types on AS/400?
The valid data types are
Entry
Meaning
A
Character
P
Packed decimal
S
Zoned decimal
B
Binary

-7-

Tips n Facts
F
H
L
T
Z

Floating point
Hexadecimal
Date
Time
Timestamp

What is the difference between Interactive and Batch jobs?


-

CL commands are used in either batch or interactive jobs.


The AS/400 system provides many menus and displays to assist the programmer, including the Programmer
Menu, the Command Entry display, command prompt displays, and the Programming Development Manager
(PDM) Menu to make interactive entries.
Interactive job has to wait for the issued command to complete to continue with another command.
SBMJOB command causes the command to run in batch.
SBMJOB command causes the program that issues it to continue without waiting for the issued command to
complete.
In case of an exception, if the program is running in an interactive job, the system sends the message to the
job's external message queue. If the program is running as a batch job, the system sends the message to the
system operator message queue, QSYSOPR.

The Tips
To view the program source we generally use 2 or 5 option on PDM. Is there any other way to
it?
Try using the following commands to view the code:
DSPPFM FILE (SRCPF) MBR (PROGRAM NAME)
DSPF
FILE (SRCPF) MBR (PROGRAM NAME)
The RUNQRY command displays the records but it is not possible to find a particular string in
the file records, as the find option is not provided. Is there any way out?
Try using the following commands to find a particular string:
DSPPFM FILE (FILE NAME)
DSPF
FILE (FILE NAME)
How can I know the system date, its format etc.?
Use DSPSYSVAL command on the command line with the system values like QDATE, QDATFMT, QDATSEP,
QDAY, QDAYOFWEEK etc.
Please note that the system date does not have any fixed format. It is always displayed in the format specified
in the QDATFMT system value.
Can I retrieve a CL source, which I have deleted by mistake?
A CL program can be reconstructed from the object program by using the command RTVCLSRC.
Can I avoid source listing while compiling a CL program?
Yes. By specifying OPTION (*NOSOURCE) for source listing options on a CRTCLPGM command only
error messages are listed. A complete source listing is not printed.
If I change the text for a source, is there any other way to reflect that change in the text of the
object other than compilation?
Yes. Use CHGPGM command to change the object text of a CL program without recompiling the program. The
CHGPGM command automatically recompiles the program with the changed text. However, the attribute
FRCCRT should be (*YES) on CHGPGM command for automatic compilation.

-8-

Tips n Facts
What are the various methods of minimizing the program object size?
Removal of observability
Optimization
Compression
What is observability?
-

Program observability consists of two types of data, namely Debug Data and Creation Data:
Debug Data represented by the *DBGDTA value. This data is necessary to allow a program to be debugged.
Creation Data represented by the *CRTDTA value. This data is necessary to translate the code to machine
instructions. The program must have this data for you to change the program optimization level.
Using the Change Program (CHGPGM) command, you can remove either type of data from the module, or
remove both types. Removing all observability reduces the program to its minimum size (with compression).
Once this data is removed, you cannot change the program in any way unless you compile the program again
and replace the data. To compile it again, you must have authority to the source code.

What is optimization?
Optimization is a process where the system looks for processing shortcuts that reduce the amount of system
resources necessary to produce the same output.
Optimization removes redundant instructions.
To optimize, set the OPTIMIZE attribute on a CHGPGM command to *YES.
What is the significance of CPROBJ command?
Use Compress Object (CPROBJ) command to compress selected objects in order to save disk space.
You can use the Decompress object (DCPOBJ) command to decompress objects that have been
compressed.
Please note that the database files can not be compressed.
How do I know whether an object is compressed or not?
Use DSPOBJD OBJ (TEST1) OBJTYPE (*PGM) DETAIL (*FULL) to know the compression status.
Compressed objects are temporarily or permanently decompressed when used, depending on the
object type and usage.
For example *PGM is automatically permanently decompressed when used. *FILE is automatically
decompressed when opened. If only description is retrieved, *FILE is temporarily decompressed.
How can you retrieve the program name in a CL program?
Send a program message (SNDPGMMSG) to this job and receive (RCVMSG) the message. The call stack entry
will be the name of this program. In the following example, the variable &PGMNM will have the program name:
PGM
DCL
VAR(&PGMNM) TYPE(*CHAR) LEN(10)
DCL
VAR(&CALLING) TYPE(*CHAR) LEN(10)
DCL
VAR(&SENDER) TYPE(*CHAR) LEN(80)
SNDPGMMSG MSGID(A000004) MSGF(MYLIB1/MSGF1)
RCVMSG
PGMQ(*PRV) SENDER(&SENDER)
CHGVAR
VAR(&PGMNM) VALUE(%SST(&SENDER 27 10))
ENDPGM
Please note that the below statement will retrieve the calling program name:
CHGVAR
VAR(&CALLING) VALUE(%SST(&SENDER 56 10))
Can I pass a numeric variable for the call to a program from command line?
Yes, the hexadecimal value of the numeric variable has to be passed. The following call command
shows how to pass the value 25.5 to a program variable that is declared as LEN(15 5) in hexadecimal
value
CALL PGMA PARM (X02550F)
-

How can you read a particular member of a physical file in your program?
Mention the physical file member name you want to read on data member (DTAMBR) parameter of CRTLF
command and use that logical file to read.

-9-

Tips n Facts
Generally STRISDB is used for debugging CLP. Can I debug a CLP using STRDBG command?
Yes. The steps involved are as follows:
Compile CLP using with Source listing options *SRCDBG.
Then issue command STRDBG PGM (PGM1) OPMSRC (*YES)
Follow the same process for debugging RPG also.
It is very time consuming to go to spool and search for the spool file for the latest compilation
made. Is there any way out?
Try this. If you are compiling a source by name PGM1, use the following command to see its spool:
DSPSPLF FILE (PGM1) SPLNBR (*LAST)
Can I know in what all CL program objects a particular command is being used?
Use PRTCMDUSG (Print Command Usage) command.
Is it possible to have different descriptions for a source and its object?
Yes, it is possible. When you try to compile a source the default for object text is *SRCMBRTXT.
Instead of *SRCMBRTXT you can type your own text.
Please note that this is valid only for objects created from sources.
How can we take a back up of the spool file?
Create a physical file with record length = Length of the record in spool + 12.
CRTPF FILE (MYLIB1/SPOOL) RCDLEN (144)
Open the spool file with option 2 (CHGSPLFA) and make note of Spooled file, Job name, User, Number,
Spooled file number.
Use CPYSPLF command as follows to copy the spool file to physical file SPOOL:
CPYSPLF FILE (PGM1) TOFILE (MYLIB1/SPOOL) JOB (599815/#VYERRAP/QPADEV004C)
SPLNBR (12)
Now use CPYF command as follows:
CPYF FROMFILE (MYLIB1/SPOOL) TOFILE (MYLIB1/QCLSRC) TOMBR (PGM1BKUP)
MBROPT (*REPLACE) FMTOPT (*CVTSRC)
The above process creates a member by name PGM1BKUP in source physical file QCLSRC.
How can I know all the commands starting with a particular string?
For example if you want to know all the commands starting with string CHG type CHG* on command
line and press enter.
What is the significance of MRGSRC (Merge source) command?
If you are maintaining two copies of the same source and if one of the copies is updated, you can
reflect those updates in other copy by using MRGSRC command (option 55 on PDM).
How can I search for a string in all the members of a source physical file?
Type option 25 on first member in the source physical file.
Press F13. Option 25 is repeated for all the members. Press Enter.
Find String display is shown. Enter the string you want to search for and press Enter.
The members having the string in them are displayed one after another by pressing Enter.
The other way is to use FNDSTRPDM command as follows:
FNDSTRPDM STRING ('CHG') FILE (MYLIB1/QCLSRC) MBR (*ALL) OPTION (*DSP)
What are User-defined options?
With user-defined options, you can call your own commands from any PDM list display. These options
make it easier for you to do frequent operations, because you can type an option on a list display
instead of retyping an entire command.
The process to create an user-defined option is as follows:
Press F16 on PDM. Work with User-Defined Options display is shown.
Press F6. Create User-Defined Option display is shown. Type the option and command. For example:
CC CHGCURLIB CURLIB (&L)
Now you can use CC instead of CHGCURLIB as an option on PDM.

- 10 -

Tips n Facts

Can I use CPYF command for copying a logical file?


If you try to copy a logical file using CPYF command a physical file with the same name is created. Therefore
CRTDUPOBJ command should be used.
How can I know the dependant logical files on a physical file?
The DSPDBR command on a physical file can be used to display a list of dependent logical files by default.
How can I know all the files using the format of a physical file?
Use DSPDBR command with RCDFMT parameter on a physical file.
For
-

what all information I can use DSPFD command?


Use DSPFD command to know the number of records in a database file.
Use TYPE (*MBRLIST) parameter on DSPFD command to know the members in a file.
Use TYPE (*SELECT) parameter on DSPFD command to know the select/omit rules in a logical file.
Use TYPE (*JOIN) parameter on DSPFD command to know the join description in a join logical file.

Can I know the record count in a file using RUNQRY command?


Use OUTFORM (*SUMMARY) parameter on RUNQRY command to know the number of records in a file.
Can I select records from a file based on certain criteria using RUNQRY command?
Use RUNQRY QRYFILE ((FILENAME)) RCDSLT (*YES).
How do I specify the OR and AND select/omit conditions in the DDS of a logical file?
The OR condition for select rule in LF:
A
A
A
A

S DEPART
S DEPART

COMP(EQ 117)
COMP(EQ 131)

The AND condition for select rule in LF:


S DEPART
DEPART

COMP(EQ 117)
COMP(EQ 131)

Can I avoid underlining of input fields on display file screen?


By specifying CHGINPDFT at the file level or record level or field level the underlining of input fields on the
screen be prevented.
Can I retain the screen after closing the display file?
Using the KEEP keyword at the record level will prevent the screen from being erased when the display file is
closed.
Can you copy the records created by the OPNQRYF to other files?
Yes, by using CPYFRMQRYF.
How to print the help for one CL command keyword parameter?
From a command line, type the CL command name and press F4 to display the command prompt display.
Position the cursor anywhere on the line of the keyword parameter for which you want help. Press F1 to
display the help for the keyword parameter. Press F14 to print the help.
We can restore the source changes but not the source date for a particular line of code. Is
there any way out?
For example if you want to change the source date for a particular line of code in member PGM1 in
MYLIB1/QCLSRC, the steps involved would be:

- 11 -

Tips n Facts
-

OVRDBF FILE (PGM1) TOFILE (MYLIB1/QCLSRC) MBR (PGM1)


Start SQL session and enter the following command: UPDATE PGM1 SET SRCDAT = 111213 WHERE SRCDAT =
111215

The system creates a job log when it is idle long enough and the system logs the user out but
how can I have this created all the time i.e. whenever a user signs out?
Take prompt for SIGNOFF command and change the job log parameter to *LIST.
Is it possible to use SQL in CL programs?
SQL in CL is no problem. Add this line to your CL program (MYCLPGM1):
RUNSQLSTM SRCFILE(MYLIB1/QCLSRC) SRCMBR(MYSQL1) COMMIT(*NONE)
-

Create MYSQL1 member with the required SQL statements: (the member type in PDM is 'SQL' instead of 'CLP')
DELETE FROM MYLIB1/TCAFILE;

Note: RUNSQLSTM runs the whole SQL member, no way to select only one statement of it. So you must create
more SQL members for a CLP, if you need to run the statements from several places of your CLP. Perhaps like
this: CLP = MYCLPGM, SQL members: MYCLPGM1, MYCLPGM2, ... then you have them right below the CL in
PDM. See the ';' at the end of each line. It's important.

How can I avoid status message while running commands like CPYF, OPNQRY etc. in a CL
program?
The following code will avoid status message:
DCL
VAR (&STSMSG) TYPE (*CHAR)
LEN (7)
RTVJOBA
STSMSG (&STSMSG)
CHGJOB STSMSG (*NONE)
CPYF
CHGJOB STSMSG (&STSMSG)
How to use QCMDEXC?
Execute Command (QCMDEXC) is an IBM-supplied program that runs a single command. This command is
used to activate another command. After the command gets executed the control returns to your CL
program.
The command runs as if it was not in a program. Therefore, variables cannot be used on the command
because values cannot be returned by the command to CL variables. Additionally, the QCMDEXC program
cannot run commands that can only be used in CL procedures or programs. The format of the call to the
QCMDEXC program is the following:
CALL PGM (QCMDEXC) PARM (command command-length)
Enter the command you wish to run as a character string on the first parameter. You must enclose the
command in apostrophes if it contains blanks. The maximum length of the character string is 6000
characters. Never count the delimiters (the apostrophes) as part of the string. The length that is specified
as the second value on the PARM parameter is the length of the character string that is passed as the
command. Length must be a packed decimal value of length 15 with 5 decimal positions. Thus, to replace
a library list, the call to the QCMDEXC program would look like this:
CALL PGM (QCMDEXC) PARM ('CHGLIBL LIBL (QGPL NEWLIB QTEMP)' 31)

- 12 -

Tips n Facts
The Facts
1.

A CL program can handle up to 1000 MONMSG commands. Up to 50 message identifiers can be entered on a
MSGID parameter for a MONMSG command.

2.

Up to 10 programs can be debugged simultaneously in a job.

3.

CLP does not support zoned and binary variables. It supports only packed variables.

4.

The maximum number of parameters that can be passed to another program is 40.

5.

There is no limit on command label length as long as the label fits on one line in the source record.

6.

Up to 10 levels of embedding are permitted in CL. Let us see the IF condition embedding. E.g. IF (A=1) THEN
(IF (B=2) THEN (IF C=3) THEN (DO)))

7.

When a call command is run in batch mode, variables passed as arguments are treated as constants.

8.

CL does not support arrays. CL does not support CASE statement.

9.

A null value can not be passed to another program.

10. CL cannot be used for processing printer or ICF files.


11. All keywords in a CL command can be coded positional.
12. The command QCMD is used to display command entry screen.
13. The command MOVOBJ is used to move the object from one library to another.
14. DCL, DCLF commands must precede all other commands except the PGM command.
15. The system message file is QCPFMSG. You can view all the exception messages in this message file.
16. CL cannot be used for processing sub files within display files. However message sub files can be processed.
17. CL cannot be used to update or add records in database files. However, it can read records from the database
files.
18. The only way, a program can determines that no messages were received by a RCVMSG command if the
message text is blank.
19. If an override command through a call to QCMDEXEC is executed, the override will be in effect at the same
invocation level as the program that issued the call to QCMDEXEC.
20. Only one file can be declared in a CL.

- 13 -

Tips n Facts
Appendix A - Using Command prompts

On a prompt display of a command, enter ? on a field to know the permissible values for that field. This
character can be used in all entry fields. It performs the same function as the F4 (Prompt) key.

On a prompt display of a command, enter & to increase the length of the entry field. If a particular input field
is not large enough for the parameter value or values you want to type, you can expand the field by using the
ampersand (&). The field will expand to the next larger length of 25, 80, 132, 256, or 512 characters.

If you type a less than sign (<) followed by at least one blank in place of the first character of a value, that
value is deleted. This character can be used only in fields that allow a list of values.

By typing a greater than sign (>) in the input field, you tell the system you want to type additional values
ahead of that value. On an input field that already contains a value, type the > over the first character of the
value and press the spacebar or press the Field Exit key to remove the remaining characters. Then press the
Enter key. The value in the input field where you typed the > is not lost. When you enter the additional values
and press the Enter key, the replaced value reappears following the inserted value. This character can be used
only in fields that allow a list of values.

Appendix B - Selective prompting character.


The special prompt characters help us in displaying command prompts both on command line and while
running the programs. For example the command
? WRKMBRPDM will display the prompt as if F4 is pressed. Let us see how others work
WRKMBRPDM ??FILE (*N)
The parameter is displayed and input-capable.
WRKMBRPDM ?*FILE(*N)
The parameter is displayed but not input-capable.
WRKMBRPDM ?<FILE(*N)
The parameter is displayed and input-capable, but the command default is sent to the CPP unless the
value displayed on the parameter is changed.
?
WRKMBRPDM ?-FILE(*N)
The parameter is not displayed. The specified value is passed to the CPP. Not allowed prompt override
programs.
WRKMBRPDM ?&FILE(*N)
The parameter is not displayed until F9 is pressed and the parameters are input-capable.
WRKMBRPDM ?%FILE(*N)
The parameter is not displayed until F9 is pressed and the parameters are not input-capable.
-

?/ Reserved for IBM use.

- 14 -

Tips n Facts
Appendix C - Object Authorities and Lock states
Object Authorities
A user can be given one of the following authorities to objects: *ALL, *EXCLUDE, *USE, *CHANGE.
Object
Authority

---------------Object-------------OPR
X

*ALL
*EXCLUDE
*USE
*CHANGE

MGT
X

EXIST
X

ALTER
X

--------------------Data--------------------REF
X

X
X

READ
X

ADD
X

UPDATE
X

DELETE
X

EXECUTE
X

X
X

X
X

Note: You can type an "X" or a blank to give or remove object/data authorities. For some *FILE objects, a
"/" may appear in the column. A "/" indicates that the user has the specified authority to some, but not
all of the fields in the file.
-

Object operational authority - It provides the user authority to display the objects attributes.

Object management authority - It provides authority to specify security, to move or rename the
object, and to add members if the object is a database file.

Object existence authority - It provides authority to control the object's existence and ownership.

Object alter authority - It provides authority to change the attributes of an object, such as adding or
removing triggers for a database file.

Object reference authority - It provides authority to specify the object as the first level in a referential
constraint.

Read authority - It provides authority to access the contents of the object.

Add authority - It provides authority to add entries to the object.

Update authority - It provides authority to change the content of existing entries in the object.

Delete authority - It provides authority to remove entries from the object.

Execute authority - It provides authority to run a program or search a library or directory.

- 15 -

Tips n Facts
Object Lock states
Objects are allocated on the basis of their intended use and whether they can be shared. A lock state
identifies the use of the object and whether it is shared. The five lock states are as follows:
-

Exclusive (*EXCL) - The object is reserved for the exclusive use of the requesting job. No other job
can use the object.

Exclusive allow read (*EXCLRD) - The object is allocated to the job that requested it but other jobs
can read the object.

Shared for update (*SHRUPD) - The object can be shared either for update or read with another job.

Shared no update (*SHRNUP) - The object can be shared with another job if the job requests either a
*SHRNUP lock state or *SHRRD lock state.

Shared for read (*SHRRD) - The object can be shared with another job if the user does not request
exclusive use of the object.

Use WRKJOB (work with job) command and take option 12 to display the lock states for objects. Use
WRKOBJLCK (Work with object locks) to display the lock state for a specified object.

- 16 -

Tips n Facts
Appendix D - Message queues and Messages
Types of message queues
All messages are sent to the message queue. In addition to the below message queues, you can create
your own message queues for sending messages to system users and between application programs.
-

Workstation message queue is used for sending and receiving messages between workstation
users and between workstation users and the system operator.
User profile message queue can be used for communication between users. It is automatically
created when the user profile is created.
Job message queue is used for receiving requests to be processed and for sending messages that
result from processing the requests. It exists for each job and only exists for the life of job. It consists
of an external message queue (*EXT) and a set of program message queues.
System operator message queue (QSYSOPR) is used for receiving and replying to messages from
the system, display station users, and application programs.
The history log message queue is used for sending information to the history log (QHST) from any
job in the system.

Types of messages
-

Informational (*INFO) message that conveys information about the condition of a function.
Inquiry (*INQ) message that conveys information and also asks for a reply.
Notify (*NOTIFY) message that describes a condition for which a program requires corrective
action.
Request (*RQS) message that requests a function from the receiving program.
Completion (*COMP) message that conveys completion status of work.
Diagnostic (*DIAG) message about errors in the processing of a system function.
Status (*STATUS) message that describes the status of the work done by a program. Status
messages sent to the external message queue (*EXT) is shown at the display station.
Escape (*ESCAPE) message that describes a condition for which a program must end abnormally.

The message identifier you specify on the ADDMSGD command is used to refer to the message and is the
name of the message description. The message identifier must be of 7 characters:
PPPMMNN
Where PPP is the product or application code, MM is the numeric group code and NN is the numeric
subtype code. The number specified as MMNN can be used to further divide a set of product or application
messages. Numeric group and subtype codes consist of decimal numbers 0 through 9 and the characters
A through F.
For example: CPF1234 is message 1234 of CPF.
You should use care in using a numeric subtype code of 00 in the message identifier. If you use a numeric
subtype code of 00 for a message that can be sent as an escape, notify, or status message and that can,
therefore, be monitored, a subtype code of 00 in the Monitor Message (MONMSG) command causes all
messages in the numeric group to be monitored.
Valid message types for message queue types
Message Type
Message Queue Type
External
Program
Informational
X
X
Inquiry
X
Completion
X
X
Diagnostic
X
X
Request
X
X
Escape
X
Status
X
X
Notify
X
X

QSYSOPR
X
X
X
X

Work station
X
X
X
X

Message types that can be send with different message sending commands
Message Type

- 17 -

User
X
X
X
X

Tips n Facts
Sending
message
SNDMSG
SNDUSRMSG
SNDPGMMSG
SNDBRKMSG

*INFO

*INQ

X
X
X
X

X
X
X
X

*RQS

*COMP

*DIAG

*NOTIFY

*ESCAPE

*STATUS

SNDMSG (Send message)


-

It can be used on a command line.


It can not use messages in message file for sending messages. It can only use the message text
entered by the user.
It can be used to send message either to a user profile or a message queue.
The type of messages allowed on SNDMSG are *INFO, *INQ.

E.g. SNDMSG

MSG('AS/400 MESSAGE FILE') TOUSR(#VYERRAP) +


MSGTYPE (*INQ) RPYMSGQ (#VYERRAP)

SNDPGMMSG (Send program message)


E.g.

It can not be used on a command line.


It can use messages in message file for sending messages. It can also use the message text entered
by the user.
It can be used to send message either to a user profile or a message queue.
The type of messages allowed on SNDPGMMSG are *INFO, *INQ, *RQS, *COMP, *DIAG, *NOTIFY,
*ESCAPE, *STATUS.
For *NOTIFY, *ESCAPE, *STATUS messages Message Id and Message file are mandatory. It does not
take message text entered by the user.
For status message:
SNDPGMMSG MSGID(A000010) MSGF(MSGF1) TOPGMQ(*EXT) +
MSGTYPE(*STATUS)
For message at display station:
SNDPGMMSG MSGID(A000010) MSGF(MSGF1)

SNDUSRMSG (Send user message)


-

It can not be used on a command line.


It can use messages in message file for sending messages. It can also use the message text entered
by the user.
It can be used to send message either to a user profile or a message queue.
The type of messages allowed on SNDMSG are *INFO, *INQ.

E.g. SNDUSRMSG MSG('AS/400 MESSAGE FILES') TOUSR(#VYERRAP)


SNDBRKMSG (Send break message)
It can be used on a command line.
It can not use messages in message file for sending messages. It can only use the message text
entered by the user.
It can be used to send message only to a work station message queue.
The type of messages allowed on SNDMSG are *INFO, *INQ.
E.g. SNDBRKMSG MSG('AS/400 MESSAGE FILES') +
TOMSGQ (QPADEV000D)
Defining substitution variables
Consider the message File &1 not found in message file. Here &1 is the substitution variable. The value
in &1 is populated to make the message more meaningful as follows:

- 18 -

Tips n Facts
Add message Id P000001 in message file MSGF1 with message text as File &1 not found. And define
substitution variable &1 is as FMT ((*CHAR 10) in the message file.
SNDPGMMSG MSGID(P000001) MSGF(MGS1) MSGDTA(ORDHDR)
&1 is replaced with ORDHDR. Now the message will be displayed as File ORDHDR not found.
Please note that the command RMVMSG

CLEAR(*ALL) removes all messages from message queue.

Appendix E - %BINARY and %SWITCH built-in Functions


Using the %BINARY built-in Function
The binary built-in function (%BINARY or %BIN) interprets the contents of a specified CL character
variable as a signed binary integer. The syntax of the binary built-in function is:
%BIN (character-variable-name starting-position length)
The starting position and length are optional. You can use the binary built-in function with both the IF and
CHGVAR commands. The following are examples of the binary built-in function:
DCL VAR(&B2) TYPE(*CHAR) LEN(2)
DCL VAR(&N) TYPE(*DEC) LEN(3 0)
CHGVAR &N %BINARY (&B2)

VALUE(X'001C')

The content of variable &B2 is treated as a 2-byte signed binary integer and converted to its decimal
equivalent of 28. It is then assigned to the decimal variable &N
DCL VAR(&N) TYPE(*DEC) LEN(5 0) VALUE(107)
DCL VAR(&B4) TYPE(*CHAR) LEN(4)
CHGVAR %BIN (&B4) &N
The value of the decimal variable &N is converted to a 4-byte signed binary number and is placed in
character variable &B4 Variable &B4 will have the value of X'0000006B'.
DCL VAR(&P) TYPE(*CHAR) LEN(100)
DCL VAR(&L) TYPE(*DEC) LEN(5 0)
CHGVAR &L VALUE(%BIN(&P 1 2) * 5)
The first two characters of variable &P is treated as a signed binary integer, converted to its decimal
equivalent, and multiplied by 5. The product is assigned to the decimal variable &L.
Using the %SWITCH built-in Function
The switch built-in function (%SWITCH) compares one or more of eight switches with the eight switch
settings already established for the job and returns a logical value of '0' or '1'. The initial values of the
switches for the job are determined first by the Create Job Description (CRTJOBD) command; the default
value is 00000000. You can change this if necessary using the SWS parameter on the SBMJOB, CHGJOB,
or JOB command. Other high-level languages may also set job switches.
If, in the comparison of your %SWITCH values against the job values, every switch is the same, a logical
value of '1' (true) is returned. If any switch tested does not have the value indicated, the result is a '0'
(false). The syntax of the %SWITCH built-in function is:
%SWITCH (8-character-mask)
The 8-character mask is used to indicate which job switches are to be tested, and what value each switch
is to be tested for. Each position in the mask corresponds with one of the eight job switches in a job.
Position 1 corresponds with job switch 1, position 2 with switch 2, and so on. Each position in the mask
can be specified as one of three values: 0, 1, or X.
0

The corresponding job switch is to be tested for a 0 (off).

- 19 -

Tips n Facts
1

The corresponding job switch is to be tested for a 1 (on).

X
The corresponding job switch is not to be tested. The value in the switch does not affect the result
of %SWITCH.
If %SWITCH (0X111XX0) is specified, job switches 1 and 8 are tested for 0s; switches 3, 4, and 5 are
tested for 1s; and switches 2, 6, and 7 are not tested. If each job switch contains the value (1 or 0 only)
shown in the mask, the result of %SWITCH is true '1'.
On the IF command, %SWITCH can be specified on the COND parameter as the logical expression to be
tested. In the following example, 0X111XX0 is compared to the predetermined job switch setting: IF
COND(%SWITCH(0X111XX0)) THEN(GOTO C)
If job switches 1, 3, 4, 5, and 8 contain 0, 1, 1, 1, and 0, respectively, the result is true and the procedure
branches to the command having the label C. If one or more of the switches tested do not have the values
indicated in the mask, the result is false, and the branch does not occur.
On the CHGVAR command, you can specify %SWITCH to change the value of a logical variable. The value
of the logical variable is determined by the results of comparing your %SWITCH settings with the job
switch settings. If the result of the comparison is true, the logical variable is set to '1'. If the result is
false, the variable is set to '0'. For instance, if the job switch is set to 10000001 and this procedure is
processed:
PGM
DCL &A *LGL
CHGVAR VAR(&A) VALUE(%SWITCH(10000001))
.
.
ENDPGM
Then the variable &A has a value of '1'.
Appendix F - Data Queues
-

Data queues are a type of system object that you can create to which one HLL program can send
data. They are the fastest means of asynchronous communication between two jobs. To receive and
send data to DQ has fewer overheads than using database files, message queues or data areas. They
should not be used for storing large volumes of data and for long term storage of data. They are
similar to message queues in that programs can send and receive data from them. While only one
program can have receive pending on a message queue more than one program can have a receive
pending on a message queue at the same time.

To clear a data queue:


PGM
DCL
VAR(&QNAME) TYPE(*CHAR) LEN(10) VALUE('DTAQ1')
DCL
VAR(&LIB) TYPE(*CHAR) LEN(10) VALUE('MYLIB1')
CALL
PGM(QCLRDTAQ) PARM(&QNAME &LIB)
ENDPGM
To send data to a data queue:
PGM
DCL
DCL
DCL
DCL
CALL

VAR(&QNAME) TYPE(*CHAR) LEN(10) VALUE('DTAQ1')


VAR(&LIB) TYPE(*CHAR) LEN(10) VALUE('MYLIB1')
VAR(&FLDLEN) TYPE(*DEC) LEN(5) VALUE(17)
VAR(&FIELD) TYPE(*CHAR) LEN(17) +
VALUE ('Sample data queue')
PGM(QSNDDTAQ) PARM(&QNAME &LIB &FLDLEN +
&FIELD)

ENDPGM
To receive data from data queue:
PGM
DCL
DCL

VAR(&QNAME) TYPE(*CHAR) LEN(10) VALUE('DTAQ1')


VAR(&LIB) TYPE(*CHAR) LEN(10) VALUE('MYLIB1')

- 20 -

Tips n Facts
DCL
DCL
DCL
CALL
ENDPGM
-

VAR(&FLDLEN) TYPE(*DEC) LEN(5) VALUE(20)


VAR(&FIELD) TYPE(*CHAR) LEN(20)
VAR(&WAIT) TYPE(*DEC) LEN(5 0) VALUE(1)
PGM(QRCVDTAQ) PARM(&QNAME &LIB &FLDLEN +
&FIELD &WAIT)

The commands using all the parameters:


CALL

PGM(QSNDDTAQ) PARM(&QNAME &LIB &FLDLEN +


&FIELD &KEYLEN &KEY)
CALL
PGM(QRCVDTAQ) PARM(&QNAME &LIB &FLDLEN +
&FIELD & WAIT &ORDER &KEYLEN &KEY &SENDRLEN &SNDR)
&QNAME is 10-length character field that names the data queue.
&LIB is 10-length character field that names the library containing data queue.
&FLDLEN is 5-digit packed decimal variable, which specifies the number of characters sent to/received
from the data queue.
&FIELD is a character field of length equal to the value in &FLDLEN.
&KEYLEN is a 3-digit packed decimal variable, which specifies the length of the key sent to/received from
the data queue.
&KEY is a character field of length equal to the value in &KEYLEN.
&WAIT is a 5-digit packed decimal variable, which waits for the time specified in this variable if there are
no entries in the data queue.
&ORDER is a 2-length character field that retrieves a message using the specified character key like GT: or
LT: or NE: etc
&SNDRLEN is a 3-digit packed decimal field that sends the length of the sender identification parameter. It
must be zero or equal to or greater than 8.
&SNDR is a character field that identifies the variable to contain the sender identification information
associated with the received message.

Appendix G - Data area


-

A local data area cannot be created, deleted or allocated.

A local data area can not be referred to from any other job. Other programs within same job can refer it.

A Program Initialization Parameter data area (PIP) is created for each pre-start job when the job is
started. The size of PDA is 2000 bytes but the number of parameters contained in it is not restricted.

A data area is an object used to hold data for access by any job running on the system. It can be
used to store information of limited size, independent of the existence of programs and files.

A local data area (*LDA) is created for each job in the system with a length of 1024 and type *CHAR.
It can not be referred to from any other job. It can not be created, deleted or allocated. No library is
associated with it.

The contents of the submitting jobs LDA is copied in to submitted jobs LDA. Hence, the contents of
LDA exist across routing step boundaries.

A group data area (*GDA) is created when an interactive job becomes a group job with a length of
512 and type *CHAR. It can not be referred to from by jobs outside the group. It can not be created,
deleted or allocated. No library is associated with it.

- 21 -

Tips n Facts
Appendix H - SEU Colors and Attributes
-

You need to embed the hex value for the display attribute (highlight, blink, underline, color, etc.)
directly in the source statement to achieve this.
Create a member by name SEUFMTCODE of type TEXT in source physical file QRPGLESRC.
Do the following override and compile interactively the SEUCODES program of type RPGLE:
OVRDBF FILE (DUMMY) TOFILE (MYLIB1/QRPGLESRC) MBR (SEUFMTCODE)
Call the program SEUCODES, which will keep lines for various attributes in member SEUFMTCODE.
Copy the line that you want into the member you are editing and type over it.

The code for SEUCODES program


FDUMMY o
*
D Normal
D RI
D HI
D RI_HI
D UL
D RI_UL
D HI_UL
D ND
D BL
D RI_BL
*
C
C
C
C
C
C
C
C
C
C
C
C
C
C
C
C
C
C
C
C
C
*

Disk
s
s
s
s
s
s
s
s
s
s

eval
write
eval
write
eval
write
eval
write
eval
write
eval
write
eval
write
eval
write
eval
write
eval
write
eval

1
1
1
1
1
1
1
1
1
1

RENAME(QRPGLESRC:SEUFMTCODE)
Inz(x'20')
Inz(x'21')
Inz(x'22')
Inz(x'23')
Inz(x'24')
Inz(x'25')
Inz(x'26')
Inz(x'27')
Inz(x'28')
Inz(x'29')

SRCDTA = '
SEUFMTCODE
SRCDTA = '
SEUFMTCODE
SRCDTA = '
SEUFMTCODE
SRCDTA = '
SEUFMTCODE
SRCDTA = '
SEUFMTCODE
SRCDTA = '
SEUFMTCODE
SRCDTA = '
SEUFMTCODE
SRCDTA = '
SEUFMTCODE
SRCDTA = '
SEUFMTCODE
SRCDTA = '
SEUFMTCODE
*inlr = *on

' + RI + ' RI'


' + HI + ' HI'
' + RI_HI + ' RI_HI'
' + UL + ' UL'
' + RI_UL + ' RI_UL'
' + HI_UL + ' HI_UL'
Non-display next'
' + ND + ' ND'
' + BL + ' BL'
' + RI_BL + ' RI_BL'

Appendix I - Selecting Records Using the OPNQRYF Command


In all of the following examples, it is assumed that a single-format database file (physical or logical) is
being processed. (The FILE parameter on the OPNQRYF command allows you to specify a record format
name if the file is a multiple format logical file.)
To request a selection against a character constant
OPNQRYF FILE(FILEA) QRYSLT('CODE *EQ "D" ')
To request a selection against a numeric constant:
OPNQRYF FILE(FILEA) QRYSLT('AMT *GT 1000.00')

- 22 -

Tips n Facts
When comparing a charcter field value to a CL variable
OPNQRYF FILE(FILEA) QRYSLT('"' *CAT &CHAR *CAT '" *EQ FIELDA')
Notice that apostrophes and quotation marks enclose the CL variables and *CAT operators. (only character
CL variables can be used)
When comparing a numeric field value to a CL variable
OPNQRYF FILE(FILEA) QRYSLT(&CHARNUM *CAT ' *EQ NUM')
Notice that apostrophes enclose the field and operator only. (only character CL variables can be used)
Selecting records using the contains function
To process all records in which the Addr field contains the street named BROADWAY you can specify:
OPNQRYF FILE(FILEA) QRYSLT('ADDR *CT "BROADWAY" ')
Mapping fields for packed numeric data fields
In this example, if DATE was a date data type, it could be specified as follows:
OPNQRYF FILE(FILEA) QRYSLT ('YEAR *EQ 88') MAPFLD((YEAR '%YEAR(DATE)'))
Note: Mapped field definitions are always processed before the QRYSLT parameter is evaluated.
You could accomplish the same result by specifying the substring on the QRYSLT parameter and dropping
one of the mapped field definitions as follows:
OPNQRYF FILE(FILEA) +
QRYSLT('%SST(CHAR6 5 2) *EQ "88" ') +
MAPFLD((CHAR6 '%DIGITS(DATE)'))
Using the "wildcard" function
You would not select the other records because a comparison is made with blanks added to the value you
specified. The way to select all four names is to specify:
QRYSLT('NAME *EQ %WLDCRD("JOHNS*")')

Appendix J - User Defined Commands


The AS/400 control program lets users define a command that calls a program to perform some function.
Users can define commands by using a command definition statement.
Command Statements
The command definition statement of each command contains one or more of the following command
statements:
-

CMD (Command) - Specifies the prompt text for the command (Only one statement)
DEP (Dependent) - Defines the relationship among parameters
ELEM (Element) - Defines an element in a list used as a parameter value (A maximum of 300
statements)
PARM (Parameter) - Defines a parameter or key parameter for a command (A maximum 75 300
statements)
PMTCTL (Prompt Control) - Defines conditions under which certain parameters are prompted
QUAL (Qualifier) - Defines a qualifier of a name used as a parameter (A maximum of 300 statements)

Command Processing Program


The command processing program (CPP) is the program that the command analyzer calls to perform the
function requested. The CPP can be a CL program, another HLL program. The CPP must accept the
parameters as defined by the command definition statements. A command processing program is
mandatory.
Validity Checking program
To ensure that the valid values are entered for the required parameters, You may write your own validity
checking program. A Validity Checking program is optional.

- 23 -

Tips n Facts
Prompt Override Program
You can write prompt override programs to supply current values for parameter defaults when prompting
the command. For example, prompt override programs are frequently used on Change commands to
supply values for parameters with a default value of *SAME. A prompt override program is optional.
Command Creation
Let
-

us create command similar to WRKMBRPDM, by name WM with the following functionality:


When WM command is taken it will prompt for source file and library.
After you enter valid values it will show that PDM with the source file and library the user has entered.
If incorrect values are entered, the validation program sends error messages.

We
-

need three sources as follows:


WM of type CMD - Command program.
WMPRC of type CLLE - Command processing program.
WMVAL of type CLLE - Command validation program.
While compiling the command program take prompt to enter the processing program and validation
program.

The code for the Command Program (WM)


CMD
PARM
PARM

PROMPT('WORK WITH MEMBERS USING PDM')


KWD(FILE) TYPE(*NAME) LEN(10) PROMPT('File')
KWD(LIB) TYPE(*NAME) LEN(10) PROMPT('Library')

The code for Command Processing Program (WMPRC)


PGM
PARM(&File &Library)
DCL
VAR(&File) TYPE(*CHAR) LEN(10)
DCL
VAR(&Library) TYPE(*CHAR) LEN(10)
WRKMBRPDM FILE(&LIBRARY/&FILE)
ENDPGM
The code for Command Validity Checking Program (WMVAL)
PGM
DCL
DCL

PARM(&FILE &LIBRARY)
VAR(&FILE) TYPE(*CHAR) LEN(10)
VAR(&LIBRARY) TYPE(*CHAR) LEN(10)

/* Check for the existence of Library on the system

*/

CHKOBJ
OBJ(&LIBRARY) OBJTYPE(*LIB)
MONMSG
MSGID(CPF0000) EXEC(DO)
SNDPGMMSG MSGID(CPD0006) MSGF(QCPFMSG) MSGDTA('0000 +
Library . . does not exist on the +
System.') MSGTYPE(*DIAG)
SNDPGMMSG MSGID(CPF0002) MSGF(QCPFMSG) MSGTYPE(*ESCAPE)
ENDDO
/* Check for the existence of Source File in the specified Library */
CHKOBJ
OBJ(&LIBRARY/&FILE) OBJTYPE(*FILE)
MONMSG
MSGID(CPF0000) EXEC(DO)
SNDPGMMSG MSGID(CPD0006) MSGF(QCPFMSG) MSGDTA('0000 +
File . . does not exist in specified +
Library.') MSGTYPE(*DIAG)
SNDPGMMSG MSGID(CPF0002) MSGF(QCPFMSG) MSGTYPE(*ESCAPE)
ENDDO
ENDPGM

- 24 -

Tips n Facts
Technical Questions & Answer:
Files used on AS/400:

Physical file.

Source Physical file.

Logical file.

Join logical file.

Display file.

Printer file.

Spooled file.

Save file.
Difference between Dynamic select and Access path
Dynamic select
It occurs when the file is read

Acess path
It occurs before the file is read

Difference between logical file and physical file


PF
It may have only one record format
It contains actual data

LF
It may have multiple record format.
It doesnt contain data but provides a logical
and sequence view.

Three methods of maintain the access path


Immediate : All path associated with this file will update immediately.
Rebuild
: The open access path will be updated when changes is made.
Delay
: only access path that are updated are the ones that are open at the time the
change is made.
Difference between Lf and JLF
JLF is a type of LF that contains fields from two or more PF and combines them into a single
record format.
LF
JLF
It allows multiple record formats.
It allows only one record format.
Changes can be done through this.
Changes cant be done through this.
Record format should be the same as PF
Record format name must be different as PF

Essential keyword for JLF:


JFILE : To specify two or more file name to be joined.
JOIN: It is optional when two files are used. It is mandatory when more than two files are used
to specify what are the two files to be joined.
JFLD : It must be specified at least one time for each JOIN keyword entered.
JREF : It is used at field definition level to identify which PF the specified field is from.
Advantage of having *Like Define op-code in D spec.
At C Spec to define a field based on a binary or zoned numeric field, the new field is given
packed decimal type.
At D Spec it will carry the binary or zoned data type over to the newly defined field.
Advantage of D Spec :

It simplifies coding and maintenance of programs.


DS sub field can be indented,making them easier to read.
INZ keyword can be used to initialize the field.
New data type can be defined on the D spec.
Externally described file can be renamed using the PREFIX keyword.

- 25 -

Tips n Facts
DS Types :

Program described DS.

Data Area DS.

File information DS.

Program Status DS.


LDA(Local Data Area) :

It is automatically created by the system when a batch or interactive job is initiated.

LDA consists of a single character field of 1024 bytes.

When no data area name is specified it uses automatically.


Data Area DS:
UDS is specified on the D spec to define a Data Area DS.
Data Area Commands:
CRTDTAARA : To create a Data Area.
CHGDTAARA: To change the Data Area.
RTVDTAARA : To retrieve the Data Area.
ALCOBJ
: To lock the Data Area.
SNDDTAARA : copies the data from CL field to a Data Area.

Figurative constant :
It is a type of literal that derives its definition directly from the program field with which it is associated.

*BLANKS

*ZEROS

*HIVAL

*LOVAL

*ALLX

*ON

*OFF
Record Lock :
If a file is defined with input for update on the F spec, and a record is read from that file, the program
locks the record for update.
File information DS can be used to check for a record lock:
Ffilex

UF

DFld1
D Stat1

DS

K Disk

INFDS(FLD1)

*Status
File continuation line will contain INFDS together with a DS name.
DS name specified on the F spec is then used on the D spec to define the DS itself.
DS sub field defined with RPG reserved word *STATUS will contain the error code 01218 if the
record is locked.

Five ways to release a record lock:

Update or delete operation will release a record lock.


Read or Chain operation performed on the file will unlock a record that was locked by a previous
READ or CHAIN.
SETLL or SETGT operation will release a record lock.
UNLOCK will release a record lock.
Except operation can be used to release the record lock.

Three types of Arrays:


Compile Time Array : It is loaded to array when the program is created or compiled.
Prexecution Time Array : It is automatically loaded into the array name when the program is called.

- 26 -

Tips n Facts
Execution Time Array : It is loaded to program after it is called.

Difference between primary file and full procedural file:


Primary file
It reads sequentially and automatically from
beginning to end.
Order of the record read cant be changed
Only one primary file allowed per program

Full procedural file


It reads in any order.

Many files can be specified as full procedural.

Some approaches to create a structured RPG program

Sets of logic into a separate subroutine that can be called when required.

Use proper commenting and documentation to describe each function performed by the program.

Avoid GOTO statements.

Try to have only one read and one update statement per file format used by the program.

Use RPG structured programming op-codes.


ILE Tips:

ILE RPG op-code CALLB is used on the C spec to call the program.
Programs are than made into non
executable objects called Modules using the Create
Module(CRTPGMMOD) command.
Finally the modules are bound using the CRTPGM or the CRTSRVPGM command.
After the programs are bound together, the call performance is greatly improved.

Error handling:

If Level check *YES was specified for the file when it was created, the program will abend with a
CPF message (CPF4131) that says there is a File Format Level check.

Level Check *YES is the default used by the system for file creation.

If level check *NO was specified for the file when it was created, the program may run; however,
the program may produce incorrect results.

A READ or CHAIN operation must precede an UPDATE operation. If an update is done without a
Read or Chain, the program will end with error Update issued without prior read or Chain.

Subfile:

a group of records that have the same record format and are read from and written to a display
station in one operation. As the term suggests, a subfile is not a file; rather, it is a temporary
place to store data of the same format to be used by a display file program..
A subfile is considered a relative record file since it may not be accessed by a key but only by a
RRN.

Work with Display Records


File . . . . . . : QDDSSRC
Library . . . . :
LIBKA

Member . . . . . . : CL018
Source type . . . : DSPF

Type options, press Enter.


1=Add
2=Edit comments
7=Rename
8=Select keywords
Opt Order
10
20
30

Record
CL01801
CL01800
CL01802

Type

3=Copy
4=Delete
12=Design image

Related Subfile

SFL
SFLCTL CL01801
RECORD

Date

00/00/00
30/08/07
00/00/00

- 27 -

DDS Error

Tips n Facts

0004.00
0005.00
0006.00
0007.00
0008.00
0009.00
0010.00
0011.00 R CL01801
0013.00
0014.00 CLNAM2
0015.00 KCLN2$
0016.00 SELEC$
0017.00
0018.00
0019.00 CLNAM$
0020.00
0021.00
0022.00 ADDR1$
0023.00
0024.00
0037.00 CANDT$
0038.00
0039.00
0040.00
0048.00 CLTMSC
0049.00
0050.00
0051.00
0052.00 R CL01800
0054.00
0055.00
0056.00
0057.00
0058.00
0059.00
0060.00
0061.00
0062.00
0063.00
0064.00
0065.00
0066.00
0067.00
0068.00
0069.00
0070.00
0071.00
0072.00
0073.00
0074.00
0075.00
0076.00
0077.00
0078.00
0079.00
0080.00 CPOSL#
0081.00 CPOSC#
0082.00 DSPST$

DSPSIZ(24 80 *DS3)
CHGINPDFT(HI CS)
MSGLOC(24)
PRINT CF04
(FILE LEVEL KEYS)
ROLLUP(28)
ROLLDOWN(29)
VLDCMDKEY(26 'Valid command keys')
SFL
TEXT('Search Subfile')
R
H
REFFLD(RDTAREF/CLNAM *LIBL/DTAREF)
R
H
REFFLD(RDTAREF/KCLN2 *LIBL/DTAREF)
R
B 7 2REFFLD(RDTAREF/SELEC *LIBL/DTAREF)
DSPATR(PC)
VALUES(' ' '1')
R -7 O 7 4REFFLD(RDTAREF/CLNAM *LIBL/DTAREF)
DSPATR(HI)
COLOR(BLU)
R -5 O 7 38REFFLD(RDTAREF/ADDR1 *LIBL/DTAREF)
DSPATR(HI)
COLOR(BLU)
R
O 8 18REFFLD(RDTAREF/CANDT$ *LIBL/DTAREF)
EDTWRD(' / / 0')
COLOR(PNK)
DSPATR(HI)
R
O 8 73REFFLD(RDTAREF/CLTMS *LIBL/DTAREF)
COLOR(BLU)
EDTCDE(Z)
DSPATR(ND)
SFLCTL(CL01801)
CF13
CF14
CF15
CF16
CF17
CF18
CF19
CF20
CF21
CF22
CF23
CF24
CF01(01)
CA03(03)
CF12(12)
KEEP
CSRLOC(CPOSL#
CPOSC#)
OVERLAY
SFLDSP(25)
SFLDSPCTL(26)
SFLINZ(28)
SFLCLR(29)
SFLSIZ(0009) Max: 9999
SFLPAG(0008) Max: Depend upon display record size
SFLMSGID(UER0036 *LIBL/QUSERMSG)
SFLMSGID(UER0110 *LIBL/QUSERMSG)
R
H
REFFLD(RACTFIL/CPOSL# *LIBL/ACTFIL)
R
H
REFFLD(RACTFIL/CPOSC# *LIBL/ACTFIL)
R
H
REFFLD(RDTAREF/DSPST$ *LIBL/DTAREF)

- 28 -

Tips n Facts
0082.00 DSPST$ R
H
REFFLD(RDTAREF/DSPST$ *LIBL/DTAREF)
0083.00
SFLRCDNBR
0084.00
1 2'CL018'
0085.00 CMPNY# R
O 1 22REFFLD(RDTAREF/CMPNY# *LIBL/DTAREF)
0137.00 R CL01802
0139.00
OVERLAY
0140.00
23 2'1 - Select
0141.00
F3=Exit F12=Previous'
0142.00
COLOR(BLU)
0143.00 MSGLN# R
O 24 2REFFLD(RDTAREF/MSGLN# *LIBL/DTAREF)
0144.00
DSPATR(HI)

CL018

OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO

OOOOOOOO OOOOO

CLIENT SELECT Search by OOOOOOOOOOOOOOOOOOOOOOOOOOOOOO Locate BBBBBBBBBBBBBBBB


Master Client: 6666666 - OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
Client Name
Address
Postcode Clt No.
Branch
Cancelled Search Index
Telephone
B OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO OOOOOOOOOOOOOOOOOOOOOOOOO OOOOOOOO
6666666
OO
OO 66/66/66 OOOOOOOOOOOOOOOO OOOOOOOOOOOOOOOO
B OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO OOOOOOOOOOOOOOOOOOOOOOOOO OOOOOOOO
6666666
OO
OO 66/66/66 OOOOOOOOOOOOOOOO OOOOOOOOOOOOOOOO
B OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO OOOOOOOOOOOOOOOOOOOOOOOOO OOOOOOOO
6666666
OO
OO 66/66/66 OOOOOOOOOOOOOOOO OOOOOOOOOOOOOOOO
B OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO OOOOOOOOOOOOOOOOOOOOOOOOO OOOOOOOO
6666666
OO
OO 66/66/66 OOOOOOOOOOOOOOOO OOOOOOOOOOOOOOOO
B OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO OOOOOOOOOOOOOOOOOOOOOOOOO OOOOOOOO
6666666
OO
OO 66/66/66 OOOOOOOOOOOOOOOO OOOOOOOOOOOOOOOO
B OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO OOOOOOOOOOOOOOOOOOOOOOOOO OOOOOOOO
6666666
OO
OO 66/66/66 OOOOOOOOOOOOOOOO OOOOOOOOOOOOOOOO
B OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO OOOOOOOOOOOOOOOOOOOOOOOOO OOOOOOOO
6666666
OO
OO 66/66/66 OOOOOOOOOOOOOOOO OOOOOOOOOOOOOOOO
B OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO OOOOOOOOOOOOOOOOOOOOOOOOO OOOOOOOO
6666666
OO
OO 66/66/66 OOOOOOOOOOOOOOOO OOOOOOOOOOOOOOOO

Clear a Subfile:
SETON
WRITE SFC1
SETOFF

29
(Subfile clear indicator)
(Subfile control record format name)
29

Initialize a Subfile:
SETON

28

Load a Subfile:
READ
ADD
WRITE

EMPPF
1
SFL1

(Physical file)
RRN1
***MUST : RRN value must be set prior to writing Subfile RCD FMT ****
(Subfile record format)

Displaying Subfile:

- 29 -

Tips n Facts
SETON
EXFMT

2526

SFC1

(SFLDSP SFLDSPCTL indicators)


(Subfile control record format name)

Displaying More at Bottom:


SETON

30 (SFLEND indicator)

TYPES OF LOADING THE SUBFILE


1. Load All

SFLSIZ>SFLPAG

In this method of loading the subfile, all the records from the physical file are loaded at a stretch into
the subfile before displaying the subfile.

When all the physical file records are loaded, the subfile can be displayed.

Maximum of only 9999 records can be loaded.

The EXFMT opcode will display the subfile from the first page.

The subsequent pages of the subfile can be seen by pressing page down key.The previous pages can
be seen by pressing the page up key. The subfile can be written into the display device file in one
single operation. A group of records can also be read from the display device.

Declare physical file.


Declare display file with RRN for subfile record format.
Initialize RRN value.
Clear subfile.
Load subfile with all the physical file records.

Seton

Seton SFLEND indicator when end of file is reached.

EXFMT the subfile control record format.


Associate a function key to come out

SFLDSP

2. Load on demand

SFLDSPCTL

SFLSIZ>SFLPAG

In this method of loading the subfile, only the page full of


before displaying the subfile.

(i.e. 4) records is loaded from the physical file

When the first page is loaded the subfile can be displayed.The EXFMT opcode will display the subfile's first
page. The subsequent page of the subfile has to be loaded by pressing page down key.Again the subfile
can be displayed by exformatting. The newly loaded pages will be appended to the existing pages.
The previous pages can be seen by pressing the page up key.
Declare physical file.
Declare display file with RRN for subfile record format.
Initialize RRN value.

- 30 -

Tips n Facts
Clear subfile.
Load subfile with first page.
Store the starting key for the next page in a temporary variable

Set on

EXFMT the subfile control record format.

Associate a function key to come out.

When page down key is pressed build the next page.

Store the starting key for the next page in the temporary variable.

Set on

SFLDSP

SFLDSPCTL
(Displays only first page of the Subfile)

SFLEND when the end of the file is reached

3. Load one Page at a Time

SFLSIZ=SFLPAG

Declare physical file.

Declare display file with RRN for subfile record format.

Initialize RRN value.

Clear subfile.

Load subfile with first page.

Store the starting key for the next page in a temporary variable

Seton

EXFMT the subfile control record format.


Associate a function key to come out.

When page down key is pressed clear the subfile and build the next page .

When page up key is pressed clear the subfile and build the previous page.

When position to field is filled and enter is pressed clear the subfile and build the page starting from
that record.

Store the linking key for the next page and the linking key for the previous page in temporary
variables.

Seton

SFLDSP

SFLDSPCTL

SFLEND when end of the file is reached.

If the Subfile size is at least ONE GREATER than the subfile page then the subfile size will grow
dynamically up to 9999.
If SFLSIZ = SFLPAG then SFL size will not grow.

READC:

This opcode 'READ CHANGED record will be used to read, only the records from the subfile which
are changed in the display.

- 31 -

Tips n Facts

E.g. when we have a subfile displayed with many records and an option field for every record like that
of the PDM screen. (options like 2 = edit 4 = delete 5 = display can be entered for that option ).

The records for which you have entered an option have to be processed.

MDT:

Every subfile record will have a modified data tag set on for it when it is a changed record.
When READC is performed on a changed record the MDT will be made off and READC will consider a
record as a changed one if the MDT is on.

Hence READC when performed for the second time on the same record, which was changed before
but not changed for the second time, will not work.

But we may need to perform READC more than once on a changed record once for validation and
then for taking some action.

So we should have the facility to seton the MDT again for the changed record even after performing
READC.

This can be done using the keyword SFLNXTCHG (subfile next change).

SFLNXTCHG should be associated with an indicator in subfile record format level keyword. Standard
indicator 27.

UPDAT opcode should be used to seton the MDT as follows.

Seton
Updat
subfile record format
Setof

27
27

Subfile ADD:
Subfile Delete:
Subfile Update:
Message Subfile:
SFLMSGRCD
SFLMSGKEY
SFLPGMQ

Tips about subfile:


Two record formats are required in the display file DDS to code one subfile.
Subfile record format is coded first.
Subfile control record format is coded second.
Five important keywords about subfile:
SFL : it is used on the subfile record format.
SFLCTL: the keyword with the name of the subfile Record format is specified on the Subfile control
record format.
SFLDSP : It is necessary on the subfile control Record Format since it causes the subfile records to be
displayed.
SFLSIZ : it is necessary to define the total size of the subfile.
SFLPAG: it is necessary to define how many subfile records are displayed at a time.
SFLNXTCHG Uses:

- 32 -

Tips n Facts

It is specified with an indicator on a Subfile Record Format that is defined to allow modification of
subfile records by the user.
When user changes subfile records the RPG opcode READC is used to read all records that were
modified in the subfile, which will allow the program to validate them and display any errors
found to the user.
When validation is performed, a record in error is updated in the subfile with the SFLNXTCHG
indicator turned on.
Updating a subfile record with the SFLNXTCHG indicator set on will cause the record to be
considered modified even though no further changes are made to the record.
When the subfile is read again, even though the user did not change that record, the READC opcode will pick the record up again for validation and redisplay the same error until corrected.
This will prevent the user from ignoring any errors made when changing data in a subfile.

Message subfile :
It is a special file that may contain multiple messages taken from the Program Message Queue and placed
in the message subfile for display on the screen.
SFLMSGRCD: It allows which line of the screen the subfile will begin display of its records.
SFLMSGKEY: It is used as message reference key to locate and select msgs from the program message
queue when loading the message subfile.
SFLPGMQ : When it is specified on the subfile Record Format, the messages are added to the subfile from
the Program queue one at a time.
Difference between CA01 and CF01
CA01
CF01
Any data entered on the screen is not returned to Any data entered on the screen is returned to the
the program when the command key is pressed.
program when the command key is pressed.

+ to the subfile:
SFLEND is a record-level keyword used to generate a plus sign in the lower-right-hand corner of the
screen when there are more subfile records to be displayed.
If *MORE is specified with the SFLEND keyword, then the screen will display the word More on the lower
right. Bottom.. when subfile is reached at bottom.
Overlay keyword:
It is used to display more than one record format on the screen at the same time.
Difference between CLRL and OVERLAY
CLRL

OVERLAY

It is used to clear a specific number of lines from the


screen before a format is displayed.

It does not control the number of lines that are


cleared and does not allow two record formats to
overlap.

It control the number of lines cleard. If the SLNO


keyword is specified, then the first line number to be
cleared is also controlled by clear line.
OPNQRYF:

It provides a variety of execution time functions on physical or logical files such as Dynamic
record Selection, Dynamic Keyed Access path, Dynamic Join and Group processing.

Based on command a temporary access path to the file specified by the OPNQRYF command is
created and shared by other programs called after OPNQRYF is initiated.
A file in an RPG program that uses the access path created by an Open Query file should be
overridden

RPG program should be overridden to the file name used in the OPNQRYF statement in the CL
program with SHARE *YES specified on the override statement.

Why use LF rather than Open Query File:

- 33 -

Tips n Facts

If the PF u are working with is very large, creating and using a LF will allow an application to
perform faster than using an Open Query file.
Since access path created by Open Query file are temporary, applications that use an access path
frequently will be more efficient using a LF, since the access path will not have to be rebuilt every
time the file is open.

CL Tips:

Only one file can be defined using the DCLF statement in a CL program.

SNDRCVF may be used to write and read a display file record format.
How to set Lower limit to a file in a CL program:

Use the POSDBF command with parameter File section Set to start.

Use the OVRDBF command , which allows you to position the file by a key value, by RRN or set to
*START.
How to

check for an error in a CL program to prevent the CL:


Use the CL command MONMSG with the MSGID parameter set to CPF9999.
It may be specified at program level by being placed immediately after all declare statements.
An error detected for any CL command in the pgm is caught and sent to job log of the job where
the CL program is running.

How to read a file sequentially from beginning to end:


PGM
DCLF FILE(FILEA)
READAGN:
RCVF
MONMSG MSGID(CPF0864) GOTO CMDLBL(END)
GOTO CMDLBL(READAGN)
END:
ENDPGM
To identify CL program executing batch or interactive:

RTVOBJA .

Specify the field name on the TYPE parameter in the RTVOBJA command.

If value is 0 then it is batch job.

If value is 1 then it is interactive job.


To duplicate a file :

CPYF

CRTDUBOBJ
Only two field need to be updated where 1000 fields present in physical file.

It is most efficient to execute an output operation to the O spec where the file names and
field names to be updated are specified.
RLU:
To pring last ten pages when 10000 pages present
CHGSPLFA can be used to cause a spooled file to being printing from whatever page u specify on the
command.
Parameter PAGERANGE will allow to control the number of pages to be printed from the initial page
specified.
Expecting parameter and not expecting parameter:

If program expects parameters to be passed and you dont wish to pass parameters, one
solution is to pass the parameter with blanks and zeros, as with initialization.

If program expects parameter to be passed but you specifically dont wish to pass parameter
in a given solution , you may specify the Program Status Data Str. Which is defined on the I
spec using SDS with *PARMS keyword and a field name to contain the data.

The field name specified together with the *PARMS keyword will contain the number of
parameter passed to the program.

The code that specifies the parameter list *ENTRY PLIST on the C spec must be conditioned
not to execute when the no. of parameters passed to the program is zero.

- 34 -

Tips n Facts
To handle date field in CL program:
CHGVAR VAR(&Character) value (&Numeric)
CHGVAR VAR(%SST(&Fulldate 1 2)) value(&Century)
Journaling and commitment control:
Journaling is a function which record the changes in a file in a journal.
These record images are used to recover the changes in the file should the system end abnormally.
Commitment control is a function that allows you to define and process no. of changes to database
file as a single unit.
1.
2.
3.
4.

CRTJRNRCV JRNRCV(KANLIB/JRNRCV1)
CRTJRN JRN(KANLIB/JRN1) JRNRCV(KANLIB/JRNRCV1)
STRJRNPF File(KANLIB/PARENT) JRN(KANLIB/JRN1) IMAGES(*Both)
STRJRNPF File(KANLIB/CHILD) JRN(KANLIB/JRN1) IMAGES(*Both)

ADDPFCST:
Delete Rule : *NOACTION
Update Rule : *NOACTION
ADDPFCST
FILE(KANLIB/CHILD)
TYPE(*REFCST)
PRNFIL(KANLIB/PARENT) PARKEY(DEPTNO)

TESTN

KEY(DEPTNO)

CST(CONST1)

All numeric in the given string high will be on.


Leading blanks with valid numeric Low will be on.
All blanks Equal will be on.
Invalid numeric all will be zero.

Chain:
IF record not found high indicator will be set on else will be set off.
Any error low indicator will be set on.
Lokup:
If record found equal will be on.
High will be on when it finds nearest higher than.
Low will be on when it finds lower than.
OCCUR:
Low will be on if an attempt is made to set the current occurrence out of range.

AS/400 QUESTION BANK


1.Define library?

A Library is a collection of objects.

Type *LIB that is used to group related object and to find objects by name.

A library is a directory to a group of objects.

The number of objects contained in a library and the number of libraries on the system
are limited only by the amount of storage available.

All libraries are placed in the system library QSYS.

- 35 -

Tips n Facts

Libraries provide a method for organizing objects.

A library is an open-ended directory.

A library can never become FULL as if has no finite size.

Libraries themselves are objects.

A library contain the object name, type, and the address

Library list

System library- 15 (QSYSLIB)


QSYS
QHLPSYS
QUSRSYS

Product library 2

Current library 1

User library

- 25 (QUSRLIB)

QGPL
QTEMP
MYLIB
When you logon the first library to be load is QSYS. The system library is loaded at the
first time.
2.Define object?

Every thing that can be stored or retrieved on the system is known as an OBJECT.

Objects exit to make users independent of the implementation used in the machine.

The create object instruction establish the objects name and its type.

All objects are structured with a common object header, and a type

dependent

functional portion.

A user is not concerned with the space his object occupies.

The system allocate space automatically

WRKOBJPDM is used to display all object in such a library

The library the object name and its type is Unique.

3.Define source physical file?


Source physical file is also a file, which has one, or more files included in it. It is just like a
directory and it contains many members. The members are like a various programs residing in the
directory CRTSRCPF is used to create source physical file.
4.Define physical file?
It is a file, which physically occupies the portion of memory. A physical file contains one record
format and one or more members. Its type PF. By using CRTPF command to create PF. Maximum number
of fields included in a PF is 8000. Maximum no of key fields included is 120.
5.Define logical file?
Logical file does not occupies any memory space and logical file be derived from physical file. One
or more logical file can be derived from a single physical file. A logical file can contain up to 32 record

- 36 -

Tips n Facts
formats. It selects records dynamically. It cannot exist with out a physical file. We can filter the data with
criteria by using select and omit command. CRTLF command is used to create a LF. It accesses the data
by creating access path.
A logical file does not contain any data but provides the VIEWS of the data to satisfy end-users
needs.
There are two types

Non join logical file

Join logical file

6.Difference between physical file and logical file?


Physical file

Logical file

1. Occupies the portion of memory. Its containing

Does not occupy any memory space. Does not

data.

contain any data.

2. A physical file contains one record format

A logical file can contain up to 32 record formats.

3.Can be exist even with out LF

Can not exist with out PF

4. If you delete a LF, the PF can not be deleted

If you delete a LF, the PF can not be deleted

5.CRTPF command is used to create such object

CRTLF command is used to create such type object

6.The object type is PF

The object type is LF

7. What are the four levels of entries in physical file?


(i).

File level entries (optional): File level entries give the system information of the
entire file. (UNIQUE, LIFO, FIFO, FCFO, REF)
UNIQUE: A record cannot be entered or copied into a file if its key value is same as the
key value of a record already existing in the file.
LIFO: Last in first out
FIFO: First in first out
FCFO: First change first out.
REF: This keyword is used to specify the name of the file from which the field
descriptions are retrieved.

Ex: you can specify whether the key is unique.


(ii).

Record format level entries: Record format level entries give the system information
about specific record format in the file. For a PF the record format name is specified
along with an optional text description. (FORMAT, TEXT)
(i) FORMAT:

This record-level keyword specifies that the record format being define is to share the
field specifications of a previously defined record format. The name of the record format
being defined must be the name of the previously defined record format.
The format of this keyword is:
FORMAT (LIB-NAME / FILE-NAME)

- 37 -

Tips n Facts
(ii) TEXT:
This record level keyword is used to supply a text description of the record format and it
is used for documentation purposes only.
The format of this keyword is:
TEXT (description)
(iii)

Field level entries: The field names and field lengths are specified along with and
optional text description for each field. (ALIAS, ALWNULL, CCSID, CHECK, CHKMSGID,
CMP, COLHDG, COMP, DATFMT, DATSEP, DFT, EDTCDE, EDTWRD, REFFLD, REFSHIFT,
TEXT, TIMEFMT, TIMESEP, VALUES, VARLEN)

(iv)

Key field level entries: The field names used as key fields are specified. (DESCEND,
SIGNED, ABSVAL, UNSIGNED, ZONE, NOALTSEQ, DIGIT)

8. What are the six levels of entries in logical file?


(i)

File level entries (optional): File level entries give the system information of the
entire file. You can specify whether the key is same as physical file.

(ii)

Record format level entries: Record format level entries give the system information
about specific record format in the file. For examples, for a logical file when a record
format is described we can specify the physical file it is based on.

(iii)

JOIN Level entries:

Join level entries give the system information about PF used

in a JOIN LOGICAL FILE. (It is not applicable to NON JOIN LOGICAL FILES).
(iv)

Field level entries (optional): The field level entries give the system information
about individual fields in the record format.

(v)

Key field level entries: The key field level entries give the system information about
the key fields of a file. The field names used as key fields are specified.

(vi)

Select / Omit level entries: These entire give the system information about which
records are to be returned to the program when processing the file. These specifications
apply to logical file only.

9. Explain JDUPSEQ and JDFTVAL.


JDUPSEQ:
This join level keyword is used to specify the order in which records with duplicate join
fields are presented when the JLF is read.
The format for this keyword is:
JDUPSEQ (Sequencing field-name [*DESCEND])

This keyword has no effect on the ordering of records with unique keys.

If *DESCEND is not specified then the default is sequencing in ascending order.

JDFTVAL:

When this file-level keyword is used the system provides default values for all for fields
when a join to a secondary file does not produce any records.

If this keyword is not specified a record in the primary file for which there is
no corresponding record in the secondary file is skipped.

10. What are the different between non-join logical files and join logical files.

- 38 -

Tips n Facts
Non join logical file
We can able to insert or delete or update records

Join logical file


Insertion, updating or deletion of records is not

using non-logical file.


DFU can be used to display non-join logical file.
1-32 record format is specified
Commitment control is used

possible in join logical files.


DFU is not available
Only one record format can be specified
Commitment control cannot be used.

11. How many record formats can have physical & logical file.

The physical file only one record format can be specified.

The logical file 1-32 record format is specified

12. What is the advantage open query file?

Dynamic selection of records

It will sort the records based on the field values.

We can retrieve records based on Virtual fields.

Can create join logical files

13. Explain non-join logical file?


Non-join logical files can either be a simple logical file, which contains only one record format or a
multiple record format logical file, which contains more than one
Record format.
Logical files can be derived from 1 to 32 physical files and so a logical file can have a maximum
of 32 record formats.

Single record format logical file:


If a logical file is derived from single physical file it is called simple logical file.

Multiple record format logical file:


Multiple record non-join logical files will select records from 2 or more physical files by referring
to only one logical file.

Each record format is always associated with one or more physical file.

The same PF can be used in more than one record format.

Specify the entries in single or multiple format logical files:


1.File-level entries (optional): (REFACCPTH, DYNSLT)
REFACCPTH: The access path information for this logical file is to be copied from another
PF or LF.
Format of the keyword is:
REFACCPTH (LIB name / DATABASE name)
DYNSLT: This keyword is selection and omission tests in the file. This keyword specifies
dynamic select/omit.
2.Record level entries:(PFILE)
PFILE: The physical files containing the data to be accessed through the
Record formats being defined.
Format of the keyword is:
PFILE (LIB name / PF name)
3.Field-level entries (optional)
4. Key field level entries (optional)
5.Select and Omit field level entries (optional)

- 39 -

Tips n Facts
REFACCPTHIt is applicable for non-join logical file only and meaning is referring the
access path from the PF or LF in the file level entries.
PFILE--- it is applicable only for non-join logical file in record level entries.
14. Explain join logical file?
A join-logical file is a logical file that combines two or more PF. In the record format not all the
fields need to exist in all the PF.

A PF cannot be changed through a JLF.

DFU cannot be used to display a JLF.

Only one record format can be specified in a JLF.

Commitment control cannot be used with a JLF.

Key fields must be fields defined in the join record format and must be fields from the
PRIMARY FILE.

Specify the entries in join logical file:


1.File-level entries (optional): (JDFTVAL)
2.Record-level entries: (JFILE)
3.join-level entries :(JOIN, JFLD, JDUPSEQ)
4.field level entries (optional): (JREF, ALL, CONCAT, DYNSLT, RENAME, SST, TRNTBL)
5.Key field level entries (optional)
6.Select and Omit field level entries. (Optional)

JFILE----It is similar to indicate that this is a join logical field and it must
have more than 2 physical files.

JOIN: It is similar that this file level entries to be represent the position of
the files .There must

one primary file and can have

secondary files..

JFLD: Which feels we are going to join.

JREF: represents the primary file reference field

JDFTVAL: represents that it as a left outer join.

SELECT OMIT
Columns . . . 1 71
Edit
KSENTHILS/EXAMPLE
SEU==> SELOMIT
FMT PF.
*************** Beginning of data *******************
0001.00
R RECSEL
0002.00
EMPNO
5P 0
0003.00
EMPNAME
20A
0004.00
K EMPNO
****************** End of data ************************
EMPNO EMPNAME
000001 10,001 SHYAM
000002 10,002 SANKA
000003 10,003 SHYAM
000004 10,004 SENTH
000005 10,005 SANKA
000006 10,006 SHYAM
000007 10,007 SANKA
000008 10,008 SENTH
000009 10,009 SHYAM

- 40 -

more than I

Tips n Facts
000010 10,010 SENTH
****** ******** End of report ********
Columns . . . 1 71
Edit
KSENTHILS/EXAMPLE
SEU==> SELOMILF
FMT LF...
*************** Beginning of data *********************
0001.00
R RECSEL
PFILE (SELOMIT)
0002.00
K EMPNO
0003.00
S EMPNO
CMP (GT 10003)
0004.00
O EMPNAME
CMP (EQ 'SHYAM')
****************** End of data **************************
Display Report
EMPNO EMPNAME
000001 10,002 SANKA
000002 10,004 SENTH
000003 10,005 SANKA
000004 10,006 SHYAM
000005 10,007 SANKA
000006 10,008 SENTH
000007 10,009 SHYAM
000008 10,010 SENTH
****** ******** End of report ********
Columns . . . 1 71
Edit
KSENTHILS/EXAMPLE
SEU==> SELOMILF
FMT LF
*************** Beginning of data ************************
0001.00
R RECSEL
PFILE (SELOMIT)
0002.00
K EMPNO
0003.00
O EMPNAME
CMP (EQ 'SHYAM')
0004.00
S EMPNO
CMP (GT 10001)
****************** End of data ************************
EMPNO EMPNAME
000001 10,002 SANKA
000002 10,004 SENTH
000003 10,005 SANKA
000004 10,007 SANKA
000005 10,008 SENTH
000006 10,010 SENTH
****** ******** End of report ********
Columns . . . 1 71
Edit
KSENTHILS/EXAMPLE
SEU==> SELOMIT
FMT PF.
*************** Beginning of data *******************
0001.00
R RECSEL
0002.00
EMPNO
5P 0
0003.00
EMPNAME
20A
0004.00
K EMPNO
****************** End of data ************************

EMPNO EMPNAME
000001
20 SHYAM
000002
30 RAM
000003
40 TOM
000004
50 RAMESH
000005
60 SHYAM
000006
70 SHYAM
000007
80 TOM
000008
90 TOM
000009 100 VASU
****** ******** End of report ********

- 41 -

Tips n Facts
Columns . . . 1 71
Edit
KSENTHILS/EXAMPLE
SEU==> SELOMILF1
FMT LF
*************** Beginning of data ************************
0001.00
R RECSEL
PFILE (SELOMIT1)
0002.00
K EMPNO
0003.00
S EMPNO
CMP (GT 50)
0004.00
S EMPNAME
VALUES ('SHYAM')
****************** End of data **************************
EMPNO

EMPNAME
000001
20 SHYAM
000002
60 SHYAM
000003
70 SHYAM
000004
80 TOM
000005
90 TOM
000006 100 VASU
****** ******** End of report ********
Columns . . . 1 71
Edit
KSENTHILS/EXAMPLE
SEU==> SELOMILF1
FMT LF.
*************** Beginning of data ************************
0001.00
R RECSEL
PFILE (SELOMIT1)
0002.00
K EMPNO
0003.00
S EMPNO
CMP (GT 50)
0004.00
O EMPNO
RANGE (20 40)
****************** End of data ***************************

EMPNO EMPNAME
000001
50 RAMESH
000002
60 SHYAM
000003
70 SHYAM
000004
80 TOM
000005
90 TOM
000006 100 VASU
****** ******** End of report ********
Columns . . . 1 71
Edit
KSENTHILS/EXAMPLE
SEU==> SELOMILF1
FMT LF
*************** Beginning of data ****************
0001.00
R RECSEL
PFILE (SELOMIT1)
0002.00
K EMPNO
0003.00
S EMPNO
CMP (GT 50)
0004.00
S EMPNAME
VALUES ('SHYAM')
0005.00
O EMPNO
RANGE (70 90)
****************** End of data ********************
EMPNO EMPNAME
000001
20 SHYAM
000002
30 RAM
000003
40 TOM
000004
50 RAMESH
000005
60 SHYAM
000006
70 SHYAM
000007
80 TOM
000008
90 TOM
000009 100 VASU
****** ******** End of report ********
Columns . . . 1 71
Edit
KSENTHILS/EXAMPLE
SEU==> SELOMILF1
FMT LF

- 42 -

Tips n Facts
*************** Beginning of data *****************
0001.00
R RECSEL
PFILE (SELOMIT1)
0002.00
K EMPNO
0003.00
S EMPNO
CMP (GT 50)
0005.00
O EMPNO
RANGE (70 90)
****************** End of data ************************
EMPNO EMPNAME
000001
20 SHYAM
000002
30 RAM
000003
40 TOM
000004
50 RAMESH
000005
60 SHYAM
000006
70 SHYAM
000007
80 TOM
000008
90 TOM
000009 100 VASU
****** ******** End of report ********
15. Explain self join?
Joining a file to it self is known as self-join.
(Or)
A physical file can be joined to itself to read records that are formed by combining two or more
records from the PF itself.
Columns . . . 1 71
Edit
KSENTHILS/EXAMPLE
SEU==> SEJOIN
FMT PF
*************** Beginning of data ********************
0001.00
R EMP
0002.00
EMPID
5P 0
0003.00
EMPNAME
20A
0004.00
MGRID
5P 0
0005.00
K EMPID
****************** End of data ***************************
EMPID EMPNAME
MGRID
000001 10,001 SEBI JOSEPH C.
50,001
000002 10,002 PURUSHOTTAM
50,002
000003 10,003 SAMEER DIGHE
50,003
000004 10,004 SHARATA
50,004
000005 10,005 PAUL
50,005
000006 50,001 SHIVARAM
90,001
000007 50,002 GAURAV
90,002
000008 50,003 KING
90,003
000009 50,004 SAM
90,004
000010 50,005 ANIL
90,005
****** ******** End of report ********
Columns . . . 1 71
Edit
KSENTHILS/EXAMPLE
SEU==> SELJOIN
FMT LF
*************** Beginning of data **************************
0001.00
R EMP
JFILE (SEJOIN SEJOIN)
0002.00
J
JOIN (1 2)
0003.00
JFLD (MGRID EMPID)
0004.00
EMPID
JREF (1)
0005.00
EMPNAME
JREF (1)
0006.00
MANAGER
RENAME (EMPNAME) JREF (2)
0007.00
COLHDG ('MANAGER')
****************** End of data *****************************
EMPID EMPNAME
000001 10,001 SEBI JOSEPH C.

MANAGER
SHIVARAM

- 43 -

Tips n Facts
000002
000003
000004
000005
******

10,002 PURUSHOTTAM
GAURAV
10,003 SAMEER DIGHE
KING
10,004 SHARATA
SAM
10,005 PAUL
ANIL
******** End of report ********

Columns . . . 1 71
Edit
KSENTHILS/EXAMPLE
SEU==> SELJOIN1
FMT LF
*************** Beginning of data************************
0001.00
R EMP
JFILE (SEJOIN SEJOIN)
0002.00
J
JOIN (1 2)
0003.00
JFLD (MGRID EMPID)
0004.00
EMPID
JREF (1)
0005.00
EMPNAME
RENAME (EMPNAME)
0006.00
JREF (1)
0007.00
MGRID
JREF (2)
****************** End of data *************************
EMPID EMPNAME
MGRID
000001 10,001 SEBI JOSEPH C.
90,001
000002 10,002 PURUSHOTTAM
90,002
000003 10,003 SAMEER DIGHE
90,003
000004 10,004 SHARATA
90,004
000005 10,005 PAUL
90,005
****** ******** End of report ********
Columns . . . 1 71
Edit
KSENTHILS/EXAMPLE
SEU==> SELJOIN1
FMT LF
*************** Beginning of data************************
0001.00
R EMP
JFILE (SEJOIN SEJOIN)
0002.00
J
JOIN (1 2)
0003.00
JFLD (MGRID EMPID)
0004.00
EMPID
JREF (1)
0005.00
MANAGER
RENAME (EMPNAME)
0006.00
JREF (2) COLHDG ('MANAGER')
0007.00
MGRID
JREF (2)
****************** End of data ****************************
EMPID MANAGER
MGRID
000001 10,001 SHIVARAM
90,001
000002 10,002 GAURAV
90,002
000003 10,003 KING
90,003
000004 10,004 SAM
90,004
000005 10,005 ANIL
90,005
****** ******** End of report ********
16. Explain normalization?
It is the process of segregating and decomposing information held within a system into logically
grouped, related. Uniquely identifiable entities
17. How to create user define command?
By using the CRTCMD command process the command definition statements to create the
command definition object. The CRTCMD command may be run interactively or in a batch job.
Steps for creating CRTCMD commands
1.Enter the command definition statements into the source file
Command type CMD
SKANDASAMO/CLP
CMD1
*************** Beginning of data ****************************

- 44 -

Tips n Facts
0001.00 CMD
****************** End of data *******************************
2. Enter source program in any language
SKANDASAMO/CLP
DLIB
TYPE

:CLP

*************** Beginning of data ******************************


0001.00 PGM
0002.00 DSPLIBL
0003.00 ENDPGM
****************** End of data *********************************

3. Create the command by using CRTCMD take f4


Command . . . . . . . . . . . . > KS
Library . . . . . . . . . . . >

Program to process command . . . > DLIB


Library . . . . . . . . . . . >

Name

SKANDASAMO Name, *LIBL, *CURLIB

Source member . . . . . . . . . > CMD1


Threadsafe . . . . . . . . . . .

*NO

Multithreaded job action . . . .


Text 'description' . . . . . . .

Name, *REXX

SKANDASAMO Name, *LIBL, *CURLIB

Source file . . . . . . . . . . > CLP


Library . . . . . . . . . . . >

Name

SKANDASAMO Name, *CURLIB

Name, *CMD
*YES, *NO, *COND

*SYSVAL

*SYSVAL, *RUN, *MSG, *NORUN

*SRCMBRTXT

18. How do copy a record in existing object to another object?


By using CPYF command if you want to copy a data one position to another position. We Can give
the records copying position starting and ending of the records. We want particular records means. We can
give the command in sq position.
CPYF take F4
File name (source file) : PF01
Lib-name

:SKANDASAMO

New file name

:PF02

Lib-name

:SKANDASAMO
:*FIRST

Replace

:*ADD
:*NO
:*CHAR

Start position

:1000

End position

:2000

Sql command

:
FILED EMPNO
CONDITION *GT
VALUE 40

Record format mapping :*MAP(add field)

- 45 -

Tips n Facts
+DROP (delete field)
19. Explain the command ADDPFCST?
ADDPFCST is a command that is used to define the Constraint on your physical file.
You can use constraint relationships to define dependencies between files.

The relationships that you

define are enforced by the system when changes occur to information in the files.

When you define

constraint relationships you control the referential integrity of the data being processed. All
constraints are defined at the file level.
The constraint has several types. These are REFCST, UNQCST and PRIKEY. By the by, this command is
helps to define Update rules and Delete rules.
To define or establish a referential constraint, the parent file and the dependent file must exist (RSKFIN
and RSKTRN00). However, if the parent or dependent file has no members, the constraint only is defined
(not established).
When a referential constraint is established, either an access path is created or an existing
access path with matching attributes is shared. A maximum of 300 constraint relationships can be
established for a file. However, only one primary key constraint
can be established for a file.
You can remove a constraint by using the Remove Physical File Constraint (RMVPFCST) command. You
can view all constraints for a dependent file by using the Display File Description (DSPFD)
1. You cannot add constraint relationships to system files or to program described files.
2. You cannot add a constraint relationship to a file that your user job has open.
3. Referential constraints cannot span auxiliary storage pools (ASPs).
4. Constraints cannot be added to a file in the temporary library QTEMP.
5. If a check or referential constraint is added with this command and the established referential or check
constraint has records that are in check pending, the constraint is
automatically changed to the disabled state.
6. In multithreaded jobs, this command is not threadsafe for distributed files and fails for distributed files
that use relational databases of type *SNA.
Error messages for ADDPFCST
*ESCAPE Messages
CPF32B0

Constraint cannot be added to file &1.

CPF32B7

&3 constraint(s) added to file &1 but constraint(s) in

error.
*REFCST
A referential constraint is being added.
1. Referential constraints cannot span multiple ASPs (auxiliary storage pools).
2. Referential constraints cannot be added while either the parent or the dependent file is open.

- 46 -

Tips n Facts
3. Duplicate and multiple referential constraints can be added between the same dependent and parent
files if the constraint name is unique.
20.How will be establishing REFERENTIAL INTEGTITY in as/400 system?

By using ADDPFCST command establish in as/400 system.

Referential integrity concepts

Referential constraint

Parent and dependent files

Unique key and primary keys

Parent and foreign keys

Delete rule
Propagate delete from parent file to dependent file
Restrict delete on parent file

Update rule
Restrict inconsistent updates

Insert operations on dependent file are checked

Referential constraint

A referential constraint is a relation between two files, the parent file and the
dependent file.

This relationship establishes that every record in the dependent file has to have a
matching record in the parent file.

The key value of any record in the dependent file must match a key value in the
parent file.

We call parent key the key of the parent file and foreign key the key in the
dependent file.

The parent key has to be unique and cannot contain null values.

The foreign key value has to match one (any only one) value of the parent key.
Otherwise the foreign key can contain a null value.

A record in the parent file may be related to multiple records in the dependent files;
each record in the dependent file has to have just one parent or have a null
foreign key.

Primary key we means a unique and ascending key, which is the primary, access
path for a PF and cannot contain null values.

Primary access path for a database file on the AS/400 in the access path used to
access the file by using OPNDBF command.

Delete rule
We can delete a record from parent file or dependent file first check for delete rule.

CASCADE: If we want to delete a record from the parent file and its parent key is
matching records in a dependent file, the DBMS will delete all the matching records
of the dependent file.

- 47 -

Tips n Facts

SETNULL: If we delete a record from the parent file and parent key is matching
some records in a dependent file, the DBMS will set to null the matching keys in the
dependent file.

SETDEFAULT: This is like previous case, but matching occurrences in the foreign key
are set to their default values. The default value for the foreign key has to match a
record in the parent file.

RESTRICT: The DBMS will prevent any attempt to delete records in the parent file if
its key is matching some records in the dependent file.

NO ACTION: This has the same meaning as restrict, but different timing. When we
use *NOACTION and an invalid delete operation is about to take place, DB2 /400
will delay any error message until the end of the operation itself, allowing for
instance the activation of a before trigger attached to the PF.

If *restrict is in use, the exception message is sent immediately.

Deleting records in a dependent file is always permitted.

Update rule

RESTRICT: We cannot change the value in a parent key if the old values are
matching some records in the dependent file.

The remaining portion of the record can always be updated.


We cannot update a foreign key in a dependent file if the new value for the
key is not null and does not match any value of the parent key.

NO ACTION: This is same as * restrict but with different timing considerations.


Refer above; where we describe no action delete operations.

Inserts

There is no insert rule to be chosen, but referential integrity prevents any insert in
the dependent file if the new record has no match in the parent file and its foreign
key is not null.

21. How to create a trigger in AS/400?


The trigger is an event to be performing before or after any change to a database. When a trigger
is added to a physical file, three attributes need to be defined.

The first is the event that will cause the trigger to fire. A trigger event can be an
insert, an update, or a delete a record from the file.

The second attribute to define is when to fire the trigger-before or after the event.

The third attribute to define is the identification of the trigger program to by run.

We can infer that up to six triggers can be defined for each PF.

For each update, insert, and delete

Two triggers can be defined

One that runs before the event

One that runs after the event

These trigger are added using the ADDPFTRG

Can be removed with the remove PF trigger command (RMVPFTRG)

The command ADDPFTRG takes F4

- 48 -

Tips n Facts
PF

PF001

LIB

SKANDASAMO

TRIGGER TIME
TRIGGER EVEVT

*AFTER

*BEFORE *AFTER

*UPDATE

PROGRAM

*UPDATE *INSERT *DELETE


PGM001

LIB

NAME

SKANDASAMO

REPLACE TRIGGER

*NO

*NO *YES

ALLOW REPEATED

*NO

*NO

*YES

22.What is the data area?


A data area is an object used to store data for access by any job running on the system. It is
permanent storage. A data area can be used whenever you need to store information of limited size,
independent of the existence of the programs or files.
Data Areas are chunks of memory to hold a few control values. A typical use is to keep track of the last
invoice number for a system.
To create a data area, use the command CRTDTAARA (Create Data Area). For example, to create a 100
character data area named LASTINV#:
CRTDTAARA DTAARA(MYLIB/LASTINV#) TYPE(*CHAR) LEN(100)
Now, load the first 10 positions with the value "AA12345678" with the CHGDTAARA (Change Data Area)
command
CHGDTAARA DTAARA(QTEMP/LASTINV# (1 10)) VALUE('AA12345678')
Look at the value of the data area with DSPDTAARA (Display Data Area):
DSPDTAARA MYLIB/LASTINV#
A CL program can retrieve the value with RTVDTAARA. An RPG program uses the "IN" operation to retrieve
the value and the "OUT" operation to change it.
There is a special Data Area known as the LDA (Local Data Area). It is 1024 characters and is associated
with a job. So, any display session has an LDA associated with it. Not only that, when a job is submitted to
run in batch, the LDA gets sent with the job so the batch job can read the LDA of the display session that
submitted it.
View and change your LDA by using *LDA instead of a data area name:
DSPDTAARA *LDA
CHGDTAARA DTAARA(*LDA (1 10)) VALUE('AA12345678')
Using the LDA is considered by many to be an obsolete style. Older programs use the LDA to store and
pass parameters.

Typical uses of data areas are:

To provide an area to pass information within job.

To provide a field that is easily and frequently changed to control


references within a job such as supplying the next check number.

To provide a constant field for use in several jobs, such as tax rate

To provide limited access to a large process that requires the data area.

A data area can be locked to a single user, thus preventing other users
from processing at the same time.

- 49 -

Tips n Facts

Type of data area created by the system

Local data area

Group data area

Program initialization parameter (PIP) data area


SKANDASAMO/RPGILE
DAREA

*************** Beginning of data ******************************


0001.00 DS

10A

0002.00 DG

10A

0003.00 C

*DTAARA

0004.00 C

*LOCK

0006.00 C
0007.00 C

DEFINE
IN

0005.00 C
S

INZ ('I HATE YOU')


DATA1

EVAL

S=G

OUT

DSPLY

0008.00 C

SETON

LR

****************** End of data ***********************************


OUTPUT
DSPLY I HATE YOU

AUTO NUMBER GENERATION


SKANDASAMS/TEST
TESTEX19
*************** Beginning of data *******************************
0001.00 DA

0002.00 C

*DTAARA

0003.00 C

*LOCK

4S 0
DEFINE
IN

DATA2

0004.00 C

EVAL

A=A+1

0005.00 C

OUT

0006.00 C

DSPLY

0007.00 C

SETON

LR

0008.00 C
0009.00 C
0010.00 C
****************** End of data ***********************************
OUTPUT
DSPLY

DSPLY

23.Define LDA, GDA, and PIP?

LOCAL DATA AREA (LDA)

A local data area is created for each job in the system automatically, when you
submit a job.

Only one LDA can be created by submitting a job.

- 50 -

Tips n Facts

The system create a local data area, which is initially filled with blanks, with a
length of 1024 and type *CHAR.

When you submit a job using SBMJOB command, the value of the submitting jobs
local data area is copied into the submitted jobs local data area.

You can refer to your jobs local data area by specifying *LDA for the DTAARA
keyword on the CHGDTAARA, RTVDTAARA, and DSPDTAARA commands or *LDA for
the sub string built-in function (%SST)

The following is true of a local data area:

The local data area cannot be referred to from any other job.

You cannot create, delete or allocate a local data area.

We can to change the contents of LDA by the by using CHGDTAARA


command.

No library is associated with the local data area.

ACCESSING LDA:

CHGVAR VAR (%SST (*LDA 3 5)) VALUE(123)


OR

CHGDTAARA DTAARA (*LDA (3 5)) VALUE(123)

CHGVAR VAR (&ROLNO) VALUE (%SST (*LDA

3 5))

OR

RTVDTAARA DTAARA (*LDA (3

5)) RTNVAR (&ROLNO)

GROUP DATA AREA (GDA)

The system creates a group data area when an interactive job becomes a group job.

Only one group data area can exist for a group.

The group data area is deleted when the last job in the group is ended, or when the
job is no longer part of the group job.

A group data area, which is initially filled with blanks, has a length of 512 and type
*CHAR.

The following is true for a group data area

You cannot use the group data area as a substitute for a character variable
on the sub string built-in function.

A group data area cannot be referred by jobs outside the group.

You cannot create, delete, or allocate a group data area

No library is associated with a group data area.

Example
CHGDTAARA DTAARA (*GDA) VALUE (DECEMBER 1996)
RTVDTAARA DTAARA (*GDA) RTNVAR (&GRPARA)

PROGRAM INITIALIZATION PARAMETER (PIP) DATA AREA

A PIP data area is created for each pre-started job when the job is started.

The object sub-type of the PDA is different then a regular data area.

The PIP can only be referred to by the special value name *PDA.

- 51 -

Tips n Facts

The size of the PDA is 2000 bytes but the number of parameter contained in it is not
restricted.

24. What are various steps accessing data area in CL?

The first create a general data area use the command (CRTDTAARA)

To retrieve values from data area use (RTVDTAARA)

To change this value, use (CHGDTAARA)

To display the current value, use (DSPDTAARA)

To delete a data area use (DLTDTAARA)

25. Various types of message available in CL?


Message is the interface between operating system and the programs or user and program. We
can classify the message into two types namely

Immediate message

Predefined message

Immediate message
Which the program or system user (PROGRAM MESSAGES)create when they are sent
and are not permanently stored in the system?
Control language

SNDUSRMSG

SNDPGMMSG

SNDMSG

SNDBRKMSG

Display files

ERRMSG

SFLMSG

INQUIRY and INFORMATIONAL message:

Using SNDUSRMSG command to send type of message


Predefined message
Which are created before they are used. These messages are placed in a message
file (queue) when they are created, and retrieved from the file when they are used.

Control language

- 52 -

Tips n Facts

SNDUSRMSG

SNDPGMMSG

RTVMSG

Display files

ERRMSGID

SFLMSGID

MSGCON

MSGID

COMPLETION and DIAGNOSTIC message

Using SNDPGMMSG command these of message can be sent to any


message queue.

DIAGNOSTIC message tell the calling program about errors detected by the
program. Completion message tell the result of work done by the program.

STATUS messages

Using SNDPGMMSG command status message can be sent to its callers


program message queue or to the external message queue for the job. These message
tell the receiving program the status of the work performed by the sending program.

ESCAPE message

Using SNDPGMMSG command escape message from a CL program can be sent


to its calling program. An escape message tells the calling program ended abnormally
and why.

NOTTFY message

Notify message from a CL program can be sent to the message queue of calling
program or to the external message queue. A notify message tells the calling program
about a condition under which processing can continue.
Predefined message are stored in message file

To create a message file

CRTMSGF MSGF (MFILE) SIZE () AUT()


Create and maintain messages

TEXT ()

ADDMSGD
CHGMSGD OR WRKMSGD
DSPMSGD
RMVMSGD
Message file QCPFMSG in library QSYS contain the system message
26. What will MONMSG command do?
The monitor message (MONMSG) command monitors the message send to the program message
queue for the conditions specified in the command. If condition exists, the CL command specified on the
MONMSG command is run.
Types of monitor message

Escape Message

Status or Notify Message

Escape Message

Escape message are send to tell your program of am error condition that forced the
sender to end. By monitoring for escape message, you can take corrective actions or clean up
and end your program.
Status or Notify Message

- 53 -

Tips n Facts
Status and notify message are send to tell your program of an abnormal condition that is
not serious enough for sender to end. By monitoring for status or notify message, your
program can detect this condition and not allow the function to continue.

Two levels of MONMSG command

Program level

Specific command level

Program level

The MONMSG is specified immediately following the last declare command in your CL
program. You can use as many as 100 program-level MONMSG commands in a program.
Specific command level
Here the MONMSG command immediately follows a CL command. You can use as many
as 100 commands-level MONMSG commands for a single command.

Monitor message command syntax


MONMSG
MSGID ()
MSGID-Required

Ex: MSGID (MCH1211)


CMPDTA (Optional)

Ex: MONMSG MSGID (MCH1211)


EXEC - -(Optional)

CMPDTA ()

EXEC ()

CMPDTA (LIB)

CL command
27 What are the disadvantages of using CL over RPG?
We can able to read only records but we cannot able to write or update or delete records.

We can have only one file to be used in a CL program

We cannot able to use printer files in CL

We cannot able to use subfile in a CL program

28 How you can read and write single command in CL?


By using SNDRCVF command.
Example
Type: CLP
SKANDASAMO/CLP
ADD
*************** Beginning of data ********************************
0000.01 /*ADDING TWO NUMBERS */
0001.00

PGM

0002.00

DCLF

0003.00

SNDRCVF

RCDFMT(SECLP)

0004.00

CHGVAR

VAR(&RES) VALUE(&NUM1 + &NUM2)

0005.00

SNDRCVF

RCDFMT(SECLP)

0006.00

ENDPGM

FILE(SKANDASAMO/CLPSCR) RCDFMT(SECLP)

****************** End of data **********************************


OUTPUT
FIRST NUMBER: 12
SECOND NUMBER: 12
----------

- 54 -

Tips n Facts
RESULT=

0000024

---------29 How to retrieve a date in CL?


By using RTVSYSVAL command we can get the system dates. For getting date QDATE.
The various format of date are
*DMY, *MDY, *YMD, *YYMD, *JOL, *JOB
30 How to send the message to the screen SNDPGMMSG?
BY passing unique message ID message data and message file.
SNDPGMMSG syntax
SNDPGM MSG
MSGID (MSG0001)
MSGF (MSGSUB)
31 What is the open query file?
It is a dynamic record selection. The OPNQRYF command acts as a filter between the processing
program and the database records. The database file can be a PF or LF. It will create open data pathway
to access (retrieve) data file.
If you want to specify any SQL operation within a CL we have to use OPNQRYF
k
Functions supplied by OPNQRYF are:

Dynamic record selection.

Dynamic keyed sequence access path

Dynamic keyed sequence access path over a join

Dynamic join

Handling missing records in secondary join files

Unique-key processing

Mapped field definitions

Group processing

Final total-only processing

Improving performance

Open query identifier (ID)

32. What is the different between OPNQRYF and SQLRPG?


OPNQRYF
SQLRPG
OPNQRYF will come along with OS/400 system
and no need to have any additional package
needed to execute it
OPNQRYF is faster as compared to SQLRPG

We need to have SQLRPG installed in as/400


system which involves additional cost to the
programmers
It is slower

OPNQRYF is nothing but a dynamic logical files


will be created and the records

SQLRPG is imbedding SQL statements directly


within SQL statement

33. What are the various steps in creating OPNQRYF?


Totally five steps involve in creating OPNQRYF
OVRDBF

FILE (file PF) TOFILE (LIB/ PF) SHARE (*Yes)

If a PF is having 100 records and if we want to override the PF so that it


continues only the specific number of records we are using OVRDBF

OPNQRYF

FILE (LIB / PF) QRYSLT (EMPNO *EQ *BCAT &A)

If you want to perform any SQL operation we have to declare in OPNQRYF


command only.

- 55 -

Tips n Facts

In case of OPNQRYF we can perform expression only based on characters


but not on numeric.

*BCAT
If you want to perform any charter expression are using *BCAT
expression which will provide a blanks in between the 2 variables.

%WLDCRD

It is similar to %LIKE in SQL

QRYSLT (EMPNAME *EQ %WLDCRD (S* ))


It will fetch all the records whose empname starts from S.

*CT

It will fetch all the records, which conditions the particular charter.

QRYSLT (EMPNAME *CT S )

%RANGE

It will fetch the records within the specific range

QRYSLT (EMPNO *Eq %RANGE (100 110))

CALL PGM (LIB/NAME) PARM ()

DLTOVR

As we see early the main file logically overridden and after performing the
necessary operation, we have to delete the logical file so that the main file
contains the actual records for this DLTOVR will be used.

DLTOVR FILE (OPNPF)

CLOF

We have to close the file, which has been opened

CLOF

OPNID (OPNPF)

You will copy overridden file records using CPYFRMQRYF


CPYFRMQRYF

Since OVRDBF is logical we cannot able to list the variables, which satisfy the
query condition. To see the records being selected we have to copy from the
source file to a temporary file for this CPYFRMQRYF will be used

CPYFRMQRYF

FROMOPNID (OPNPF) TOFILE (LIB/NAME) MBR (*REPLACE)

CRTFILE (*YES) FMTOPT (*NOCHK)

RUNQRY

We have copied the contents satisfy the query into a temporary file using
CPYFRMQRYF. If we run the destination file we got the actual records, which
satisfy the query.

RUNQRY QRYFILE (LIN/NAME)

Example:
Database PF
SKANDASAMO/CLP
OPENF
*************** Beginning of data ****************************

- 56 -

Tips n Facts
0000.01 C

UNIQUE

0001.00 C

R OPNQFILE

0002.00 C

OEMPNO

0003.00 C

OEMPNAME

20A

0004.00 C

OADDRESS

20A

0005.00 C
0006.00 C

ODOB

5S 0

8S 0

K OEMPNO

****************** End of data ********************************


Data file
Display Report
OEMPNO

OEMPNAME

OADDRESS

ODOB

000001 1,001

SENTHIL

SALEM1

1,232,002

000002 1,002

KUMAR

TRICHY

12,123,000

000003 1,003

SHYAM

SALEM

12,345,000

000004 1,004

RAMESH

000005 1,005

BALU

000006 1,007

KUMAR

SALEM

1,010,100

SALEM

222

JJ

32,938

****** ******** End of report ********


CL program
SKANDASAMO/CLP
OPNQFILE5
*************** Beginning of data *********************************
0001.00 PGM
0002.00

DCL

VAR(&A) TYPE(*CHAR) LEN(5)

0003.00

DCLF

FILE(SKANDASAMO/OPNQFILE3) RCDFMT(OPNF3)

0004.00

SNDRCVF

RCDFMT(OPNF3)

0005.00

CHGVAR

VAR(&A) VALUE(&OEMPNO)

0006.00

OVRDBF

FILE(OPENF) SHARE(*YES)

0006.01

OPNQRYF

FILE((SKANDASAMO/OPENF))

QRYSLT('OEMPNO *EQ'

+
0006.02
0006.03

*BCAT &A)
CPYFRMQRYF FROMOPNID(OPENF) TOFILE(SKANDASAMO/TEMP) +

0006.04

MBROPT(*REPLACE) CRTFILE(*YES)

0009.00

DLTOVR

0010.00

CLOF

0010.01

RUNQRY

0011.00

ENDPGM

FILE(OPENF)
OPNID(OPENF)
QRYFILE((SKANDASAMO/TEMP))

****************** End of data*********************************


OUTPUT
EMPLOYEE NUMBER: 1001

- 57 -

Tips n Facts
OEMPNO
000001 1,001

OEMPNAME
SENTHIL

OADDRESS

ODOB

SALEM1

1,232,002

****** ******** End of report ********


34. How the records are accessed for using OPNQRYF?
By creating open data pathway to access (retrieve) data file.
35. What is the journal?
Any changes in PF will be recorded. A journal is an object of type *JRN which detects and
records that cause a PF to change.
The information recorded by the journal is stored in an object *JRNRCV called journal
receiver.
36. What are the various steps creating journal?
The steps to start journaling

Create a journal receiver

- CRTJRNRCV

Create a journal

- CRTJRN

Start journaling of a PF

- STRJRNPF

Backup the PF

- SAVOBJ

The steps to end journaling

End journaling a PF

-ENDJRNPF

Delete a journal

Delete the last journal receiver -DLTJRNRCV

Save journal receivers

-DLTJRN

-SAVOBJ

The commands used for house keeping purposes

Change journal

Save object

Delete a journal receiver

-CHGJRN
-SAVOBJ
-DLTJRNRCV

The commands used in case of a failure are

Display journal entries

-DSPJRN

Apply journal changes

Remove journal changes

-RMVJRNCHG

Restore a saved object

-RSTOBJ

-APYJRNCHG

37. How you can list all the LF of a PF?


By using DSPDBR command it is to list all the files, which are related to a PF. It displays all the LF
that is referring the PF and also lists the child table if it is having a relation through ADDPFCST.
38. What is use of DSPFFD and DSPFD?
DSPFD (display file description)

It is used to display the details about the file when it is created.

DSPFFD (display file field description)

It is used for listing details about individual fields.

39. What is the data queue?


It is a temporary storage. We can able to store and retrieve the data, but once data
is retrieved the data is lost.

- 58 -

Tips n Facts

First create the data queue by using CRTDTAARA command

Sending a message to a data queue (QSNDDTAQ, QRCVDTAQ, And CLRDTAQ)

Data query is nothing but a queue in which are program can send a data and other
program or the same program can receive the program. QSNDDTAQ is stored in QSYS.
40. Explain QSNDDTAQ and QRCVDTAQ?
QSNDDTAQ

By using this command sent data same / another program.

QSNDDTAQ

PARM

(QUEUE NAME LIB &LEN &DAT)

QRCVDTAQ

By using this command receive data same /another program

QRCVDTAQ

PARM

(QUEUE NAME LIB &LEN &DAT &WAIT)

41. What are the mandatory parameters for declaring a Data queue?

QUEUE NAME

LIB NAME

LENGTH

DATA

WAIT

42. What will RUNSQLSTM will do?

If we want to execute set of SQL statement then we can write all the SQL statement to be
including with the source.

Type as SQL

Only insert, update and delete and no select is allowed.

Then use STRSQLSTM to execute the program

RUNSQLSTM

SRCFILE (LIB/TEST) SRCMBR (SQL01) COMMIT (*NONE)

43. What is a field reference file?


This is PF, which does not have any data and contains only the field descriptions and these fields
are referred in other PF by using REF and REFFLD

44. What is the difference between OPM, EPM and RPGLE?


OPM
Original program model is the

EPM
Extended program model will

RPGLE
It supports

old RPG/400 system, which will

support C, PASCAL, FORTRAN

support

not allow a program type to call

and

combine

another program type. Like CL,

concepts.

another

programming

in

any

another type

- 59 -

mixed
which

program
you

program

can
with

of program. it

Tips n Facts
RPG, COBOL, PL/I, BASIC only

supports modularity, copy book,

supported.
Version is V1R2

better call performance.


Version is V2R3

45. Explain WRKOBJPDM and DSPOBJD?

WRKOBJPDM
If we want to list all the source PF or files of particular type the WRKOBJPDM with file
type as PF-SRC for source PF IOR *file for listing all the files extra can be given.

DSPOBJD
If we know library name and object name and we want to know the source PF where it is
residing then DSPOBJD with option as *services instead of basic will give the source PF
name.

46. How to create RPG, RPGLE, CL, CLLE, PF, LF, PRN, and display file?
RPG

-by using CRTRPGPGM command

RPGLE

-by using CRTBNDRPG Command (or) 14

RPGLE
CL

-by using CRTRPGMOD (or) 15 /CRTPGM command

-by using CRTCLPGM command

CLLE

-by using CRTBNDCL

CLLE

-by using CRTCLMOD/CRTPGM command

PF

-by using CRTPF command

LF -by using CRTLF command


PRN

- by using CRTPRTF command

DSPF

-by using CRTDSPF command

47. It is possible to insert record to JOIN LF?


NO, insertion, updating or deleting of records is not possible in JOIN LF.
48. What are the advantages of using AS/400 system?
AS/400 is designed and build as a total system. This means that facilities such as relational
database and networking capability (and much more) are fully integrated into the operating system and
machine. The user communication with all these functions through a single control language

Layered machine architecture

Object orientation

Single-level storage

Hierarchy of microprocessors

Security levels

Layered machine architecture


This insulates users from hardware characteristics. It enables them to move to
new hardware technology at any time, without disrupting their application
programs. We can able to change any layer without affecting the other layer. If
any problem occurs in OS, then we can work with application program
independently and this is the major advantage of AS/400 system.

Object orientation

- 60 -

Tips n Facts
Every that can be stored or retrieved on the system is known as an objects.
Objects exist to make users independent of the internal structure of the machine.

Single- level storage


It provides contiguous memory between main storage and disk storage. It
provides authority to add any disk space so that use. Can access it without any problem.
There is no need for the user to think where to store the application program.

Hierarchy of microprocessors
Various types of microprocessors are used in AS/400. Each and every
microprocessor is allocated for specific purpose. If one chip is for input operation and
other for output then we can do both input and output operation since both the
microprocessor can perform independently.

Security levels
It will list the various security provided by the system.

No security

Password security

Resource security

OS security

Certifiable security

49. What are the various types of Security in AS/400?


AS/400 is designed for business that requires levels of security ranging from nothing at
all to full government certifiable security. By setting a system value, we can configure five
increasing level of security.

No security

Password security

Resource security

OS security

Certifiable security

When as AS/400 is configured, three system values dealing with security need to be specified.
These values are QAUDJRL, QMAXSIGN & QSECURITY.
QSECURITY:
This system value determines the level of security enforcement. S/38 and the original
AS/400 only had three of system security. At VIR3 of OS/400 the fourth level of security was
added, and the fifth level of security was added at V2R3. The valid values for QSECURITY are
10,20,30,40,50.
QMAXSIGN:
This system value determines the maximum number of signon attempts allowed. If the
number of unsuccessful attempts to signon to the system exceeds this number, the terminal or
device that attempted the signon is varied off.
QAUDJRL:

- 61 -

Tips n Facts
AS/400 supports an optional security auditing function. If this function is specified,
certain security events are journal. The specific events that are logged in the security audit
journal are determined by the value specified in the QAUDJRL system value and the level of
system security specified.
Level 10: No security
System is shipped with minimum-security level and doesnt require any
password to sign on. If user profile doesnt exists with the same name as the
Userid the system creates the user profile with that name.
Level 20:Password security
Minimum security is active and password is required to sign on. The user profile
must already exist for the user before we can sign on the system
Level 30:Resource security
Password security is active and user must specify given authority to resources.
This level is recommended because the system doesnt give the user authority to access the
entire object on the system after the user sign on.
Level 40:Operating system security
Password security, resource security and OS integrity are active. User must be
especially given authority to resources this level providing more security than level 30.

All attempts to access object using interfaces that are not supported fail.

Programs that contains restricted instructions will not compile

Users submitting jobs using the job description containing the user profile name,
must have *USE authority to user profile.

Level 50: C2 level security


All the level 40 security attributes are included at level 50,and in addition some
of the interfaces are modified to meet the C2 standards.

50. Explain user profile and group profile?

User profiles are used to identify users to the systems and verify authorities on the
system (DSPUSRPRF, CHGUSRPRF, EDTOBJAUT)

User profiles tell the system who can sign on and what functions the user can perform
on the system on the system resources after signing on.

The security officer or security administrator can create it.

The user profile defines the following capabilities for a particular user

User class

Object owned and authorized

Authorization of objects

- 62 -

Tips n Facts

Privileged instructions

Password

Current library

Initial program and menu

Delimited-capability user

Limit device session

Maximum storage allowed

Priority limit

Special environment

User class
When identifying a user on the system you can specify the user class in the user
profile. AS/400 has five user classes that determine the level of systems access a user is
permitted. The five user classes, starting the highest level of access, are

Security officer (*SECOFR)

Security administrator (*SECADM)

Programmer (*PGMR)

System operator (*SYSOPR)


User (*USER)

Authorization of objects
Object authority, or the right to user to use or control an object comes in two categories.

Object rights

Data rights

Object rights
Object rights are concerned with the object itself.
Object rights assign a user the following authority

Operational rights (*OPER)

Object management rights (*OBJMGT)

Object existence rights (*OBJEXT)

Operational right (*OPER)


The authority to use an object, looks at its description, and restores it. A user
must have operational rights to a program to execute it.
Object management rights (*OBJMGT)
The authority to grant and revoke and user rights move and rename object,
and members to database file.
Object existence rights (*OBJEXT)
The authority to delete, free storage, save restore or transfer ownership of an
object.

- 63 -

Tips n Facts

Data rights
Data rights apply to the data contained within the object.
Types of data rights

Read (*READ)
The authority to retrieve the contents of an object entry.

Add (*ADD)
The authority to add entries to an object. For example adding records to a

database file requires ADD rights for the library.

Update (*UPD)
The authority to change the entries in an object requires UPD rights for the

file.

Delete (*DLT)
The authority to remove object in an object. For example deleting a program

from a library requires DLT rights for the library. Deleting records for a database the
requires DLT rights the database file.
51. What are the various ways creating access path?
Access path means the records are to be retrieved from a file. The records can be retrieved from
a PF or a LF either ARRIVAL SEQUENCE or by KEYED SEQUENCE. For LF you can also select records using
select or omit keywords
Arrival sequence access path

Sequentially, where each record is taken from the next sequential physical position
in the file.

Directly by relative records number, where the record number is identified by its
position from the start of the file.

Keyed sequence access path


It is based on the contents of the key fields as defined in DDS. This type of access path
is updated in the contents of a key field is changed.
There are three ways of bounding the access path

Immediate

Rebuild

Delayed

Immediate
Access path is always maintained for every opening in a file.

Rebuild
Access path is maintained when the file is open and various updates are recorded and

the access path is rebuild every time when the access path is closed.

Delayed

- 64 -

Tips n Facts
Access path is maintained when the file is opened and updates recorded. When the file is
closed all the updates to the records are closed together but it is not rebuild. When the recorded
update percentage exceeds 25% then rebuild of records take place.
52.How many record formats PF, LF, DSPF and SFL?
PF- 1 , LF- 32, DSPF-1024

SFL-512

53.What is the command to create menu?


CRTMNU Create Menu
54. What is the difference between CALL and Transfer Control (TFRCTL)?
CALL
1.Call will transfer the control according with the

TFRCTL
Transfer Control (TFRCTL) will remove the CALL

CALL STACK

STACK and transfer the control to the calling

2. The CALL is used to different types of programs.

program.
TFRCTL is only used in CL programs.

Ex: RPGILE/400,CL/400,C/400,COBOL/400.

55. Explain ADDDUR, SUBDUR, EXTRCT and TEST?


ADDDUR:
It is a powerful opcode, which is used to add any date related function to a
particular date, time or timestamp.
Example:
SKANDASAMO/DATE
ADDDUR
*************** Beginning of data ********************************
0000.01 d*date function using the adddur
0001.00 DTIMESTE

0001.01 DTIME5

0002.00 DDATE1

0002.01 DDATE2

0002.02 DDATE3

0002.03 DDATE4

0003.00 DTIME1

0003.01 DTIME2

0003.02 DTIME3

0003.03 DTIME4

0004.00 C

MOVEL

*DATE

DATE1

0005.00 C

DATE1

ADDDUR

02:*Y

DATE2

0006.00 C

DATE1

ADDDUR

05:*M

DATE3

0007.00 C

DATE1

ADDDUR

01:*D

DATE4

0007.01 C

TIME

TIME1

0007.02 C

TIME

TIMESTE

0008.00 C

TIME1

ADDDUR

10:*H

0009.00 C*

TIME1

ADDDUR

10:*ML

0010.00 C

TIME1

ADDDUR

10:*S

- 65 -

TIME2
TIME3
TIME4

Tips n Facts
0011.00 C

TIMESTE

0012.00 C

DATE2

DSPLY

0013.00 C

DATE3

DSPLY

0014.00 C

DATE4

DSPLY

0014.01 C

TIME1

DSPLY

0014.02 C

TIME2

DSPLY

0014.03 C

TIME3

DSPLY

0014.04 C

TIME4

DSPLY

0014.05 C

TIME5

0015.00 C

ADDDUR

10:*MS

TIME5

DSPLY
SETON

LR

****************** End of data *********************************


OUTPUT
DSPLY 2004-06-27
DSPLY 2002-11-27
DSPLY 2002-06-28
DSPLY 12.18.36
DSPLY 22.18.36
DSPLY 00.00.00
DSPLY 12.18.46
DSPLY 2002-06-27-12.18.36.953010
SUBDUR:
It is used to find the difference between two date (or) time (or) time stamp
Example
SKANDASAMO/DATE
SUBDUR
*************** Beginning of data ********************************
0000.01 d*date function using the SUBDUR
0001.00 DTIMESTE

0001.01 DTIME5

0002.00 DDATE1

0002.01 DDATE2

0002.02 DDATE3

0002.03 DDATE4

0003.00 DTIME2

0003.01 DTIME1

0003.02 DTIME3

0003.03 DTIME4

INZ (D'1977-06-20')

INZ (T'12. 50.10)

0005.00 C

DATE1

SUBDUR

02:*D

DATE2

0006.00 C

DATE1

SUBDUR

05:*M

DATE3

0007.00 C

DATE1

SUBDUR

01:*Y

DATE4

0007.01 C

TIME

TIME1

0008.00 C

TIME2

SUBDUR

10:*H

TIME1

0010.00 C

TIME2

SUBDUR

10:*S

TIME4

- 66 -

Tips n Facts
0012.00 C

DATE2

DSPLY

0013.00 C

DATE3

DSPLY

0014.00 C

DATE4

DSPLY

0014.01 C

TIME1

DSPLY

0014.02 C

TIME2

DSPLY

0014.03 C

TIME3

DSPLY

0014.04 C

TIME4

DSPLY

0015.00 C

SETON

LR

****************** End of data ***********************************


OUT PUT
DSPLY 1977-06-18
DSPLY 1977-01-20
DSPLY 1976-06-20
DSPLY 02.50.10
DSPLY 12.50.10
DSPLY 00.00.00
DSPLY 12.50.00
EXTRCT:
It is used to extract year, month, day, hours, minutes, seconds, and microseconds of a
time stamp or date field.
Example:
SKANDASAMO/DATE
EXRCT
*************** Beginning of data ********************************
0000.01 d*FINT THE EXRCT DAY MONTH YEAR
0001.00 DTIMESTE

0002.00 DDATE1

0002.01 DDATE3

0002.02 DDATE2

5P 0

0002.04 DDATE4

5P 0

0002.05 DDATE5

5P 0

0002.06 DDATE6

5P 0

0002.07 DDATE7

5P 0

0002.08 DDATE8

5P 0

0003.00 DTIME0

0003.01 DTIME1

0003.02 DTIME2

5P 0

0003.03 DTIME4

5P 0

0003.04 DTIME5

5P 0

0003.05 DTIME6

5P 0

0003.06 DTIME3

0004.00 C

MOVEL

0004.01 C

TIME

INZ (D'1977-06-20')

INZ (T'12. 50.10)

26P 0
*DATE

DATE3
TIME1

- 67 -

Tips n Facts
0004.02 C

TIME

0005.00 C

EXTRCT

DATE1:*M

0006.00 C

EXTRCT

DATE3:*M

DATE4

0007.00 C

EXTRCT

DATE1:*D

DATE5

0007.01 C

EXTRCT

DATE3:*D

DATE6

0007.02 C

EXTRCT

DATE1:*Y

DATE7

0007.03 C

EXTRCT

DATE3:*Y

DATE8

0007.04 C

EXTRCT

TIME1:*H

TIME2

0007.05 C

EXTRCT

TIME1:*H

TIME4

0007.06 C

EXTRCT

TIME0:*H

TIME5

0007.07 C

EXTRCT

TIME0:*S

TIME6

EXTRCT

TIMESTE:*MS

0011.00 C
0012.00 C

DATE2

DSPLY

0013.00 C

DATE8

DSPLY

0013.01 C

DATE4

DSPLY

0013.02 C

DATE5

DSPLY

0013.03 C

DATE6

DSPLY

0014.00 C

DATE7

DSPLY

0014.01 C

TIME2

DSPLY

0014.02 C

TIME4

DSPLY

0014.03 C

TIME5

DSPLY

0014.04 C

TIME6

DSPLY

0014.05 C

TIME3

0015.00 C

TIMESTE
DATE2

TIME3

DSPLY
SETON

LR

OUTPUT
DSPLY
DSPLY

6
2002

DSPLY

DSPLY

20

DSPLY

27

DSPLY

1977

DSPLY

12

DSPLY

12

DSPLY

12

DSPLY

10

DSPLY

441000

TEST:
Test is the most powerful opcode, which will check a date is a valid, or not .The low level indicator
is set on if the date is not valid or set off if the date is a valid one.
Test will be given with extended factor like test (d), test (t), test (z) for date, time and time
stamp and if test without extended factor default to date (z).

- 68 -

Tips n Facts
Example
SKANDASAMO/DATE
TEST
*************** Beginning of data *********************************
0000.01 C*TEST FOR VALID DATE THE DATE VALID SETOFF OR SETON (NOTVALID)
0001.00 C

MOVEL

0002.00 C

TEST (D)

0003.00 C

*IN30
IF

0003.02 C

'NOTVAILD'

0003.04 C

10
30

DSPLY

0003.01 C
0003.03 C

'13/03/1999 A

*IN30=*ON
DSPLY

ELSE
'VALID'

DSPLY

0003.05 C

ENDIF

0004.00 C

SETON

LR

****************** End of data ***********************************


OUTPUT
DSPLY 1
DSPLY NOTVAILD
56. Explain Multi Dimensional Array?
The multi dimension data structure array will be implemented in occurs class.

The similar elements of same data type and same attributes size repeating many times this
time using OCCUR opcode.

Which can only be used with a multiple occurrence data structure, allow you to specify which
occurrence of data structure is used for subsequent operation within the programs.

57.Explain about RTNCSRLOC?


Type Y (Yes) in the Select parameters prompt to define parameters for the RTNCSRLOC keyword
on the Define Return Cursor Location display.
58.Explain Assume and Overlay?
Assume
Type Y (Yes) to select the ASSUME keyword. It causes the AS/400 system to assume
that this record appears on the display when the file is opened. Use this keyword to receive data
that a previous program has left on the display.
Overlay
Type Y (Yes) to allow the overlaying of fields on this record without erasing the entire
display. Note: If you type anything other than Y or blank, your entry will be ignored. You must
specify the OVERLAY keyword to select the other keywords on this display, with the exception of
PUTOVR.
59.Explain Compile time array, lookup, sorta, xfoot, and Run time array?
Compile time array

The compile time array means the elements of the array will be loaded before the
execution of the programs.

The value will be static.

We must declare in keyword command DIM (), CTDTAT (), and PERRCD ().

- 69 -

Tips n Facts

We are giving the value in after the SETON

LR.

Example

SKANDASAMO/ARRAY
COMILE
*************** Beginning of data ********************************

0000.01

c*compile time array

0001.00

darr1

0002.00

di

2p 0 inz(1)

0003.00

do

0004.00

arr1(i)

dsply

0005.00

add

0006.00

enddo

0007.00

seton

dim(3) ctdata perrcd(1)

3
1

0008.00 **
0009.00 1001
0010.00 20
0011.00 1000
****************** End of data ********************************
OUTPUT
DSPLY 1001
DSPLY 20
DSPLY 1000

Run time array

The run time array means the value will be loaded during the runtime only.

The value will be dynamic.


SKANDASAMO/ARRAY
RUNTIME

*************** Beginning of data *****************************


0000.01 c*runtime array
0001.00 darr1

0002.00 di

2p 0 inz(1)

0002.01 da

3p 0

0002.02 dj

2p 0 inz(1)

0003.00 c

do

10

dim(12)

12

0003.01 c

dsply

0003.02 c*

eval

arr1(i)=a

0003.03 c

add

0003.04 c

arr1(i)
i

enddo

0003.05 c

do

0004.00 c

arr1(j)

dsply

0005.01 c

add

0006.00 c

enddo

0007.00 c

seton

12
1

j
lr

****************** End of data *********************************

- 70 -

Tips n Facts
lookup, sorta, xfoot :
SKANDASAMO/ARRAY
SORTARRAY
*************** Beginning of data *********************************
0000.01 c*lookup,xfoot&sorta examples
0001.00 darr1

4 0 dim(3) ctdata perrcd(1)

0002.00 di

2p 0 inz(1)

0002.01 dj

2p 0 inz(1)

0002.02 dd

4p 0

0003.00 c

do

0004.00 c

arr1(i)

dsply

0005.00 c

add

0006.00 c

enddo

0006.01 c

sorta

arr1

0006.02 c

xfoot

arr1

1000

lookup

arr1

'found'

dsply

0006.03 c
0006.04 c

if

0006.05 c
0006.06 c

d
40

*in40=*on

else

0006.07 c

'notfou' dsply

0006.08

endif

0006.09

dsply

0006.10

do

0006.11

arr1(j)

0006.12

add

0006.13

enddo

0007.00

seton

dsply
1

0008.00 **
0009.00 1001
0010.00 2000
0011.00 1000
****************** End of data ***********************************
DSPLY 1001
DSPLY 2000
DSPLY 1000
DSPLY found
DSPLY 4001
DSPLY 1000
DSPLY 1001
DSPLY 2000

Pre runtime array

Pre runtime array is in between these 2 conditions where the value are static and the value
will be retrieved from disk and loaded into the array.

- 71 -

Tips n Facts

As a result there is no need to retrieve the value every time from the disk and usage of pre
runtime array makes it fast.

We must declare in keyword command DIM (), FROMFILE (), and PERRCD ().

60.Define data structure and types of data structure?


The different types fields and sub field stored with in single area. This area in storage is called
data structure.
Data structure means program allows you to define an area in storage and the layout of the
fields, called sub fields, with the area. This area in storage is called a data structure.
Data structure can be used for

Group non-contiguous data into contiguous internal storage locations

Define the same internal area multiple times using different data formats.

Operate on a field and change its contents

Divide a field into sub fields without using the MOVE or MOVEL

Define a data structure and its sub fields in the same way a record is defined.

Define multiple occurrences of a set of data

There are four different types of data structure commonly used.

General data structure

Data area data structure

File information data structure

Program status data structure

Data structure can be specified in D spec


Type IPDS
Data structure name
I Globally initialized data structure
S--Program status data structure
U--Data area data structure
BlanksGeneral (or) File status data structure

Data area data structure


A data area data structure, identified by a U in position 18 of the data structure statement,
indicates to the RPGLE program that if should read in and lock the data area of the same name at
program at program initialization and should write out and unlock the same data area at end of the
program.
The data area and data area structure must have the same name unless you rename the
data within the program by using the *NAMVAR DEFINE statement.

File information data structure


A file information data structure provides you with status information on file exception /error

occurs. This data structure name must be unique for each file. It consists of pre defined sub fields that
provide information on the file exception/error that occurred.

Program status data structure


This data structure is identified by as S in position 18 of the data structure statement,
provides program exception/error information to the program. The *ROUTINE, *STATUS, *PARM
keywords mostly preferred to determine the PS DS.

- 72 -

Tips n Facts
Example
SKANDASAMO/DATASTR
DUMP
*************** Beginning of data *************************
0001.00 HDEBUG(*YES)
0002.00 DPSSR

SDS

0004.00 DSTATUS

*status

0005.00 DROUTINE

*routine

0005.01 DPARMS

*parms

0005.02 DRES

2S 0

0007.00 C

Z-ADD

0007.01 C

Z-ADD

0010.00 C

EVAL

0011.00 C

'NOTCOM'

0012.00 C

0013.00 C

'COMING'

0014.00 C

NUM1

20

NUM2

20

RES=NUM1/NUM2

DSPLY
TAG
DSPLY

SETON

0015.00 C

*PSSR

BEGSR

0016.00 C

STATUS

DSPLY

0017.00 C

ROUTINE

0018.00 C

PARMS

LR

DSPLY
DSPLY

0019.00 C

DUMP

0020.00 C

GOTO

0021.00 C

ENDSR

****************** End of data ******************************


Output
DSPLY

102

DSPLY *DETC
DSPLY

DSPLY COMING
61. What is Lock? How you achieve in AS/400?
To give the access permission for database file. The Locks are provided by AS/400 system itself.
Type of lock

Share lock

Exclusive lock

The share lock only reading operation (PF file).

The exclusive lock to perform insert, update, and delete operations.


62. How you will release the lock?
By using RCLRSC [Reclaim Resource] command we can release the resources only. UNLOCK or
CHAIN (N) command also helps to release the lock.
By using WRKOBJLCK command and take F4.

- 73 -

Tips n Facts
63. How you execute CL command in RPGLE?
By using QCMDEXC command we can execute CL command in RPGLE. Two parameters will be
called use in the CL command to be executed and second is the length of the command.
64. Explain Commitment Control?
The AS/400 system has an integrated transaction recovery function called commitment control.
Commitment control is an extension of the journal function on the system.
The records used during a complex transaction are locked from other user and at the end of the
transaction; the program issues the commit operation, updating the records.
If the system fails before the commit operation is performed, all database changes are rolled
back to the previous commit operation and all the affected records are unlocked.
COMMIT-The transactions are updated in the data file. Commit occurs on COMMIT command
ROLLBACK- The transactions are NOT updated in the data file. Rollback occurs if there are
uncommitted transactions and on ROLLBACK command.
65. Explain about sub files in AS/400?

A subfile is a group of records READ from or WRITTEN to a display device file in one single
operation.

It is a display file facility

It is a group of records that can be stored in the main memory.

The program can store a group of records in the subfile one by one in a sequence.

LODING SUBFILES:

Load all (Size >Page)

Load on demand (Size >Page)

Load on demand (Size =Page)

Load all (Size >Page)

All the records from the database file will be loaded in to the subfile in one shot.

The subfile size should be greater than the page size at least by one. (SFLSIZ =5,
SFLPAG=4). The subfile size will dynamically grow when the subfile size mentioned
is less than the number of records in the database file.

PAGEUP and PAGEDOWN are taken care of by the system.

The total subfile size 9999 records.

Load on demand (Size > Page)


The number of records as mentioned in SFLPAG will be loaded initially.

Then the remaining records can be loaded by pressing PAGEDOWN, which is

taken care of by the programmer.

Same time PAGEUP is taken care of by the system.

The subfile size should be greater than the page size at least by one. (SFLSIZ =5,
SFLPAG=4). The subfile size will dynamically grow when the subfile size mentioned
is less than the number of records in the database file.

All the records loaded will exist in the subfile.

The total subfile size 9999 records.

- 74 -

Tips n Facts

Load on demand (Size = Page)

The number of records that will be loaded into the subfile must always be equal

to the value mentioned in for SFLSIZ and SFLPAG.

Every time the subfile should be cleared before paging up or paging down.

PAGEUP and PAGEDOWN are taken care of the programmer.

The number of records that can be in the subfile at any instance will be equal to

SFLSIZ and SFLPAG values.


Subfile points:
Record formats:
One display -1024 records formats
One display file 512 subfile
Record formats are
1.subfile record format (SFL)
2.subfile control record format (SFLCTL)
subfile record format(SFL)
This record format will have the multiple record definitions
-Defining fields.
-Defining database fields.
Subfile Control record format (SFLCTL)
This record format will control the subfile record format.
-Defining texts
-Defining control fields.
Subfile Size (SFLSIZ)
This keyword can be used to specify the maximum number of records that can be in the
subfile (buffer)
Default ->2
Maximum ->9999
Subfile Page (SFLPAG)
This keyword can be used to specify the maximum number of records that can be in one
subfile page. That is the maximum number of records that the system will display in the screen
at a time.
-Default ->1
-Maximum-> depends upon the display record size.
If the subfile size is at least one greater than the subfile page then the subfile size will
grow dynamically up to 9999.
General keywords
SFLDSP -> subfile display
SFLDSPCTL

-> subfile display control

SFLCLR -> subfile clear


SFLEND -> subfile end

- 75 -

Tips n Facts
Define General Keywords
Subfile control record . . . . . . . . . :
Type choices, press Enter.

SENWLT1
Keyword

Related subfile record . . . . . . .

SFLCTL

Subfile cursor relative record . . .


Subfile mode . . . . . . . . . . . .

SENWND1

SFLCSRRRN

Name

Y=Yes

Indicators/+

Display subfile records . . . . . .

SFLDSP

Display control record . . . . . . .

SFLDSPCTL

25
Y

26

SFLINZ

Delete subfile area . . . . . . . .

SFLDLT

Clear subfile records . . . . . . .

SFLCLR

Indicate more records . . . . . . .

28

SFLEND

30

SFLEND parameter

........

*MORE

SFLEND parameter

........

*SCRBAR

Record not active . . . . . . . . .

Name

SFLMODE

Initialize subfile fields . . . . .

Name

Y
*MORE ...

SFLRNA
More...

F3=Exit

F12=Cancel

Subfile Display (SFLDSP)


This keyword is used to insert the system that the subfile records format has to be
displayed. The subfile record format without any record in it cannot be displayed.
Subfile Display control (SFLDSPCTL)
This keyword is used to instruct the system that the subfile control record format has to
be displayed.
0009.00 C N30

SETON

2526

Subfile Clear (SFLCLR)


This keyword is used to clear the records in the subfile records format.
An indicator can control this keyword.
0005.00 C

SETON

0006.00 C

WRITE

0007.00 C

SETOFF

28
SENWLT1
28

Subfile End (SFLEND)

This keyword is used to get the display of + sign or a text more or bottom in the
bottom of the subfile.

+ or

more indicates the existence of more records in the subfile which can be

displayed by pressing PAGEDOWN key .

Bottom indicates the end of the subfile.


Instead of Enter Key - Help Type a CF or CA key number to specify that the operator is
to use the Enter key as a Roll Up key. The specified CF or CA key acts as the Enter key.

Mandatory keywords for subfile

SFL

SFLCTL

SFLSIZ

- 76 -

Tips n Facts

SFLPAG

SFLDSP

RRN (Relative record number) (control record level keyword)

RRN is the numeric value (1 to 9999) associated with each subfile record for accessing

Each record should have a unique RRN value

This value has to be giving by the program.

This has to be associated with the subfile record format in the F spec continuation line.

This has to be declared in the program as numeric variable of maximum length 4 and
decimal position 0.
F spec format in continuation line with SFILE option
0002.00 FSENDESFILECF

0003.00 F

WORKSTN
SFILE (SFL01:RRN1 )

Where RRN1 -> RRN variable name


SFL01-> subfile record format name.
RPGLE Opcodes
EXFMT
If SFLDSP and SFLDSPCTL indicators are on, this opcode will send the two
subfile record formats to the display device and waits for the users response.
WRITE (SFL)

This opcode is used to add a record to the subfile record format

RRN value should be set with a non-existing value before adding the record
in the subfile record format.

WRITE (SFLCTL)
This keyword is used for clearing & display the subfile
SFLDROP (subfile drop)
This control record level keyword is used to assign a CA (command attention) or CF
(command function) key. The program first displays the subfile in truncated form; subfile records
are truncated to fit on one display line. When the user presses the specified key, the program
displays the records in the folded form.
Or
Subfile Initially Truncated - Help Type a command function (CF) or command attention
(CA) key number to assign a CF or CA key to specify if a subfile control record requiring more
than one display line should be truncated to one line, or should be folded to display on two lines.
When this keyword is specified, the subfile is first displayed in truncated form.

The operator

presses the specified CF or CA key to switch from truncated form to folded form, or from folded
form to truncated form.
SFLFOLD (subfile fold)
This control record level keyword is used to assign a CA (command attention) or CF
(command function) key. The program first displays the subfile in folded form. When the user
presses the specified key, the program displays the records again in the truncated form.
Or

- 77 -

Tips n Facts
Subfile Initially Folded - Help Type a command function (CF) or command attention (CA)
key number to assign a CF or CA key to specify if a subfile control record requiring more than one
display line should be truncated to one line, or should be folded to display on two lines. When this
keyword is specified, the subfile is first displayed in folded form.

The operator presses the

specified CF or CA key to switch from folded form to truncated form, or from truncated form to
folded form.
SFLINZ (subfile initialize)
This control record level keyword is used to specify that the program is to initialize all
records in the subfile on the output operation (read & updates) to the subfile control record
format.
The fields in each subfile record are initialized to
CHAR->BLANKS
NUME->ZEROS
FLOAT->NULLS
SFLNXTCHG (subfile next change)
This record level keyword is used on the subfile control record format to force the user
to correct program-detected keying error in the subfile records that have been read by the
program. It does this by causing the record to be changed so that a get-next-changed operation
must read the record.
Or
Return Record - Help Type Y (Yes) to instruct the system to return this subfile record to
your program on a subsequent Get-Next-Changed input operation to the subfile. This record is
returned whether or not the operator changes it.

Note: You must type Y. If you do not, the

entry will not be used. `You can specify condition indicators for the SFLNXTCHG keyword.
SFLROLVAL (subfile roll value)
This field-level keyword is used to specify that the user can key a value into this field to
tell the program how many records to PAGEUP or PAGEDOWN when the appropriate paging key is
pressed.
SFLRCDNBR (subfile record number)
This field level keyword on the subfile control record format is used to specify that the
page of the subfile to be displayed is the page containing the record whose relative record is in
this field. If you do not specify this keyword, the program displays the first page of the subfile by
default
Example for load all
SKANDASAMO/SUBFILE
NEWEMP
*************** Beginning of data *******************
0001.00

UNIQUE

0002.00

R EMPNEW

0003.00

EMPNOM

0004.00

EMPNA

6P 0
15A

TEXT('EMPLOYEE NUMBER')
TEXT('EMPLOYEE NAME')

- 78 -

Tips n Facts
0005.00

SEX3

1A

0006.00

AGE3

3P 0

0007.00

ADDRESS5

0008.00

CITY5

0009.00

TEXT('EMPLOYEE SEX')
TEXT('EMPLOYEE AGE')

15A

TEXT('ADDRESS')

10A

TEXT('CITY')

K EMPNOM

****************** End of data *********************************


DATA FILE
Display Report
EMPNOM

EMPNA

SEX3 AGE3

ADDRESS5

000001

101

K.SENTHILKUMAR

000002

102

R.SHYAMSUNDAR

000003

103

B.MOHAN

27

TCODE

SALEM

000004

104

K.KUMAR

25

SALEM

SALEM

000005

105

A.ARUL

000006

106

BALU

000007

107

SENTHIL

000008

108

RAJ

000009

109

HEMA

000010

110

VEL

000011

111

RAMESH

000012

122

SUDHA

000013

123

KANDASAMY

25

22

TRICHY
SALEM
CHENNAI

SALEM

28
M

TRICHY

NAMAKKAL

SALEM

56

SALEM

SALEM

TCODWE

67
M

TRICHY

SALEM

33

27

SALEM

35

ATTUR

SALEM

25

25

CITY5

SALEM

ATTUR

SALEM

SALEM

ATTUR

34

SALEM

ATTUR

****** ******** End of report ********


SKANDASAMO/SUBFILE
SUB04
*************** Beginning of data ****************************
0002.00 FSENDESFILECF
0015.00 C

*IN03

E
DOWEQ

0016.00 C

EXFMT

0016.01 C

IF

0016.02 C

CALL

0016.03 C

ENDIF

0017.00 C

WORKSTN

03

*OFF

MAIN1
*IN04=*ON AND EMPCUR='EMPNOM'
'SELOADALL3'

LEAVE

0018.00 C

ENDDO

0019.00 C

SETON

LR

****************** End of data *******************************


SKANDASAMO/SUBFILE
SELOADALL3
*************** Beginning of data *****************************
0001.00 FNEWEMP

IF

0002.00 FSENDESFILECF

DISK
E

WORKSTN

0003.00 F
0004.00 C

SFILE(SENWND1:RRN1)
Z-ADD

RRN1

- 79 -

40

Tips n Facts
0005.00 C

SETON

0006.00 C

WRITE

0007.00 C

SETOFF

0008.00 C

READ

0009.00 C N30

28
SENWLT1
28
EMPNEW

30

SETON

2526

0010.00 C

DOW

*IN30=*OFF

0011.00 C

WRITE

SENWND1

0012.00 C

ADD

READ

EMPNEW

0013.00 C
0014.00 C

30

RRN1
30

LEAVE

0015.00 C

ENDDO

0016.00 C

DOW

0016.01 C

03

*IN03=*OFF

LEAVE

0016.02 C*

WRITE

HEATER

0016.03 C*

WRITE

FOOTER1

0016.04 C

EXFMT

SENWLT1

0020.00 C

ENDDO

0021.00 C

SETON

LR

****************** End of data *****************************


window main1 take 8

Select Record Keywords


Record . . . :

MAIN1

Type choices, press Enter.


Y=Yes
General keywords . . . . . . . .

Indicator keywords . . . . . . .

Application help . . . . . . . .
Select General Keywords
Record . . . :

MAIN1

Type choices, press Enter.

Keyword

Y=Yes

If this record is not on display, write it


to the display before issuing read . . . . . . .
Keep record on display . . . . . . . . . . . . . .
Assume record is on display . . . . . . . . . . .
Allow rolling of lines . . . . . . . . . . . . . .

INZRCD
KEEP
ASSUME

ALWROL

Retain CLEAR HELP HOME and ROLL keys . . . . . . .

RETKEY

Retain command function (CFnn and CAnn) keys . . .


Change input defaults . . . . . . . . . . . . . .

RETCMDKEY

CHGINPDFT

Select parameters . . . . . . . . . . . . . . .
Menu-Bar display . . . . . . . . . . . . . . . . .

MNUBARDSP

- 80 -

Tips n Facts
Select parameters . . . . . . . . . . . . . . .
Entry field attribute . . . . . . . . . . . . . .

ENTFLDATR

Select parameters . . . . . . . . . . . . . . .
Return cursor location . . . . . . . . . . . . . .

RTNCSRLOC

Select parameters . . . . . . . . . . . . . . .
Define Return Cursor Location
Record . . . :

MAIN1
Keyword number
1

of 1

Roll

+/F4 for list

Type parameters, press Enter.


Keyword
Return cursor location . . . . . . . . . . RTNCSRLOC
Type indicator *RECNAME . . . . . . . .

Y=Yes

Cursor record . . . . . . . . . . . . .

Y=Yes

RECSD

Cursor field . . . . . . . . . . . . . .

Name

EMPCUR

Name

Cursor position . . . . . . . . . . . .
CF03

Name

03

CF04

04

TAKE 12 AND F4
Work with Fields
Record . . . :

MAIN1

Type information, press Enter.


Number of fields to roll . . . . . . . . . . . . . . . . . .

Type options, change values, press Enter.


1=Select keywords
Option

Order
70

4=Delete field

Field

AGE

Type Use Length Row/Col Ref Condition Overlap


C

21

15 014

80

RECSD

10

90

EMPCUR

10

100

----------

110

F3->EXIT

120

EMPNOM

76
C
S

21 003

37
B

6,0

22 005
09 036

Y
More...

Add

Hidden

Add

Message

Add

Program-to-system

TAKE 12
SENWLT1
Select Window Keywords
Window record . . . . . . . . . . . . . :

SENWLT1

- 81 -

Tips n Facts
Type choices, press Enter.
Y=Yes
General keywords . . . . . . . .

Select record keywords . . . . .

General SFLCTL keywords . . . . .


Subfile display layout . . . . .

Subfile messages . . . . . . . .

Select General Keywords


Window record . . . . . . . . . . . . . :

SENWLT1

Type choices, press Enter.


Keyword
Window parameters . . . . . . . . . . . .

Y=Yes Indicators/+

WINDOW

Select parameters . . . . . . . . . . .

Window borders . . . . . . . . . . . . . .

WDWBORDER

Select parameters . . . . . . . . . . .
Remove windows . . . . . . . . . . . . . .

RMVWDW

User Restore Display . . . . . . . . . . .

USRRSTDSP

Define Window Parameters


Record . . . :

SENWLT1

Keyword . . :

WINDOW

Referenced window . . . . . . . . . . . .

Name

-ORWindow definition
Default start positioning . . . . . . .

Y=Yes

-ORStart line
Program-to-system field . . . . . . .
Actual line . . . . . . . . . . . . .

Name

1-25

Start position
Program-to-system field . . . . . . .

Name

Actual position . . . . . . . . . . .

Window lines . . . . . . . . . . . . . .

20

Window position . . . . . . . . . . . .
Message line . . . . . . . . . . . . . .
Restrict cursor to window . . . . . . .

1-128
1-25

40
Y

1-128
Y=Yes

Y=Yes

Select Record Keywords


Record . . . :

SENWLT1

Type choices, press Enter.


Y=Yes
General keywords . . . . . . . .

Indicator keywords . . . . . . .

Application help . . . . . . . .
Help keywords . . . . . . . . . .
Output keywords . . . . . . . . .

- 82 -

Tips n Facts
CF12

12

CF03

03
Define General Keywords

Subfile control record . . . . . . . . . :


Type choices, press Enter.

SENWLT1
Keyword

Related subfile record . . . . . . .

SFLCTL

Subfile cursor relative record . . .


Subfile mode . . . . . . . . . . . .

SENWND1

SFLCSRRRN

Name

SFLMODE

Name

Y=Yes

Indicators/+

Display subfile records . . . . . .

SFLDSP

Display control record . . . . . . .

SFLDSPCTL

Initialize subfile fields . . . . .

25
Y

26

SFLINZ

Delete subfile area . . . . . . . .

SFLDLT

Clear subfile records . . . . . . .

SFLCLR

Indicate more records . . . . . . .

28

SFLEND

30

SFLEND parameter

........

*MORE

SFLEND parameter

........

*SCRBAR

Record not active . . . . . . . . .

Y
*MORE ...

SFLRNA
More...

F3=Exit

F12=Cancel
Define Display Layout

Subfile control record . . . . . . . . . :

SENWLT1

Type values, press Enter.


Keyword Number
Records in subfile . . . . . . . . . .

SFLSIZ

Program-to-system field . . . . . .
Records per display . . . . . . . . .

SFLPAG

Spaces between records . . . . . . . .

SFLLIN

OUTPUT
EMPLOYEE DETAILS
1.SELECT
OPT

Name

EMPNUMBER

NAME

000101

K.SENTHILKUMAR

000102

R.SHYAMSUNDAR

000103

B.MOHAN

000104

K.KUMAR

000105

A.ARUL
More...

EMPLOYEE DETAILS:
1.SELECT

- 83 -

Tips n Facts
OPT

EMPNUMBER

NAME

000106

BALU

000107

SENTHIL

000108

RAJ

000109

HEMA

000110

VEL
More...

EMPLOYEE DETAILS
1.SELECT
OPT

EMPNUMBER

NAME

000111

RAMESH

000122

SUDHA

000123

KANDASAMY

66. ILE advantages over RPG?

Better call performance

Modularity

Multiple-language integration

Enhancements to the ILE compilers

Reusable components

Control over application run-time environment

Code optimization

Tool availability

Foundation for the future

67. What is a Module?


A module is a non-executable program and it contains one or more procedures. If you have
modules without procedure then it means that it is having only one default procedure and in case we can
use CALLB. We are creating a RPGLE module by CRTRPGMOD and a CL module by CRTCLMOD commands.
68.How to the create module?
A module is created as a separate object type (*MODULE). Using the CRTRPGMOD command
creates an RPGLE module. A module object cannot be run directly. You must use the CRTPGM command to
bind module object into a program object. First option 15 or CRTRPGMOD command to create a module.
The CRTPGM command is used to cerate a program from one or more module.
SKANDASAMO/RPGILE
MAIN
*************** Beginning of data *******************************
0001.00 C

CALLB

'ADD'

0002.00 C

CALLB

'SUB'

0003.00 C

CALLB

'MUL'

0004.00 C

SETON

LR

- 84 -

Tips n Facts
****************** End of data **********************************
SKANDASAMO/RPGILE
ADD
*************** Beginning of data *******************************
0002.00 C

Z-ADD

0002.01 C

40

Z-ADD

40

0004.00 C

ADD

40

0005.00 C

DSPLY

0006.00 C

SETON

LR

****************** End of data *********************************


SKANDASAMO/RPGILE
SUB
*************** Beginning of data *******************************
002.00 C

Z-ADD

002.01 C

10

40

Z-ADD

40

004.00 C

SUB

40

005.00 C

DSPLY

006.00 C

SETON

LR

****************** End of data *********************************


SKANDASAMO/RPGILE
MUL
*************** Beginning of data ******************************
0002.00 C

Z-ADD

10

40

0002.01 C

Z-ADD

40

MULT

40

0004.00 C

0005.00 C

0006.00 C

DSPLY
SETON

LR

****************** End of data *********************************


CRTPGM Take F4
Program . . . . . . . . . . . . > MAIN
Library . . . . . . . . . . . >

SKANDASAMO Name, *CURLIB

Module . . . . . . . . . . . . . > MAIN


Library . . . . . . . . . . . >

Name
Name, generic*, *PGM, *ALL (PEP)

SKANDASAMO Name, *LIBL, *CURLIB...

> ADD
>

SKANDASAMO

> SUB
>

SKANDASAMO

+ for more values > MUL


>
Text 'description' . . . . . . .

SKANDASAMO
*ENTMODTXT

OUTPUT
DSPLY
DSPLY

9
5

- 85 -

Tips n Facts
DSPLY

50

69. What is the difference in between CALL, CALLB, and CALLP?


CALL is a dynamic call where the control will be transferred when the program is executed.
(Control will be transfer the another program (run time) so it is dynamic call).
Where as CALLB and CALLP are static calls. A module is a non-executable program and it
contains one or more procedures. If you have modules without procedure then it means that it is having
only one default procedure and in case we can use CALLB.
A module is having more than one procedure then we can give explicitly the procedure name to
be called in case of CALLP out of these three CALLP is the most efficient one. (Using the CALLB, CALLP a
program or module is bind in the program so it is static).

70. What is the difference between Bind by value and Bind by reference?
Bind by value

Bind by Reference

Here the entire modules to be bounded are

In this case we are binding the programs by

physically copied into the main program object.

using

service

programs,

which

contain

reference to the module that has been called,


and the modules are not physically copied into
The program will be executed even when you

the program object.


The program will not executed when the bind

delete the entire module that has been called.

modules are deleted.

Bind by value is faster than bind by reference. (All

It is not as faster as bind by value. (All the

the modules to be bind in the main program, so it

modules cant bind the main program it is refer

is fast)

the pointer)

71. Define pass by value and pass by reference?

Pass by reference:
Pass by reference we are passing the address of the parameters and not the actual value

and so the changes in the called procedure will affect the value in the calling programs. In OPM
programs we are using only call by reference.

Pass by value:
Pass by value we are passing the value of the parameter, changes made to the formal

arguments in the called function have no effect on the values of the actual arguments in the calling
function it is used in c program.
In RPGLE we have the option to pass the parameter by value by giving the keyword
VALUE.
72. What are Program Entry Procedure (PEP) and User Entry Procedure (UEP)?

- 86 -

Tips n Facts
If we are binding many modules together to form a program then we have to specify which
module has to take control first when it has been called and that module is called as PEP for that
program.
User entry procedure (UEP) is the first statement that takes the control when a program has
been called. For example in C programs main () will be executed first when it has been called and like wise
in RPG the statement coded in C Spe will take the control first.
73. Define Copybook in RPGLE?
It will copy a Subroutine (or) any group of codes physically into the program, which is copying it.
SKANDASAMO/RPGILE
COP
*************** Beginning of data ******************************
0002.00 C

DSPLY

0002.01 C

EXSR

0004.00 C

SETON

50

ADD
LR

0005.00 C/COPY RPGILE, COPY


****************** End of data ********************************
SKANDASAMO/RPGILE
COPY
*************** Beginning of data ******************************
0000.01
0001.00 C

ADD

BEGSR

DSPLY

0002.00 C
0003.00 C

ADD

0004.00 C

ENDSR

****************** End of data *******************************


OUTPUT
13
DSPLY

18

74.What will FOR opcode will do?


SKANDASAMO/DOLOOP
FOR
*************** Beginning of data *****************************
0001.00 di

0002.00 dn
0003.00 c
0004.00 c

5p 0 inz(1)

s
for
i

endfor

0006.00 c

for

0008.00 c

i=1 to n

dsply

0005.00 c
0007.00 c

5p 0 inz(10)

i=n downto 1

dsply
endfor

0008.01*for(I=5;I<40;i=i+10)
0009.00 c

for

i=5 by n to 40

- 87 -

Tips n Facts
0010.00 c

dsply

0011.00 c

endfor

0012.00 c
0013.00 c

for
i

i=5 to 40 by n

dsply

0014.00 c

endfor

0015.00 c

seton

lr

****************** End of data *****************************


OUTPUT
DSPLY 1 DSPLY

10

DSPLY 2 DSPLY

DSPLY 3 DSPLY

DSPLY 4 DSPLY

DSPLY 5 DSPLY

DSPLY 6 DSPLY

DSPLY 7 DSPLY

DSPLY 8 DSPLY

DSPLY 9 DSPLY

DSPLY 10

DSPLY

DSPLY 5 DSPLY

DSPLY 15

DSPLY

DSPLY 25

DSPLY

DSPLY 35

DSPLY

15
25
35

75. What are the various stages for a job after it is submitted?
Job queue, Active job, and OUTQ is the three stages after the job has been submitted.
76. What is the equivalent command to setll *loval in CL?
POSDBF with file position as *start will set the file to the beginning (or) using OVRDBF and
specify the key field value by RRN value (or) by giving *start.
77. How to create a service program and what are the steps involved in this?

The service program means most commonly used modules are grouped (binding)
together to form it is called service program.

A service program is not bound to its caller until activation time

While creating service program we can create a binder program where we can refer the modules
(or) procedures (or) even data types to be used by the program. Which is using service program.
Advantages of service programs

They do not take up auxiliary storage space. There is only one copy for all users.

There is only a single copy of the read-only code in main storage for all users in this service
programs is the same as a program that you call dynamically.

Each user of the service program has an independent work area.

You can pass parameters to a service programs by using the traditional parameter list (or) by
importing and exporting variables.

- 88 -

Tips n Facts
Service programs can be maintained independently of the programs that use the functions. In

most cases, changing a service programs does not cause a program using the function to be
changed or re-created.
Disadvantages of service programs
Service programs are less desirable for a function you may or may not need. The reason is that

it is slower to call a main program that refer to a service program


78. What is an activation group?
Activation group is the boundary set for similar programs. Activation group is also a storage
space in memory.

CLP has a OVRDBF command and calls a RPGLE program

RPGLE program performs a read operation and the pointer is now in the second program and
now call the program 3

RPGLE program that also do a read operation which will read the second record

Since the pointer is in the second position and then return to 2 nd


situation when the control transfer from 3

rd

record since the 2

rd

program in the above

record is already read in

program 3. But we need to need the 2nd record according to the logic but this is not possible
in any OPM programs. But in RPGLE there is a solution for this problem by giving a common
activation group for 1st and 2nd program and have a separate activation group for the 3 rd
program while creating the program itself and this will avoid all the problem we faced before.

In some situation we want to share between 2 program then we can give the activation
group in *job level in which the changes in one program will be affected in another program.

Types of activation group levels:

*New: In this case every time you call the program an new activation group will be
created which this case will not be used mostly.

*caller: If we dont know the type of the program that is calling then we can
specify *caller where the activation group will be the same of the program that is
calling.

Named activation group: We can give our own named for different activation
group.

79.What are the statements that are affected by activation group?

OVRDBF

OPNDBF

OPNQRYF

STRCMTCTL

DLTOVR

80. What are the statements, which is not used in CLLE that is used in CLP?

RCLRSC which is replaced by RCLACTGRP

TFRCTL

81. What is the difference between FMTDTA and OPNQRYF?


FMTDTA
It will sort the records sequentially based on the

OPNQRY
It will sort the records based on the field values.

- 89 -

Tips n Facts
position of the record
If any change in the attribute size of a PF then we

If there is any change in the attribute size it will not

have to change the program specification also.

affect the program specification also.

FMTDTA is bit faster in process than OPNQRYF.

OPNQRYF is slower as compare to FMTDTA if we are


processing millions of records.

82.What is the new name for AS/400?


I series 400 is the new name given to AS/400 by IBM now.
83.How to see source of copybooks include in a program while compiling or debugging?
While compiling the program give *list instead of *source which will expand all the
copybooks.
84. Explain inner join or natural join and left outer join?
Inner join
Inner join means the matching records in between the joining file will be selected.
Columns . . . 1 71
Edit
KSENTHILS/EXAMPLE
SEU==> JPF01
FMT PF
*************** Beginning of data ****************************
0001.00
R JP1REC
0002.00
EMPNO
5S 0
0003.00
EMPNAME
20A
0004.00
K EMPNO
****************** End of data *****************************
Columns . . . 1 71
Edit
KSENTHILS/EXAMPLE
SEU==> JPF02
FMT PF.
*************** Beginning of data ***************************
0001.00
R JP2REC
0002.00
EMPNO
5S 0
0003.00
EMPSAL
10P 2
0004.00
K EMPNO
****************** End of data ********************************
Display Report
EMPNO EMPNAME
000001 1,001 SHYAMBABU
000002 1,002 SENTHILKUMAR
000003 1,003 RAMESH
****** ******** End of report ********
EMPNO
EMPSAL
000001 1,001
100.00
000002 1,002
20.00
000003 1,004
300.00
****** ******** End of report ********
Columns . . . 1 71
Edit
KSENTHILS/EXAMPLE
SEU==> JOFILE
FMT LF.
*************** Beginning of data ************************
0001.00
R JREC1
JFILE (JPF01 JPF02)
0002.00
J
JOIN (1 2)
0003.00
JFLD (EMPNO EMPNO)
0004.00
EMPNO
JREF (JPF01)
0005.00
EMPNAME
0006.00
EMPSAL
0007.00
K EMPNO
****************** End of data*********************
EMPNO EMPNAME
EMPSAL
000001 1,001 SHYAMBABU
100.00
000002 1,002 SENTHILKUMAR
20.00
****** ******** End of report ********

- 90 -

Tips n Facts

Left outer join

Left outer join all the records from primary file and matching records from the
secondary file will be selected.
Columns . . . 1 71
Edit
KSENTHILS/EXAMPLE
SEU==> JOOUT
FMT LF.
*************** Beginning of data*********************
0001.00
JDFTVAL
0002.00
R JREC1
JFILE (JPF01 JPF02)
0003.00
J
JOIN (1 2)
0004.00
JFLD (EMPNO EMPNO)
0005.00
EMPNO
JREF (JPF01)
0006.00
EMPNAME
0007.00
EMPSAL
0008.00
K EMPNO
****************** End of data********************
EMPNO EMPNAME
EMPSAL
000001 1,001 SHYAMBABU
100.00
000002 1,002 SENTHILKUMAR
20.00
000003 1,003 RAMESH
.00
****** ******** End of report ********

SEQUENCING DUPLICATE RECORDS


Columns . . . 1 71
Edit
KSENTHILS/EXAMPLE
SEU==> SEQ1
FMT PF.
*************** Beginning of data ***********************
0001.00
R SEQREC1
0002.00
EMPNO
5P 0
0003.00
EMPNAME1
20A
0004.00
ADDRESS
20A
0005.00
K EMPNO
****************** End of data **************************
Columns . . . 1 71
Edit
KSENTHILS/EXAMPLE
SEU==> SEQ2
FMT PF
*************** Beginning of data****************
0001.00
R SEQREC2
0002.00
EMPNO
5P 0
0003.00
EMPNAME
20A
0004.00
TEL
10P 0
****************** End of data ******************
EMPNO EMPNAME1
ADDRESS
000001 10,001 BOB
23,OLD MADIWALA
000002 10,002 DANNY
50,LONG ISLAND
000003 10,003 PRINC
90,ATTUR
****** ******** End of report ********
EMPNO EMPNAME
TEL
000001 10,001 BOB
825,777
000002 10,001 BOB
825,999
000003 10,001 BOB
825,888
000004 10,002 DANNY
4,222,600
****** ******** End of report ********
Columns . . . 1 71
Edit
KSENTHILS/EXAMPLE
SEU==> JDFTSEQ
FMT LF
*************** Beginning of data ******************
0001.00
R RECSEQ
JFILE (SEQ1 SEQ2)

- 91 -

Tips n Facts
0002.00
J
JOIN (1 2)
0003.00
JFLD (EMPNAME1 EMPNAME)
0004.00
JDUPSEQ (TEL)
0005.00
EMPNO
JREF (2)
0006.00
EMPNAME1
0007.00
ADDRESS
0008.00
TEL
****************** End of data************************
EMPNO EMPNAME1
ADDRESS
TEL
000001 10,001 BOB
23,OLD MADIWALA
825,777
000002 10,001 BOB
23,OLD MADIWALA
825,888
000003 10,001 BOB
23,OLD MADIWALA
825,999
000004 10,002 DANNY
50,LONG ISLAND
4,222,600
****** ******** End of report ********

JOIN DESCEND
Columns . . . 1 71
Edit
KSENTHILS/EXAMPLE
SEU==> JDFTSEQ
FMT LF
*************** Beginning of data ***********************
0001.00
R RECSEQ
JFILE (SEQ1 SEQ2)
0002.00
J
JOIN (1 2)
0003.00
JFLD (EMPNAME1 EMPNAME)
0004.00
JDUPSEQ (TEL *DESCEND)
0005.00
EMPNO
JREF (2)
0006.00
EMPNAME1
0007.00
ADDRESS
0008.00
TEL
****************** End of data *************************
EMPNO EMPNAME1
ADDRESS
TEL
000001 10,001 BOB
23,OLD MADIWALA
825,999
000002 10,001 BOB
23,OLD MADIWALA
825,888
000003 10,001 BOB
23,OLD MADIWALA
825,777
000004 10,002 DANNY
50,LONG ISLAND
4,222,600
****** ******** End of report ********
85. Explain Build in function in ILE?
%SUBST (String name: String position: length)

%ABS (Absolute value by omitting sign)

%EDITC (string: X)

In a application if we want to concatenate a string with a numeric then we can use this
%EDITC
Example:
SKANDASAMO/BULID
EDITC
*************** Beginning of data *******************************
0001.00 da

10a

0002.00 db

10p 0 inz(20)

inz('shyam')

0003.00 dc

10a

inz('sundar')

0004.00 dd

10s 0 inz(12)

0005.00 de

10a

0006.00 dout

0007.00 c

eval

0009.00 c
0010.00 c

out

inz('rambabu')

50a
out=a+%editc(b:'X')+c+%editc(d:'X')+e

dsply
seton

lr

- 92 -

Tips n Facts
0011.00
****************** End of data ***********************************
OUTPUT
DSPLY shyam

0000000020sundar

0000000012rambabu

%REPLACE (Replacing string, actual string, starting position, offset)


Here we are replacing senthilkumar from position 4 to 3 by kum. The output will be
senkumlkumar.
SKANDASAMO/BULID
REPLACE
*************** Beginning of data ****************************

0000.01 d*replace the string using keyword %replace


0001.00 dc

16a

0002.00 db

20a

0003.00 c
0004.00 c

eval
b

inz('senthilkumar')

b=%replace('kum':c:4:3)

dsply

0005.00 c

seton

lr

****************** End of data *****************************


OUTPUT
DSPLY senkumlkumar

%TRIM (%TRIML, %TRIMR)

The use of the TRIM functions is very limited, in that they support only the use of character
variables and data structures. Numeric fields, and zero-fill values are not supported. They do, however,
provide some useful function for string handling. For example, in RPG IV, one line of code is all that's
needed to left-adjust a value within a field. For example:
.....CCRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq
C

ExFmtCustMaint
C

Eval

CustName=%TrimL(CustName)

Typically, the %TRIM function is the only one of the three that get used. The other two, however,
do have their place.
%TRIM removes trailing and leading blanks from a field, and returns the remaining value, in
place, within the expression. The returned value is treated similar to a constant value with leading or
trailing blanks.
%TRIML removes leading blanks (trim-left) from a field, and returns the value in place, within the
expression.
%TRIMR removes trailing blanks (trim-right) from a field, and returns the value in place, within
the expression.

%FOUND, %EOF, %EQUAL,%OPEN

OS/400 Version 4, Release 2 RPG IV supports the elimination of the Resulting Indicators. In their
place, several new built-in functions have been introduced. Most of these new built-in function provide

- 93 -

Tips n Facts
information about the result of File operations similar to the Result indicators. But instead of coding
Resulting indicator 3, for example, to check for the end-of-file condition, you simply check the value of
the %EOF built-in function.
The built-in functions that replace the Resulting Indicators include:
%FOUND, %EOF, %EQUAL. In addition, there are %OPEN, %STATUS, and %ERROR. Mysteriously
missing is %LOCK to check for a record lock condition.
%FOUND returns an *ON or *OFF condition if the previous File operation returns a record-found
condition. This is particularly useful on the CHAIN operation. Realize, however, that when CHAIN sets on
Resulting indicator 1, a not-found condition is signaled. Whereas, without coding Resulting Indicator 1, the
%FOUND built-in function returns the found condition.
%EOF can be used to check for end-of file, beginning of file, or subfile full conditions. A READ
and READE return %EOF=*ON if the end of file is reached. READP and READPE return %EOF=*ON if the
beginning of file is reached. The WRITE operation returns %EOF=*ON if the WRITE operation to a subfile
detail record returned a subfile-full condition.
%EQUAL is used by the SETLL operation to indicate that it detected a record in the file with a
key equal to that of the value specified in Factor 1. Since SETLL does not read the record, does not lock
the record, and does not copy the data into the input buffer, SETLL is much faster and less of an impact on
the performance of the application than other operations, such as CHAIN. Use CHAIN when you need to
retrieve the record, use SETLL and %EQUAL when you need to only check for the existence of a record.
%OPEN is used to check to see if a file has already been opened. The built-in function returns
*ON if the file is opened, otherwise it returns *OFF.

%ELEM
%ELEM will display the array dimension

ELEM

*************** Beginning of data ******************************


0001.00 darr1
0002.00 dc

0003.00 c
0004.00 c

3s 0

eval
c

0005.00 c

3s 0 dim(100)
c=%elem(arr1)

dsply
seton

lr

****************** End of data **********************************


OUTPUT
DSPLY 100

%SIZE
%SIZE will display the size of the variable
SKANDASAMO/BULID
SIZE
*************** Beginning of data *****************************

0000.01 D*BY USING THIS COMMAND FIND SIZE OF DATA VALUE


0001.00 darr1

10p 0 dim(10)

- 94 -

Tips n Facts
0002.00 dds1

0003.00 dnum

10p 0 dim(20)

20p 0

0004.00 c

z-add

0005.00 c

movel

'senthil'

0006.00 c

eval

20 0
b

10

num=%size(a)

0007.00 c
0008.00 c

num

dsply

0009.00 c
0010.00 c

eval
num

dsply

0011.00 c
0012.00 c

eval
num

eval
num

eval
num

num=%size(ds1)

dsply

0017.00 c
0018.00 c

num=%size(arr1:*all)

dsply

0015.00 c
0016.00 c

num=%size(arr1)

dsply

0013.00 c
0014.00 c

num=%size(b)

eval
num

num=%size(ds1:*all)

dsply

0019.00 c

seton

lr

****************** End of data **********************************


OUTPUT
DSPLY

DSPLY

11

DSPLY

10

DSPLY

DSPLY

60

DSPLY
DSPLY
%EDITW

6
120

86.Explain keyword in ILE?


Overlay

Rename

Prefix

Options

Const

87.How you can schedule a job to run periodically?


We have to create a job scheduler for running a job periodically. Here we can make a job to run
once or periodically at a given date and time. We can create a job scheduler by using ADDJOBSCDE
command.
We can list all the job scheduler running by using the command WRKJOBSCDE command and
we can delete a job scheduler by using RMVJOBSCDE or we can reschedule the job by using
CHGJOBSCDE.
88.How to debug a batch job?
Hold the batch job to be debugged by using WRKACTJOB command and having option 3. Set the
pointer in the batch program to be debugged by using STRDBG and call the STRSRVJOB command and
start the service program, which will enter into the debug mode. After entering into debug mode
release the job that is hold before.

- 95 -

Tips n Facts
89.Define KLIST?
KLIST operation is a declarative operation that gives a name to list of KFLD. This KLIST can be
used as a search argument to retrieve records from files that have a composite key.
90.Define PLIST?
The declarative PLIST operation defines symbolic name for a parameter list to be specified in a
CALL operation.
91.Define composite key?
It is a key for a file, which is composed of more than one field.
92.Explain procedure used in RPGLE?
A procedure is a non-executable program. If a module is having more than one procedure
then we can give explicitly the procedure name to be called in case of CALLP.
Defining the prototype:

Prototype will specify the following things


Parameter type

Sequence of the parameter

Return variable and its type

It tells the name of the procedure and also the type of the call.

It will avoid all the run time problems like parameter mismatch by specifying the
prototype.
Prototype interface
It is like *entry parameter where we will specify the parameters that are received
in this program.
Import and export
If you want to specify the procedures to be the external programs then we can
specify EXPORT in your procedure.
Global and local variables
If you declare a variable in main procedure then it will be accessible in all sub
procedure and this is global declaration and if you specify the declaration in the sub
procedures then it will not be accessed in other procedures or in the main procedure.
Return
If we specify return in the sub procedure then it means that we are returning
something to the calling program. We can return a maximum of only one variable to the
calling program.
Recursion

A procedure calling to it self is known as recursion.


Pass by value/pass by reference

In case of pass by reference we are passing the address of the parameters and not
the actual value and so the changes in the called procedure will affect the value in the
calling program. In OPM program we are using only call by reference and in RPGLE we
have the option to pass the parameter by giving the keyword VALUE.
CALLP/Expression
We can call the procedure by using CALLP command if it is not having any return
type and by an expression if it returns any value.
93.How you can import and export a data type between 2 programs?
If you are using an export statement when declaring a variable then the data type can be
imported in any modules that is bind either by value or by reference. So in this case we can pass values
in between modules instead of using PLIST and *ENTRY.
94. Message subfile record format keywords?
SFLMSGRCD (subfile message record)
This keyword is used to give the line number to get the first message in the
display.
SFLMSGKEY (subfile message key)

- 96 -

Tips n Facts
This keyword is used to specify that the program message queue is built one at a
time.
SFLPGMQ (subfile program queue)
It is a message queue created for every program active in the call stack.
This keyword is used to specify the field that can have the name of the program
message queue.
95. How to create Message subfile?
Create message subfile
CRTMSGF MKSFILE/LIB
WRKMSGF FILE/ANME
OPTION 12
Add Message Description (ADDMSGD)
Type choices, press Enter.
Message identifier . . . . . . . MKS0001
Message file . . . . . . . . . . > MKSFILE
Library . . . . . . . . . . . >

Name
Name

SKANDASAMO Name, *LIBL, *CURLIB

First-level message text . . . . EMPLOYEE NUMBER &1 CANNOT BE ZEROS


PAGE DOWN
Message data fields formats:
Data type . . . . . . . . . .
Length . . . . . . . . . . . .

*CHAR

*NONE, *QTDCHAR, *CHAR...

10

Number, *VARY

WRKMSGF
MKS0001

EMPLOYEE NUMBER CANNOT BE ZEROS

MKS0002

EMPLOYEE &1 NUMBER AIREADY EXIST

MKS0003

EMPLOYEE NAME CANNOT BE BLANKS

MKS0004

ADDRESS(1) CANNOT BE BLANKS

MKS0005

CITY CANNOT BE BLANKS

MKS0006

MARITAL STATUS WILL BE WITH (M/S)

MKS0007

EMPLOYEE NUMBER &1 ADDED SUCCESFULLY

MKS0008

EMPLOYEE NUMBER DOES NOT EXISTS

MKS0009

EMPLOYEE UPDATED SUCCESSFULLY

MKS0010

EMPLOYEE NUMBERDELETE SUCCESFULLY

Create message subfile

10

MSGREC1

20

MSGCTL1

SFLMSG
SFLCTL

06/27/02
MSGREC1

USING 8 SELETION
Select Subfile Keywords
Subfile record . . . . . . . :

MSGREC1

Type choices, press Enter


Y=Yes
General keywords . . . . . . . .

Indicator keywords . . . . . . .

Message record . . . . . . . . .

- 97 -

06/27/02

Tips n Facts
TEXT keyword . . . . . . . . . .
Define Message Record
Subfile record . . . . . . . :

MSGREC1

Type choices, press Enter.


Keyword
Line number for first message . . . .
Message ID field . . . . . . . . . .

SFLMSGRCD

SFLMSGKEY

24

1-27

DUMMY

Name

(if program message queue is built


one message at a time)
Program message queue field . . . . .

SFLPGMQ

QUEUE

Generate a 276 byte field . . . . .

Name

Y=Yes

MESSAGE SUBFILE (SFTCTL)


Subfile control record . . . . . . . . . :

MSGCTL1

Type choices, press Enter.


Y=Yes
General keywords . . . . . . . .

Subfile display layout . . . . .

Subfile messages . . . . . . . .

Select record keywords . . . . .

TEXT keyword . . . . . . . . . .
Define General Keywords
Subfile control record . . . . . . . . . :
Type choices, press Enter.

MSGCTL1
Keyword

Related subfile record . . . . . . .

SFLCTL

Subfile cursor relative record . . .


Subfile mode . . . . . . . . . . . .

MSGREC1

SFLCSRRRN

Name

SFLMODE

Program message queue field . . . .

Name

SFLPGMQ

QUEUE

Generate a 276 byte field . . . .


Y=Yes

Indicators/+

SFLDSP

Display control record . . . . . . .

SFLDSPCTL

SFLINZ

SFLDLT

Clear subfile records . . . . . . .

SFLCLR
SFLEND

SFLEND parameter

........

*MORE

SFLEND parameter

........

*SCRBAR

Record not active . . . . . . . . .

Delete subfile area . . . . . . . .


Indicate more records . . . . . . .

SFLRNA
More...

F3=Exit

F12=Cancel
Select Record Keywords

Record . . . :

Name

Y=Yes

Display subfile records . . . . . .


Initialize subfile fields . . . . .

Name

MSGCTL1

Type choices, press Enter.

- 98 -

*MORE ...

Tips n Facts
Y=Yes
General keywords . . . . . . . .

Indicator keywords . . . . . . .

Overlay keywords . . . . . . . .

Select Overlay Keywords


Record . . . :

MSGCTL1

Type choices, press Enter.


Keyword
Overlay without erasing . . . . . .

Y=Yes Indicators/+

OVERLAY

Roll

Create CL program for SNDPGMMSG


SKANDASAMO/EMPCUSTOR
MSG

*************** Beginning of data *****************************


0001.00

PGM

PARM(&MSGID &MSGFI &MSGDTA)

0002.00

DCL

VAR(&MSGID) TYPE(*CHAR) LEN(7)

0003.00

DCL

VAR(&MSGFI) TYPE(*CHAR) LEN(7)

0004.00

DCL

VAR(&MSGDTA) TYPE(*CHAR) LEN(10)

0005.00

SNDPGMMSG MSGID(&MSGID) MSGF(&MSGFI) MSGDTA(&MSGDTA)

0006.00

ENDPGM

****************** End of data******************************

Create CL program for RMVMSG


SKANDASAMO/EMPCUSTOR
RMO

*************** Beginning of data *****************************


0001.00

RMVMSG

PGMQ(*PRV) CLEAR(*ALL)

****************** End of data *******************************

Design the screen

Generate RPG program

0000.01 FMESSTAB

IF A E

0001.00 FMKSSCR

CF

K DISK

WORKSTN

0001.01 C

MOVEL

MSTATUS

0002.02 C

MOVEL

'*'

0003.00 C

MOVEL

'MKSFILE'

0004.00 C

PL01

QUEUE
MSGFI

PLIST

0005.00 C

PARM

MSGID

0006.00 C

PARM

MSGFI

10

0007.00 C

PARM

0008.00 C

DOW

*IN03=*OFF

0008.01 C

MOVEL

ERROR

0008.02 C

MOVEL

ERROREMP

0012.00 C

WRITE

MSGCTL1

0013.00 C

EXFMT

MKSSEN

MSGDTA

- 99 -

10
10
10

Tips n Facts
0013.01 C

CALL

0014.00 C

IF

'RMO'

0014.01 C

MOVEL

ERROR

0014.02 C

MOVEL

ERROREMP

0015.00 C

MOVEL

'MKS0001'

0016.00 C

MOVEL

0017.00 C

CALL

0017.01 C

ENDIF

EMPNUMB=*ZEROS

*ZEROS
'MSG'

MSGID
MSGDTA
PL01

96.What is active subfile?

Subfile, which are in the main memory, are called as active sub files.

A maximum of 12 sub file can be active at a time.

97. Navigation between two screens?


SKANDASAMS/TABLES
EX21
*************** Beginning of data *****************************
0001.00 FEXDSPF
0002.00 C

CF

E
Z-ADD

WORKSTN
1

SCR1

0003.00 C

*IN03

DOWEQ

*OFF

0004.00 C

SCR1

DOWEQ

0005.00 C
0006.00 C

EXFMT
03

IF

0008.00 C

Z-ADD

0009.00 C

LEAVE

0010.00 C

ENDIF

0011.00 C

ENDDO
SCR1

0013.00 C
0014.00 C

*IN08=*ON

IF

0016.00 C

Z-ADD

0017.00 C

LEAVE

0018.00 C

ENDIF

0019.00 C

ENDDO
03

SCR1

DSPF2

LEAVE

0015.00 C

0020.00 C

DOWEQ
EXFMT

03

DSPF1

LEAVE

0007.00 C

0012.00 C

20

*IN07=*ON
1

SCR1

LEAVE

0021.00 C

ENDDO

0022.00 C

SETON

LR

****************** End of data *******************************


98. What is the different between READE and CHAIN opcodes?
READE
1.The matching records for table
2. We are using the looping concept

CHAIN
The first matching records only
Looping is not necessary

- 100 -

Tips n Facts
3.The indicator setin the EQ
4. We are most using in SETGT or SETLL

The indicator setin the HI


It is not necessary

99. Define indicator & MOVEA?


It is a 1-bit flag where value will be either 0 or 1 AS/400 provider 99 indicators for the business
user.

1-24 ->assigned functions keys

25-99 ->our own purpose

100. Define ITER / LEAVE/DO/Dow?


ITER-> Transfer the control before do loop.
LEAVE-> Transfer the control after do loop.
DOU Checks after entering the loop, it is performed at least once.
DOW Checks before entering into the loop.
101.CL commands?
1. WRKMBRPDM
2. CRTSRCPF
By using this command to create source physical file. Default PF size is 92.
3.DSPFD
It is used to display the details about the file when it is created.
4. DSPFFD
It is used for listing details about Individual Fields.
5.STRDFU
It is used to add Data into the records.
6.STRSDA
It is used to go into screen Designing or Menu Designing.
7.CRTMSGF
For creating the Message file
8.WRKMSGF
If you want to create or change or delete any message we can use this command.
9.CRTDTAARA
For creating The Data Area
10.DSPDTAARA
For listing the content of Data area.
11.CHGDATARA
For changing the content of Data area.
12.DSPLIBL
For listing the contents of library
13.ADDLIBLE
For Adding a library into the current library.
14.RMVLIBLE
For Removing a library into the current library.
15.CHGCURLIB

- 101 -

Tips n Facts
For changing the Current Library to a new library
16.EDTLIBL
It is used to the edit of the library file. (Change library file it is temporary delete the
library file)
For Adding or removing library lists.
17.SNDBRKMSG
Used for sending message to all user.
18.CRTPF
It is used to create a PF. Using this command we can set the maximum number of
records, whether delete or update operation is allowed or not, maximum storage allocation,
waiting time etc can be determined
19.CRTLF
To create the logical files.
20.STRRLU
To go into the RLU we are using this command. Default length of RLU is 132 if you give it
and creating it very first time else it set the page width value of last edited RLU. We can give the
page width value from 1 to 378 in page width option.
21.DSPSBS
It is used to list the various subsystems running under AS/400 environment. Various
subsystems running are QINTER, QACTIVE, and QBATCH etc.
22.CRTRPGPGM
It is used to create an RPG program. We can determine what sort of source file is
generated. For example when we need the entire source compile as it is since source is default. If
we give *NOSOURCE only syntax errors is generated NOSECLVL will not allows secondary
message where as other setting is allowed it and so on
23.CRTCLPGM
To create CL program
24.EDTOBJAUT
It is used to give authority to a particular source PF. For giving authority to other user
we must give authority to library, user profile and the source PF.
25.DSPOBJD
If we know library name and object name and we want to know the source PF where it is
residing then DSPOBJD with option as services instant of basic will give the source PF name.
It describes various object descriptions like created Date, Created by, Source Physical
file, which it is being created, and so on.
26.STRSQL
To start into SQL.
27.WRKSPLF
To work with Spool file
28.DLTSPLF
To delete the spool file
29.CRTDUPOBJ

- 102 -

Tips n Facts
By using this command to create duplicate object. If you want to compile a PF having
1000 of records and when we compile it all the data will be lost else if you want to add or delete
a attribute data for other fields will have to copied. For that we a duplicate object.
30.CPYF
Records are being copied from PF to temporary file and after compiling it we have to
again copy back from temporary file to the original file. If we Add a attribute we have to give
*map and if we want to delete a attribute we have to give *drop in the map entry field.
31.DLTF
After copying into the original file we have to delete the temporary file or if you want to
delete any file we are using this command. DLTF will only remove the object
32.RMVM
It is used to delete the member as well as the object.
33.RUNQRY
To display all the records in a PF.
34.CRTCMD
It is the powerful command used to create user define commands.

35.CMPPFM

It is used to compare two programs or files. It can be coded by taking option 54 in


Subfile screen.
36.MRGSRC
It is used to merge a file with another file. We have to mention three files one is the root
file, which is just a root and does not contain any code even. The second file is target file where
we can have the ready-made we can copy the target source.
37.RTVCLSRC
If you delete a CL Source then we can retain the source if you are having the object by
using this command.
38.SBMJOB
If you want to submit the job in certain interval i.e. on a specified date and time we can
use this command.
39.DSPJOB
It will display all the jobs.
40.DSPUSRPRF
It will display all the entries regarding the particular user profile. It displays information
like what is the user. Profile name; date previously, user class, printing and all.
41.CPYSRCF
If we want to copy all the members in a source PF to another source PF.
42.WRKACTJOB
To display the active jobs running in AS/400 systems.
43.DSPJOBLOG
By using this command display the output console.
44.SNDMSG
This command is to send the message to an user.
45.DSPMSG
This command is display all the message.
46.CHGCURLIB

- 103 -

Tips n Facts
Change the current library file.
47.ADDLIBLE
It is used to add the library. It is fully administrator authority.
48.RMVLIBLE
This command is to remove a library from the list.
49.CRTUSRPRF
It is used to display the rights given to a user. The system administrator can change
authority he can give the authority as a system administrator.
50.DSPDBR (data base relation)
This is used to list all the files, which are related to a PF. It displays all the LF that is
referring the PF and also lists the child table if it is having a relation through ADDPFCST.
51.DSPJOB
It will display all the jobs submitted within the specific interval and display the entire
user who worked on the system at that time
52.WRKMSGQ
It will list all the messages of different user in the job queue.
53.CPYSRCF
If we want to copy all the members in a source PF to another source PF we can use this
command.
54.CPYTODKT
If we want to copy from source PF to a diskette file
55.CPYTOTAP
If we want to copy source PF to a tape then we can use this command.
56.STRDBG
If we want to debug a ILE program then we can use this command .We have to create a
ILE program by compiling with 15 which is CRTRPGMOD command and take F10 give debugging
values as *Source. This will create a module. Then we have the create the program by giving
program name and module name as the same and if we are calling any other modules also in
that include that in the CRTPGM command
Ex: CRTPGM PGM (LIB/PNAME) MODULE (LIB/PNAME)
(LIB/SPNAME)
Now the program as well as the module is created. Then we have to start the debug by using the
command.
STRDBG PGM (LIB/PNAME) UPDPROD (*YES)
It will shoe the source code of the program and we have to press F6 set the break point and
press F10 key and call the program
CALL PNAME
F11-> display the variable
Shift + F11 -> go to module
102. Data types in CL?
Char, Logical, Numerical

- 104 -

Tips n Facts
103. String operation in CL?
*CAT ->Concatenate without editing.
*BCAT->Trailing blanks in the first character string are truncated. One blanks is inserted, then
the two character strings are concatenated. Any leading blanks of the second operand are not
truncated
*TCAT->All trailing blanks in the first character string are truncated, and then the two character
strings are concatenated. Any leading blanks of the second operand are not truncated.
SKANDASAMO/CLP
STRING
*************** Beginning of data ********************************
0000.01 /*STRING *CAT *BCAT *TCAT FUNCTION */
0001.00

PGM

PARM(&STR &STR1 &STR2 &STR3 &STR4)

0001.02

DCL

VAR(&STR) TYPE(*CHAR) LEN(15)

0001.03

DCL

VAR(&STR1) TYPE(*CHAR) LEN(15)

0001.04

DCL

VAR(&STR2) TYPE(*CHAR) LEN(15)

TYPE ()
*DEC

LEN ()

VALUE ()

Default (15 5)

Default (0)

Max (15 9)
*CHAR

Default (32)

Default (b)

*LGL

Default (0)

0001.05

DCL

VAR(&STR3) TYPE(*CHAR) LEN(15)

0001.06

DCL

VAR(&STR4) TYPE(*CHAR) LEN(40)

0001.07

CHGVAR

VAR(&STR2) VALUE(&STR *CAT &STR1)

0001.08

CHGVAR

VAR(&STR3) VALUE(&STR *BCAT &STR1)

0001.09

CHGVAR

VAR(&STR4) VALUE(&STR *TCAT &STR1)

0001.10

SNDMSG

MSG(&STR3) TOUSR(SKANDASAMY)

0001.11

SNDMSG

MSG(&STR4) TOUSR(SKANDASAMY)

0001.12

SNDMSG

MSG(&STR2) TOUSR(SKANDASAMY)

0006.00 ENDPGM
****************** End of data **********************************
run
call program name (string) f4
Program . . . . . . . . . . . . > STRING
Library . . . . . . . . . . . >

Name

SKANDASAMO Name, *LIBL, *CURLIB

Parameters . . . . . . . . . . . > SENTHIL


> kumar
> ''
> ''
+ for more values > ''
DSPMSG
104.

How to set the cursor position in particular field in particular position?

- 105 -

Tips n Facts
Using the curpos
105. How will retrieve the data in data area?
In retrieve a data area
Out-write a data area
106.Built in function in CL?

%SUBSTRING or %SST
The sub string built-in function produces a character string that is a subset of
an existing character string and can only be used with a CL program.
%SUBSTRING (Character-variable-name Starting-position length)
Or
%SST (Character-variable-name Starting-position length)

%SWITCH

106. Define indicator in CL?


We can set on or setoff the indicator by the command.
CHGVAR (&IN30) VALUE (0) ->setoff
CHGVAR (&IN30) VALUE (1)->seton
107. Message subfile in CL?
Subfile cannot be used in CL but we can use message subfiles in CL.
108. CL processing commands & program control commands?
PROCESSING -> CHGVAR, SNDPGMMSG, OVRDBF, AND DLTF.
PROGRAM CONTROL ->CALL, RETURN, TFRCTL
109. How to CL code has to change to use a call procedure?
By using CALLPRC command. This is the bound call in CL that calls a procedure within a
module.
110. Figurative constants in RPGLE?
*HIVAL, *LOVAL, *ZERO, *ZEROS, *BLANKS, SETLL, SETGT.
111. Rename of fields and prefix?
112. How you will avoid multiple users updating the same records?
The displaying the records in the screen we will be getting the timestamp along with the
actual data. Store this in output data structure and while updating check weather the previous time
stamp is the same timestamp before updating. If the record is updated by another user than the time
stamp will be changed and if it does not matches then throw the error message Record is already
updated by another user else update the records with current time stamp.
Program 1
Store the time stamp and this time stamp will come as a input to the second program
Program2

Here wstmst1 contains the input time stamp and check this matches with the database. If

matches Update else send error message.


113.Define binder program?
The binder program means binding the procedure it is called binder program.
114.question details?
DEFAULT CL MSGID?

CPF0000
Dspf windows type?
WINDOW

- 106 -

Tips n Facts

How many key define in logical file?

All the PF fields are create in key.


What is the level check error?

The level check error means RPGLE program is compiled and PF or LF are
compile suppose the PF or LF compile after the compiling the RPGLE program this type
of error is called level check error.
If you want to copy a PF without making any modification to it then FORMAT
keyword is used.

Default access path maintenance is *IMMED

Maximum no of printer files included in a RPGLE program is 8

Maximum no of files declared in RPGLE is 50 and CL is l

Maximum no of key fields included is 120

Maximum no of fields included in a PF is 8000

Maximum no of arrays included is a RPG is 200

Maximum no of parameter passed in a RPG is 255 and CL 40

Total no of system library is 15 and user library is 25

While logging on the first library to be included is QSYS

QGPH and QTEMP are user library

Printer file default length is 132.

Default size of a member is CRTSRCPF command for ordinary files is 92.

115. What's the difference between CHAIN and SETLL? Is there a performance
advantage?
There are two important differences between CHAIN and SETLL.
1.

The CHAIN operation applies a record lock to files that are open or update. The SETLL operation
does not apply the lock.

2.

The CHAIN operation copies the record's data to the input buffer for the program. The SETLL
operation does not.

More Details
The CHAIN operation performs a random GET operation to the database file. If the operation is
successful, the data in the record is copied to the input buffer. If the CHAIN operation fails, a record-notfound condition is signaled, typically via Resulting Indicator 1. If the database file has been opened for
UPDATE, the CHAIN operation places a record lock on the retrieved record. No other application can access
this record for update while this lock is applied. Furthermore, if another program has issued a lock to the
recording being accessed, the CHAIN operation will wait for the database time-out period. If the record is
released during that period, the CHAIN operation continues. If the other program does not release the
record, the CHAIN operation fails with an exception.
CHAIN with NO LOCK
The CHAIN operation supports the NO LOCK operation extender (the old "half-adjust" column). In
RPG III you specify an N in the operation extender column, in RPG IV, you specify CHAIN (n) for the
operation code. Using NO LOCK allows you to access a record without a record lock being applied,
regardless of the way in which the file is open. The record's data, however, is still copied to the input
buffer when NO LOCK is specified.

- 107 -

Tips n Facts
The SETLL operation performs a quasi READ LESS THAN OR EQUAL operation. If the operation is
successful, a READ PRIOR is performed. The database record's data, however, is not copied to the input
buffer, nor is there a record lock applied to the accessed record. Hence, SETLL is probably the operation
code to use for testing the existence of a record. However, if the record needs to be retrieved, CHAIN
more effective.
Performance
If your requirement is to check for the existence of a record, traditionally the CHAIN operation is
used. However, since CHAIN copies the record's data to your program's input buffer, there is additional
overhead required for the CHAIN operation. The SETLL can be used to effectively accomplish the same
task as the CHAIN test. Use SETLL with resulting indicator 3 (equal). If this indicator is set on, a record
exists whose key matches they value specified in Factor 1. If your requirement is that the record
eventually be updated, subsequent to the existents test, you should consider using of CHAIN.
116. How do I debug a remote (i.e. "batch") job from an interactive job?
The ability to debug another job has been a long-standing requirement for AS/400, now iSeries
programmers. It isn't as difficult as it may seem. Whether you need to debug a batch job, another
interactive job, or an HTTP server job (browser/CGI program), the following steps can get you started.
Starting Debug for a Remote Job
1.

2.

Determine the job name of number for the job you need to debug.

Use WRKACTJOB and note the Job name, number and user profile ID.

If debugging a CGI program, look in the job log of the job for CPF message HTP2001.

Run the Start Service Job (STRSRVJOB) command specifying the job to be debugged

3.

Run Start Debug (STRDBG) on the program to be debugged

4.

E.g., STRSRVJOB JOB (012345/usrid/jobname)

E.g., STRDBG PGM (libnam/pgmname) UPDPROD(*YES | *NO)

At this point the program in the remote job is under debug control from your job

You can now set break points (if you're debugging an RPG IV program, the source will
have already been displayed).

Press F12 from within the debugger to return to CMD entry after setting your break
points.

5.

Evoke the program in the remote job. If you you're doing a web browser session, hit the SUBMIT
button.

6.

You interactive job will "break" at the debug break points and you can debug application
normally.

Ending Debug for a Remote Job


Ending the debug session should be done in the following sequence.

- 108 -

Tips n Facts
1.

From your debugging session, run the End Debug (ENDDBG) command

2.

Then run the (End Service Job) ENDSRVJOB command

Your session is no longer controlling the remote job. The remote job continues normally.
Special Considerations when Debugging a Web Browser/CGI Program
To debug a CGI program that is evoked from a Web Browser session running from the standard IBM HTTP
Web Server, you need to do the following in addition to the above.
Before Starting Debug for a Web Browser/CGI Session/Program

End the HTTP Server using the following CL command:

ENDTCPSVR *HTTP

WARNING!!! -- You MUST include *HTTP as the parameter for ENDTCPSVR otherwise all
TCP/IP server jobs (including telnet, ftp, smtp, etc.) will be ended. And this is a bad
thing. IBM sucks for making *ALL the default for ENDTCPSVR.

Restart the HTTP Server using the following CL command:

STRTCPSVR *HTTP HTTPSVR(DEFAULT '-minat 1 -maxat 1')

This restarts the HTTP server with once instance of each job type (one for CGI, one for
Java, etc.)

Using WRKACTJOB in the QHTTPSVR subsystem location the jobs running.

The job whose joblog contains the CPF message HTP2001 is the one to be debugged.

After Finishing the Debug Session

End the HTTP server using the following CL command:

ENDTCPSVR *HTTP

Restart the HTTP server using the following CL command, unless your shop has another process
for starting the HTTP server:

STRTCPSVR *HTTP

Your system should be back to normal.


117. What is the new E operation extender used for?
The new (E) operation extender is used to cause the %ERROR and %STATUS
built-in functions to be initialized after an operation is performed. That is, these built-in
functions and the E operation extender are used in place of Resulting Indicator 2 on all
operation codes that currently support Resulting Indicator 2 as an error condition.
For example, to check to see if a record is locked, you would code the following:
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq
C

CustNO

Chain(E) CustMast

- 109 -

Tips n Facts
C

if

Select

When

exsr

When

exsr

endSL

ELSE

if

exsr

endif

endif

%ERROR = *ON
%STATUS = 1221
UpdateNoRead
%STATUS = 1218
RecdLocked

%FOUND( CustMast )
whatever...

The concept is to first check %ERROR for a generalized error condition, and then check %STATUS
for the specific error. Note that no resulting indicators are used in the previous example. The normal notfound condition is checked using the %FOUND built-in function rather than testing Resulting Indicator 1.
118. Why doesn't the %CHAR built-in function work with numeric values?
Under the initial release of OS/400 Version 4, Release 2, the %CHAR built-in function was
introduced. However, the function, as designed, only converted DATE values to character values. This
proved to be too restrictive a use for this function. In the next release of OS/400 (V4R4) IBM will add
function to %CHAR allowing it to convert all forms of non-character data to character. In that release
%CHAR will function with numeric values.
D Amount
C

7P 2 Inz(123.45)
Eval

text = 'The amount is: ' + %Char(


amount )

The TEXT field would contain the following after the EVAL operation is performed:
'The amount is: 123.45'
Unlike %EDITC, the %CHAR built-in function trims off leading blanks. However, %EDITC provides
much more editing power than %CHAR. Use %CHAR for basic number to character conversion.
119. What's new in V4R4 and RPG IV?
There are a few significant enhancements in RPG IV in OS/400 Version 4, Release 4.
The %CHAR built-in function has be fixed. It now functions like it was supposed to in
the first place. You can wrap a numeric value in %CHAR and a nicely edited character form of the
number is returned. The edited form includes the decimal, trimmed off leading blanks, and a
negative sign.
The FOR loop provides a free-format version of the DO operation code. With the FOR
operation, you can begin a loop operation and continue iterating through the loop until a variable
equals a limit value. The syntax for the FOR operation is enhanced with the TO, BY and DOWNTO
keywords. The TO operation indicators the upper limit for the looping, while the BY keyword

- 110 -

Tips n Facts
identifies the increment value for the loop counter. Alternatively, you can specify the DOWNTO
keyword to loop backwards from a large value to a small value.
The OPENOPT keyword is added to the Header specification. This keyword can be used
along with its one and only keyword *INZOFL to cause overflow indicators to be set off when
their corresponding printer file is closed and then re-opened during the program.
In subroutines, the LEAVESR operation can now be used to exit a subroutine
immediately. Effectively this is a "glorified goto" operation that branches to the ENDSR statement
of a subroutine.
120. How does the CONST keyword work with Procedure parameters?
If you are certain that the called procedure will NOT modify a parameter, the CONST keyword can
provide several benefits.
1.

It automatically converts a field of a similar data type, to the length and type required by the
parameter.
What this means, is say a parameter is a 15 position pack field, with 5 decimals.

Normally, you'd have to specify a Pdk(15,5) field for the parameter. However, if the
parameter is read-only, you can specify CONST on the Prototype and Procedure Interface for
the parameter. When you do this, the compiler automatically converts the value (say it's a
literal of 27) to the size and type required by the parameter. This works really cool with DATE
fields. A date for any format can be passed as a parameter value when that parameter value
is CONST.
2.

Performance is improved because the compiler can generate more optimized code for the CONST
parameter.
CONST can be used on calls to procedures or programs. We use it all the time when calling

QCMDEXC from within RPG IV. All three parameters of the QCMDEXC program are CONST values. The
example code below can be used as the PROTOTYPE to call QCMDEXC from within RPG IV. To call it
using this prototype, specify something like: CALLP run('addlible myLib' 14) in your calculation
specs.
.....DName+++++++++++EUDS.......Length+TDc.Functions++++++++++++++
D Run
D cmdstr
D cmdlen
D cmdDbcs

PR

ExtPgm('QCMDEXC')
3000A

Const Options(*VarSize)

15P 5 Const
3A

Const Options(*NOPASS)

Note: if you're using CodeStudio or IBM's Code/400 as your RPG IV editor under Windows, you could
simply highlight the above source code within your Internet Browser, and copy it to the Windows
clipboard. Then activate CodeStudio (or Code/400) and use the Paste function to insert the code directly
into the editor. Pretty cool, huh? <g>

- 111 -

Tips n Facts
121. Can you clear up the confusion in the different releases of RPG IV and OS/400
and ILE?
RPG IV is the next generation of the RPG language. RPG III is the original version of AS/400
RPG/400. The name "AS/400 RPG/400" is that given to the IBM compiler package for distribution on the
AS/400. This compiler package compiles various versions of RPG, including RPGII and at least two
releases of RPGIII.
As of OS/400 Version 3 release 1, IBM changed the name of this compiler package to "AS/400
ILE RPG/400". The reason for this name change was to identify that fact that the compile now includes a
version of RPG that targets the Integrated Language Environment (ILE), that is RPG IV.
ILE was first shipped in OS/400 Version 2, Release 3. However, only the C language compiler
produced code that targeted this environment. First, a word about ILE.
ILE is the new, "native" runtime environment for Programs, on the AS/400. Under OS/400
Version 2 Release 3, IBM introduced a new program model. This basically means that new features and
interfaces became available. However, IBM did not just port some runtime environment to the OS/400
operating system, it actually re-wrote code, and wrote new code that, essentially, changed the way
OS/400 works. This new code provides support for a mixed set of high-level languages.
Previously, RPG and CL had their own little runtime environment, COBOL had it's own, C had it's
own, and so on. Under ILE, all programming languages run in ILE. The same "environment" is used for
COBOL, C, RPG and CL.
However, to take advantage of ILE, new compilers needed to be created. As for RPG, rather than
convert the existing RPGII and RPGIII compilers, IBM, who was designing a new version of RPG anyway,
decided to target ILE with the new compiler. This would simultaneously provide a new version of RPG and
an ILE targeted compiler.
Names Are Important
A good friend of mine once said, "names are important" in the programming world. If a field is
called "Rhinoceros", does it represent its use or purpose? Okay, so perhaps in traditional RPG "Iguana" is a
better choice for this example. (Shorter name.)
During the development of RPG IV, two distinct issues arose. First, the internal name for RPG IV,
was "ILE RPG". This was not a code name, but rather the name IBM used to refer to the new compiler.
After all, it was targeting ILE, why not refer to it as "ILE RPG"? Second, the re-architecture of RPG came
into question.
Unfortunately, the internal name "ILE RPG" began to be leaked out to the public. Several
magazine writers and IBMers not involved in the development of RPG IV continued to use the term "ILE
RPG" when referring to RPG IV. I suppose these people still refer to the AS/400 as SilverLake or perhaps
even Olympic.
Then when IBM announced the compiler package or product name as "AS/400 ILE RPG/400" it
only added to the confusion. IBM dropped the ball when promoting the RPG IV name. They are, after all,
set up to market their products with their product names. The name of one programming language
included in a product that contains nearly seven full compilers isn't high priority.

- 112 -

Tips n Facts
RPG IV is the version of RPG that targets ILE. OS/400 V3R1 compatible RPG IV can also target what is
now called "the original program model" or simply OPM. OPM is just a name that has been given to the
original runtime environment of RPG and CL under OS/400. This is the environment in which RPGIII and
CL run. Under ILE, however, the original native environment is emulated, that is, ILE isn't an environment
at all, it is native OS/400, whereas, OPM is now an environment under ILE. Some very clever
programming and design went into this, don't you think? Not very many other operating systems, if any,
provide this kind of continuity.
RPG IV -- Release what?
RPG IV was first shipped with OS/400 Version 3, Release 1. This is now referred to as RPG IV
release 1. But don't worry about remembering releases of RPG IV.
Under

OS/400 Version 3, Release 6, IBM enhanced RPG with procedures, many more built-in

functions, and several new data types. This is referred to as RPG IV release 2.
Then, OS/400 Version 3, Release 2 was announced. It brought the original release of RPG IV (on
the CISC boxes) up to the same level as RPG IV under V3R6. Are you confused yet? Me too!
Under OS/400 Version 3, Release 7, IBM added a couple of enhancements, most notably they
increased the length of a field name to a number so large not even magazine authors that don't write realworld code could complain about it anymore. They also added one or two new data types, rounding out
RPG IV so that it supports all AS/400 data types, except variable length fields. This version of RPG IV is
known as RPG IV Release 3.
The following table identifies the current releases of RPG IV. Note that RPG IV releases do not
necessarily coincide with releases of the operating system.
RPG

IV

OS/400 Version/Release

CISC or RISC

Release
1

V3 R1

CISC

V3 R6

V3 R2

V3 R7

RISC

V4 R2

RISC

V3

RISC
CISC

R5

(speculation)

CISC

See note 1
5

V4 R3

RISC

V4 R4 (February 1999)

RISC

- 113 -

Tips n Facts
6

V4 R5 (Summer 2000)

RISC

NOTE 1: It is speculated that IBM may ship a final "clean up" release of OS/400 for CISC that would
included a large level of compatibility with OS/400 V4 R5.
The release levels of RPG IV are only important if you want to keep track of that kind of thing.
One disappointing issue is that unless you stay on the most current release of OS/400, you don't get all
the cool new features in RPG IV. Even if you stay current, you can't target prior releases if you use any of
the new features. In fact, even if you use a new feature that doesn't depend on an operating system
enhancement, it can't be used for back releases. This is because of the way the TGTRLS (target release)
feature has been implemented. Basically, if you're on V4 R2 and you do a TGTRLS(V3R2M0) the compiler
calls the actual compiler for V3 R2. It doesn't have a built-in syntax checker that says "This feature
requires an OS/400 upgrade so don't allow it, or this one is okay so accept it." It iscalling the same
"binary" compiler code that is on any old V3 R2 system. Which means, for example, that if you want to
take advantage of the new compiler directives, but you often have to target a prior release, you can't use
those directives. For example, /IF DEFINED does nothing for the executable code that's generated, but is
not supported when TGTRLS(V3R2M0) is specified. ;( Bummer!)
So now we know about RPG IV release levels and how the term "ILE RPG" got into our
vocabulary. So let's clear up another term, the name of the RPG language. The big one is the term
"RPG/400". There is not programming language called "RPG/400". The language most often called
"RPG/400" is RPGIII. However, back in the System/38 days, the System/38 RPG language was called
RPGIII. When the AS/400 was announced, programmers wanted to give themselves an advantage on their
rsum. So they began calling AS/400 RPGIII, "RPG/400". Then to make matter worse, when RPG IV was
announced, programmers thought that the number "IV" in "RPG IV" was less than the "400" in "RPG/400".
So they decided to call RPG IV, "ILE RPG". Well let's set the record straight. The table below lists the RPG
language names, their incorrect name, and the proper name.
Commonly

used

Formal Name

Proper (correct) Name

RPG/36

System/36-compatible RPGII

RPGII

RPG/38

System/38-compatible RPGIII

RPGIII

RPG/400

RPGIII

RPGIII

ILE RPG

RPG IV

RPG IV

Wrong Name

122. How do I declare an array with a dynamic number of elements?


In RPG IV, the new (V3 R7) ALLOC, REALLOC and DEALLOC operation codes can be used to
allocate memory. This means that at run time, you can go out to the system and ask it to assign storage
to the program that was not allocated to the program when it was evoked.
These operation codes can be used to allocate memory up to 16MB. The allocation can be assigned to a
pointer variable. In RPG IV, pointers have the data-type of asterisk (*). All that is needed is to allocate

- 114 -

Tips n Facts
memory to a pointer that is used with the BASED keyword of the desired dynamic array. The example that
follows illustrates this technique:
.....DName+++++++++++EUDS.......Length+TDc.Functions++++++++++++++++++
D DynoArr
D nSize

7P 0 Dim(10000) based( pDynoArr)

10i 0

.....CSRn01..............OpCode(ex)Extended-factor2++++++++++++++++++
C

Eval

nsize = %size(DinoArr) * 64

.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq
C

Alloc

nSize

pDynoArr

** We now have enough storage allocated for 64 elements.

Eval

ReAlloc

nsize = %size(DinoArr) * 70
nSize

pDynoArr

** We have changed the allocation to enough storage for 70 elements


C* ... code to use the array goes here...
C

Dealloc(N)

pDynoArr

** We have just returned the storage to the system.


To increase or decrease the number of elements in the dynamic array, use the REALLOC operation
code. Simply change the number of bytes that need to be allocated, and call REALLOC with the new size in
Factor 2 and the original pointer variable in the Result field. REALLOC allocates new storage of the size
specified, and copies the original data to that new location. Then it frees ("deallocates") the original
storage.
IMPORTANT: Always remember to DEALLOC anything you ALLOC. That is always free up memory
that you have allocated otherwise memory leaks will be created.
If you are not on V3 R7, you can still use dynamic memory by calling one of the system APIs or
linking into the QC2LE binding directory and calling the C runtime MALLOC and DEALLOC functions.

123. RPG IV - Built-in Functions


The original release of RPG IV included a set of built-in functions. These built-in functions were:
%ADDR, %PADDR, %SIZE, %ELEM, %SUBST, %TRIM, %TRIML, %TRIMR
In addition, under OS/400 V3R2 and V3R7 the %PARMS built-in function was introduced. Since then,
several built-in functions have been added to RPG IV. The following table provides the OS/400 Version and
Release that the specific built-in functions were introduced and/or enhanced.
NOTE: IBM Seems to skip-ship the RPG IV compiler. So RPG IV in V4R1, V4R3 and V4R5 have no new
functionality. The next scheduled upgrade is OS/400 V5R1 in Spring 2001.

Version

Built-in Function

Parameters

- 115 -

Return Value Description

Tips n Facts
Release
V3R7

%ABS

numeric expression

Absolute value of expression

%ADDR

variable name

Address of variable

V5R1

%ALLOC

memory size

Pointer to the allocated storage.

V4R2
V4R4

%CHAR

graphic,
date,
time,
timestamp, or numeric
expression

Value in character data type

V5R1

%CHECK

compare-value : datato-search { : startposition }

First position in the searched-data that


contains a character not in the list of
the characters in the compare value.

V5R1

%CHECKR

compare-value : datato-search { : startposition }

Last position in the searched-data that


contains a character not in the list of
the characters in the compare value.
(Search begins with the right-most
character and proceeds to the left.

V5R1

%DATE

{ value { : date-formatcode }

A date data-type value after converting


the "value" to the specified date format.
If no value is specified, the current
system date is returned.

V5R1

%DAYS

days

A duration value that can be used in an


expression to add a number of days to a
date value.

V3R7

%DEC

numeric
expression
{:digits : decpos}

Value in packed numeric format. If


digits and decpos are specified the
result value is formatted to fit in a
variable of the number of digits
specified.

V3R7

%DECH

numeric expression
digits : decpos

Half-adjusted value in packed numeric


format. The
length
and
decimal
positions

V3R7

%DECPOS

numeric expression

Number of decimal digits.

V5R1

%DIFF

start-date : end-date :
duration-code

Calculates the difference between two


date fields. The type of difference
returned is specified by the durationcode.

V4R4

%DIV

Numerator
Denominator

Performs integer division and returns


the quotient (result) of that division
operation.

V3R7

%EDITC

non-float
numeric
expression : edit code
{:*CURSYM | *ASTFILL
| currency symbol}

String representing edited value.

V3R7

%EDITFLT

numeric expression

Character
external
representation of float.

- 116 -

display

Tips n Facts
V3R7

%EDITW

non-float
numeric
expression : edit word

String representing edited value

%ELEM

array, table, or multiple


occurrence
data
structure name

Number of elements or occurrences

V4R2

%EOF

{file name}

'1' if the most recent file input operation


or write to a subfile (for a particular file,
if specified) | ended in an end-of-file or
|
beginning-of-file
condition
'0'
otherwise.

V4R2

%EQUAL

{file name}

'1' if the most recent SETLL (for a


particular file, if specified) or LOOKUP
operation found an exact match '0'
otherwise.

V4R2

%ERROR

V3R7

%FLOAT

numeric expression

Value in float format.

V4R2

%FOUND

{file name}

'1' if the most recent relevant operation


(for a particular file, if specified) found a
record (CHAIN, DELETE, SETGT, SETLL),
an element (LOOKUP), or a match
(CHECK, CHECKR, SCAN) '0' otherwise.

V4R4

%GRAPHIC

Any character value

Converts character data to double-byte


character set value.

V5R1

%HOURS

hours

A duration value that can be used in an


expression to add a number of hours to
a time value.

V3R7

%INT

numeric expression

Value in integer format

V3R7

%INTH

numeric expression

Half-adjusted value in integer format

V3R7

%LEN

any expression

'1' if the most recent operation code


with extender 'E' specified resulted in an
error '0' otherwise.

1.

Returns the length of a variable


or literal value, or the current
length of a varying length field.

2.

When used on the left side of


the equal sign, sets the length
of a varying length field.

V5R1

%LOOKUPxx

search-data : array { :
start-index { : elements
to search }}

An array index of the element in the


array where the search-data is located.

V5R1

%TLOOKUPxx

search-data : searchedtable { : alternatetable }

*ON if the search is successful,


otherwise *OFF. (NOTE: The indexes of
the searched-table and alternate-table
are set to the index of the search-data if
*ON is returned.)

- 117 -

Tips n Facts
V5R1

%MINUTES

minutes

A duration value that can be used in an


expression to add a number of minutes
to a time value.

V5R1

%MONTHS

months

A duration value that can be used in an


expression to add a number of months
to a date value.

V5R1

%MSECONDS

milliseconds

A duration value that can be used in an


expression to add a number of
milliseconds to a time value.

V3R7

%NULLIND

null-capable field name

Value in indicator format representing


the null indicator setting for the nullcapable field.

V5R1

%OCCUR

data-structure

The current occurrence of the data


structure, or sets the current occurrence
of the data structure

V4R2

%OPEN

file name

'1' if the specified file is open '0' if the


specified file is closed. Consider this
built-in to be an 'Is this file open?"
operation.

%PADDR

procedure name

Address of procedure

V3R2
V3R6

%PARMS

V5R1

%REALLOC

pointer : new-size

V4R4

%REM

Numerator
Denominator

Performs integer division and returns


the remainder from the division
operation.

V4R2

%REPLACE

replacement
string:
source
string
{:start
position {:source length
to replace}}

String
produced
by
inserting
replacement string into source string,
starting at start position and replacing
the specified number of characters.

V3R7

%SCAN

search argument : string


to be searched {:start
position}

First position of search argument in


string or zero, if not found.

V5R1

%SECONDS

seconds

A duration value that can be used in an


expression to add a number of seconds
to a time value.

V5R1

%SHTDN

%SIZE

Number of
procedure

parameters

passed

to

Pointer to the allocated storage.

*ON if the job is being shut down (e.g.,


when the PWRDWNSYS command is
issued) otherwise *OFF is returned.
variable, data structure,
array, or literal {: *ALL}

- 118 -

Number of bytes used by variable or


literal. *ALL returns the number of
bytes used by all the elements of the
array, or all the occurrences of the data
structure.

Tips n Facts
V5R1

%SQRT

expression or value

The square root of the expression or


value.

V4R2

%STATUS

{file name}

0 if no program or file error occurred


since the most recent operation code
with extender 'E' specified most recent
value set for any program or file status,
if an error occurred if a file is specified,
the value returned is the most recent
status for that file.

V3R7

%STR

pointer{:maximum
length}

Characters
addressed
by
pointer
argument up to but not including the
first x'00'.

V5R1

%SUBDT

date : duration-code

The extracted component of the date


value. (The functional equivalent of the
EXTRCT operation code.)

%SUBST

string:start{:length}

Substring value. If length is not


specified, the substring begins with
start and continues through the end of
the string.

V5R1

%THIS

Used for Java integration. Returns an


Object reference.

V5R1

%TIME

{ value { : time-formatcode }

A time data-type value after converting


the "value" to the specified time format.
If no value is specified, the current
system time is returned.

V5R1

%TIMESTAMP

{value { : *ISO | *ISO0


}

A timestamp data-type value with or


without separators.

%TRIM

string

String with left and


trimmed (removed)

%TRIML

string

String with left blanks trimmed

%TRIMR

string

String with right blanks trimmed

V4R4

%UCS2

Any character value

Returns a varying length value.

V4R2

%UNS

numeric expression

Value in unsigned format

V4R2

%UNSH

numeric expression

Half-adjusted value in unsigned format

V5R1

%XLATE

from-table : to-table :
string-to-convert
{ :
starting-position }

The converted string is returned.

V4R4

%XFOOT

Array name

Cross foots (totals) all the elements in


an array.

right

blanks

WRKOBJPDM
If we want to list all the source physical file or files of a particular type the
Wrkobjpdm with file type as pf-src for source physical file ior *file for listing all the files etc can be given
DSPOBJD

- 119 -

Tips n Facts
If we know library name and object name and we want to know the source physical file where it is residing
then dspobjd with option as services instead of basic will give the source physical file name
WRKACTJOB
To display the active jobs running in as/400 systems
RTVMSG
If you want to retrieve the text message from message files and move it to a temporary variable we can
make use of this command
Ex
PGM
DCL
VAR(&MSGVAL) TYPE(*CHAR) LEN(100)
DCL
VAR(&MSGFI) TYPE(*CHAR) LEN(10) +
VALUE(SHYAMFILE)
DCL
VAR(&MSGID) TYPE(*CHAR) LEN(7) +
VALUE(MSG0002)
DCL
VAR(&MSGDTA) TYPE(*CHAR) LEN(3)
CHGVAR
VAR(&MSGDTA) VALUE(5)
RTVMSG
MSGID(&MSGID) MSGF(&MSGFI) MSGDTA(&MS
MSG(&MSGVAL)
SNDMSG
MSG(&MSGVAL) TOUSR(SHYAMR)
ENDPGM
This will retrieve the message whose message id is msg0002 and message file is shyam file and msgdta is
the value passed and here it is 5
CPYSRCF
If we want to copy all the members in a source physical file to another source physical file we can use this
command
CPYTODKT
If we want to copy from source physical file to a diskette file
CPYTOTAP
If we want to copy a source physical file to a tape then we can use this command
STRDBG
If we want to debug a ILE program then we can use this command. We have to create a ile program by
compiling with 15 which is CRTRPGMOD command and give debugging values as *source .This will create
a module. Then we have the create the program by giving program name and module name as the same
and if we are calling any other modules also in that include that in the crtpgm command
EX: CRTPGM PGM(SHYAMRLIB/ZP1263) MODULE(SHYAMRLIB/ZP1263 SHYAMRLIB/ZR3002)
Now the program as well as the module is created .Then we have to start the debug by using the
command
STRDBG PGM(SHYAMRLIB/ZP1263) UPDPROD(*YES)
It will show the source code of the program and we have to press F10 key and call the program
Call pgm(zp1263)
And it will move to debug mode and we can watch the flow of the program.
When we start the debug and when the source is not available then there is some problem in the creation
of the program
ENDDBG
After the debugging is over we have to end it by using this command
DSPDBR
This is used to list all the files which are related to a physical file. It displays all the logical files that are
referring the physical files and also list the child table if it is having a relation through ADDPFCST
CopyBook in ile
It will copy a subroutine or any group of codes physically into the program which is copying it.
C
DSPLY
A
50
C
EXSR
ADD
C
SETON
LR
C/COPY TESTSHYAM,SUBRTN

- 120 -

Tips n Facts
C
C
C
C

ADD
A

BEGSR
ADD
3
DSPLY
ENDSR

In the above program we are copying a subroutine called SUBRTN residing in the source physical file
TESTSHYAM.The subroutine SUBRTN called can be of any type even text and no need to compile this
program. In the above example the object will be created with code present in both the programs.
Normally a copy book will be presented after seton lr statement if you are using it as a subroutine but if
you are just including a piece of code or initializing some statements then it can be used in between the
programs either in d spec or c spec or even fspec depends on the application. In other words we can
create 3 programs having F SPEC,D SPEC and C SPEC and just use 3 copy books like below
F/COPY TESTSHYAM,FILEDEF
D/COPY TESTSHYAM,DDEF
C/COPY TESTSHYAM/CDEF
TEST
Test is the most powerful opcode which will check a date is a valid or not. The low level indicator is set on
if the date is not valid or set off if the date is a valid one.
Test will be given with extended factor like test(d),test(t), Test(z) for date, time and time stamp and if
test without extended factor defaults to date(z).
Factor 1 will be date format or time format. If it is blank it will take the value from
H-spec and no Hspec then default format is *iso .
Factor 2 is blanks and result contains the data to be tested
datfmt(*dmy)
movel
'13/03/1999' a
8
test(d)
a
30
*in30
dsply
seton
lr
In the above example the date format is *dmy and 30 will set to off
give *mdy then it is an error.

(valid date) .If in the H-Spec if we

DUMP
Dump is a opcode in RPG which is used to force to produce a dump if any error occurs. It is used in
program status data structure or file information data structure and it is used for a user to see if any error
occurs in the system. We have to specify debug(*yes) in h-spec to make a dump
HDEBUG(*YES)
dpssr
sds
DSTATUS
*STATUS
DROUTINE
*ROUTINE
DPARMS
*PARMS
dRES
S
2S 0
C
Z-ADD
1
NUM1
C
Z-ADD
0
NUM2
C
EVAL
RES=NUM1/NUM2
C
'NOTCOM'
DSPLY
C
A
TAG
C
'COMING'
DSPLY
C
SETON
C
*PSSR
BEGSR
C
STATUS
DSPLY
C
ROUTINE
DSPLY
C
PARMS
DSPLY
C
DUMP
C
GOTO
A
C
ENDSR

20
20

LR

In the above example divide by zero exception is caused and the control will be
transferred to *pssr routine where it is making the dump and move the control to tag a. This program also
illustrate the usage of parms status, routine keywords in program status data structures
Pre runtime array:

- 121 -

Tips n Facts
In case of compile time array the elements of the array will be loaded before the execution of the
programs. The value will be static in this case.
In case of runtime array the value will be loaded during the runtime only and this is dynamic
Pre runtime array is in between these 2 conditions where the values are static and the value will be
retrieved from the disk and loaded into the array. As a result there is no need to retrieve the value every
time from the disk and usage of pre runtime array makes it fast.
Example of pre runtime array
FPF02
IT F 80
DISK
Here T will represents that this is a pre runtime array and F for representing it as a program described file
and 80 is the size of the file.
DARR1
S
15 0 DIM(100) FROMFILE(PF02) PERRCD(4)
Here the from file size is 80 and since perrcd is 4 and length is 15 the from file will have elements like this
element1element2element3element4+20 free space
Like this there are 100 elements are stored in the array.
We can specify to file location if you want to copy the content of the from file and this is optional
FPF02
IT
Fwsdatapf o
DARR1
d
DI
C
1
C
ARR1(I)
C
C
C

80
F 80
S

DISK
DISK
15a DIM(100) FROMFILE(PF02) PERRCD(1)
tofile(wsdatapf)
S
2S 0 INZ(1)
DO
10
DSPLY
ADD
1
I
ENDDO
SETON
LR

This will load first 100 records into the file and display only the first 10 records
Build in functions in ILE
%SUBST(String name:starting position:length)
%abs(-32.32)= Absolute value by omitting the sign
%editc(string:X)
In a application if we want to concatenate a string with a numeric then we can use this editc
da
s
5a INZ('SHYAM')
db
s
5s 0 INZ(20)
dc
s
5a INZ('SUNDA')
dd
s
5s 0 INZ(12)
de
s
5a INZ('RAMBA')
dout
s
25a
c
eval
out=a+ %editc(b:'X') +c+%editc(d:'X')+e
c
out
dsply
%REPLACE: %replace(replacing string,actual string,starting position,offset)
Here we are replacing shyamsundar from position 1to 5 by sam. The output will be
sam sundar.
DC
S
12A INZ('SHYAMSUNDAR')
C
EVAL
C=%REPLACE('SAM ':C:1:5)
If we are not giving starting position then the result will be samamsundar.
If we are giving starting position as 3 then the output will be shsamsundar.
If we are giving EVAL
C=%REPLACE('SAM ':C:1:1) then result is samhyamsundar.
Keyword Overlay
ddds1
ds
ddate1
10a inz('2001-01-01')
dyyyy
4s 0 overlay(date1:1) inz(1999)
dmm
2s 0 overlay(date1:6) inz(12)
ddd
2s 0 overlay(date1:9) inz(12)
c
date1
dsply
c
eval
*inlr=*on
Here the value of date1 is 1999-01-01 instead of 2001-01-01.Here the first four character are overlaid by
the next statement
Note1:

We can create a module in CLP by making the type as CLLE

- 122 -

Tips n Facts

ILE RPG Exception Handling

ILE RPG provides four types of exception handling mechanisms:


An error indicator or an 'E' operation code extender handler

A MONITOR group
An error subroutine handler
A default exception handler

RPG categorizes exceptions into two classes, program and file; this determines which type of error
subroutine is called. Some examples of program exceptions are division by zero, out-of-bounds array
index, or SQRT of a negative number. Some examples of file exceptions are undefined record type or a
device error.
There are five ways for you to indicate that RPG should handle an exception. You can:
1.
2.
3.
4.
5.

Specify an error indicator in positions 73 - 74 of the calculation specifications of the appropriate


operation code.
Specify the operation code extender 'E' for the appropriate operation code.
Include the code that produces the exception within a MONITOR group.
Code a file error subroutine, which is defined by the INFSR keyword on a file description
specification, for file exceptions. The file error subroutine can only be coded in the main source
section. You cannot code an INFSR for a file that is used in a subprocedure.
Code a program error subroutine, which is named *PSSR, for program exceptions. Note that a
*PSSR is local to the procedure in which it is coded. This means that a *PSSR in a main
procedure will handle only those program errors associated with the main procedure. Similarly, a
*PSSR in a subprocedure will only handle the errors in that subprocedure.

Exception Handling within a Main Procedure


When an exception occurs within a main procedure ILE RPG does the following:
1.

If an error indicator is present on the calculation specification and the exception is one that is
expected for that operation:
a. The indicator is set on
b. The exception is handled
c. Control resumes with the next ILE RPG operation.

2.

If an 'E' operation code extender is present on the calculation specification and the exception is
one that is expected for that operation:
a. The return values for the built-in funtions %STATUS and %ERROR are set.

Note:
%STATUS is set when any exception occurs even if the 'E' extender is not specified.
b. The exception is handled
c. Control resumes with the next ILE RPG operation.

or

3.

If no error indicator or 'E' extender is persent and the code that generates the exception is in the
MONITOR block of a MONITOR group, control will pass to the on-error section of the MONITOR
group.

4.

If no error indicator or 'E' extender is present, no active MONITOR group could handle the
exception, and
a. you have coded a *PSSR error subroutine and the exception is a program exception
b.

FPRDMAS
F
F

you have coded a INFSR error subroutine for the file and the exception is an I/O
exception,
UF

K DISK
INFSR(PrdInfsr)
INFDS(PrdInfds)

- 123 -

Tips n Facts
D PrdInfds
DS
D PrdStatus
*STATUS
* List of expected exceptions.
*
*-----------------------------------------------------------------*
D ErrRecLock
C
CONST(1218)
*-----------------------------------------------------------------*
* Access the product master file using the transaction product
*
* number.
*
*-----------------------------------------------------------------*
C
TRNPRDNO
CHAIN
PRDREC
10
*-----------------------------------------------------------------*
* If the record is found, update the quantity in the master file. *
*-----------------------------------------------------------------*
C
IF
NOT *IN10
C
SUB
TRNQTY
PRDQTY
C
UPDATE
PRDREC
*-----------------------------------------------------------------*
* If the record is not found, write to the error report
*
*-----------------------------------------------------------------*
C
ELSE
C
EXCEPT
NOTFOUND
C
ENDIF
C
SETON
LR
*-----------------------------------------------------------------*
* Error handling routine.
*
*-----------------------------------------------------------------*
C
PrdInfsr
BEGSR
*-----------------------------------------------------------------*
* If the master record is currently locked, write the transaction *
* record to the back log file and skip to next transaction.
*
*-----------------------------------------------------------------*
C
PrdStatus
DSPLY
C
IF
(PrdStatus = ErrRecLock)
C
WRITE
TRNBREC
C
MOVE
'*GETIN'
ReturnPt
6
*-----------------------------------------------------------------*
* If unexpected error occurs, cause inquiry message to be issued. *
*-----------------------------------------------------------------*
C
ELSE
C
MOVE
*BLANK
ReturnPt
C
ENDIF
C
ENDSR
ReturnPt
*-----------------------------------------------------------------*
* Error report format.
*
*-----------------------------------------------------------------*
OPRINT
E
NOTFOUND
O
TRNPRDNO
O
29 'NOT IN PRDMAS FILE'
The following is done for each record in the TRANSACT file:
1.

The appropriate record in the product master file is located using the transaction
product number.
2. If the record is found, then the quantity of the inventory is updated.
3. If an error occurs on the UPDATE operation, then control is passed to the INFSR
error subroutine.
4. If the record is not found, then the product number is written to an error report.
When control is passed to the error subroutine, the following occurs:

If the error is due to a record lock, then the record is written to a backlog file
and control returns to the main part with the next transaction (via *GETIN as the
return point).

If the error is due to some other reason, then blanks are moved to ReturnPt. This
will result in the RPG default handler receiving control. The recovery action at
that point will depend on the nature of the error.
Note that the check for a record lock error is done by matching the *STATUS subfield of
the INFDS for PRDMAS against the field ErrRecLock which is defined with the value of the
record lock status code. The INFSR could be extended to handle other types of I/O errors
by defining other errors, checking for them, and then taking an appropriate action.

- 124 -

Tips n Facts

then the exception will be handled and control will resume at the first statement of the error subroutine.
5.

If no error indicator, 'E' extender, or error subroutine is coded and no active MONITOR group
could handle the exception, then the RPG default error handler is invoked.
c. If the exception is not a function check, then the exception will be percolated.
d. If the exception is a function check, then an inquiry message will be displayed. If the 'G'
or 'R' option is chosen, the function check will be handled and control will resume at the
appropriate point (*GETIN for 'G' or the same calculation specification that received the
exception for 'R') in the procedure. Otherwise,the function check will be percolated and
the procedure will be abnormally terminated.
See Unhandled Exceptions for a full description of the RPG default handler.
Exception Handling within Subprocedures
Exception handling within a subprocedure differs from a main procedure in the following ways:
Because you cannot code an INFSR subroutine, you should handle file errors using error
indicators, the 'E' operation code extender, or a MONITOR group.

There is no default handler; in other words, users will never see an inquiry message.

Exception handling within a subprocedure differs from a main procedure primarily because there is no RPG
cycle code generated for subprocedures. As a result there is no default exception handler for
subprocedures and so situations where the default handler would be called for a main procedure
correspond to abnormal end of the subprocedure. This means that:

Factor 2 of an ENDSR operation for a *PSSR subroutine within a subprocedure must be blank. A
blank factor 2 in a main procedure would result in control being passed to the default handler. In
a subprocedure, if the ENDSR is reached, then the subprocedure will end abnormally and
RNX9001 will be signalled to the caller of the subprocedure.

If there is no *PSSR and a function check occurs, the procedure is removed from the call stack
and the exception is percolated to the caller.

Since an inquiry message is never issued for an error in a subprocedure, you do not have access
to the 'Retry' function available for some I/O errors. If you expect record-lock errors in a
subprocedure, you should code an error indicator or an 'E' extender and check if the status is
related to a record being locked.

Note that the PSDS and INFDS have module scope. Both main procedures and subprocedures can access
them.
TIP
A *PSSR is local to the procedure in which it is coded; therefore, to have a common error routine, you can
code a procedure to handle the error and call the procedure from each local *PSSR.
Differences between OPM and ILE RPG Exception Handling
For the most part, exception handling behaves the same in OPM RPG and ILE RPG. The key difference lies
in the area of unhandled exceptions.
In OPM, if an exception occurs and there is no RPG-specific handler enabled, then an inquiry message is
issued. In ILE, this will only occur if the exception is a function check. If it is not, then the exception will
be passed to the caller of the procedure or program, and any eligible higher call stack entries are given a
chance to handle the exception. For example, consider the following example:
PGM A calls PGM B, which in turn calls PGM C.

PGM B has an error indicator coded for the call.


PGM C has no error indicator or *PSSR error subroutine coded.
PGM C gets an exception.

- 125 -

Tips n Facts
In OPM, an inquiry message would be issued for PGM C. In ILE, the exception is percolated to PGM B,
since it is unhandled by PGM C. The error indicator in PGM B is turned on allowing PGM B to handle the
error, and in the process PGM C ends abnormally. There is no inquiry message.
If PGM C has a *PSSR error subroutine coded, then in both OPM and ILE, the exception is handled by PGM
C and the error subroutine is run.
Note:
Inquiry messages issued by ILE RPG will start with the prefix 'RNQ', not 'RPG', as in OPM RPG

Question1:
How can you copy only 100 records in a file which contains millions of records?
(Ans)
By using CPYF command we can give the record copying position starting and ending of the
records. If we want to copy the records between 1000 and 1100 in the million records we can
give 1000 in the start position and 1100 in the end position.

Restrict the file to contain only 100 records using CHGPF and then when you copy , only 100
records get added.

Question2:
How to convert a field from Uppercase to lowercase?
(Ans)
By using XLATE command we can convert a field from upper to loew case or vice versa.
FDSPF001 CF E
WORKSTN
Dlower
S
26A inz('abcdefghijklmnopqrstuvwxyz')
Dupper1
S
26A inz('ABCDEFGHIJKLMNOPQRSTUVWXYZ')
C
*in03
doweq
*off
C
exfmt
casecon
C 03
leave
C
if
*in09=*on
C
upper1:lower XLATE
lowcase
upper
C
endif
C
enddo
C
seton
lr
Here lowcase and upper are the two fields in the screen and the user is entering characters in lowcase and
convert that to upper case and move it to field upper when user press f9 key.
Question 3:
How to copy a file from as/400 system to a local pc.
(Ans)
Do the following to copy
ftp as/400 machine ip address
In wipro case
ftp 10.200.9.80
It will ask for user name and password. Enter your as/400 user id and
password. It will then say the
user has logged in successfully.
If you want to copy a rpgle program called load2 residing in shyamrlib library and source physical file
name is shyamrile then we have to change the current library into shyamrlib .Just type cd shyamrlib and it
will change the library. And then get shyamrile.load2 will copy the file into c:\ in local pc. If you want to
copy from a PC to as/400 library then do the following
To do: Copy from c:\shyam\load2 to shyamrile\load2 in shyamrlib
Steps:
cd shyamrlib
put c:\shyam\load2 shyamrile.load2
will copy the file in shyam in c directory into shyamrile in shyamrlib.

- 126 -

Tips n Facts
Question 4:
How will your read a 100th record in a group of records in a file?
(Ans)
Declare the file without K in record address type in file definition.
z-add the position you want to retrieve. Suppose you want to retrieve 125 th records
then z-add 125 to rrn
Do chain based on rrn.
fworkfile1 if e
disk
c
z-add
2174
rrn1
40
c
rrn1
chain
workfile1
40
c
seton
lr
Here we are reading the 2174th record.
Question 5:
Explain the usage of procedure in a life project
(Ans)
Here is a procedure which will accept the character in lower case and return the value in upper case. In
java the user may enter either in lower or upper cases and we have to convert into uppercase else the
chain will fail. So we create a procedure in our program which do this and call the procedure in our
program.
Ex:

This is the program which is calling the procedure.


DPROC1
PR
DX
10A
DA
S
10A
C
EVAL
A='shyamsunda'
C
CALLP
PROC1(A)
c
A
dsply
c
seton
The procedure
HNOMAIN
DPROC1
D

PR

PPROC1
B
DPROC1
PI
DX
Dlower
S
Dupper1
S
C
lower:upper1 XLATE
C
RETURN
PPROC1
E

lr

10A
10A
EXPORT
10A
10A
26A
26A
X
X

inz('abcdefghijklmnopqrstuvwxyz)
inz('ABCDEFGHIJKLMNOPQRSTUVWXYZ)
X

Question 6:
How to query a record for getting the rrn value?
(Ans)
Select rrn(zphamsp) from zphamsp where code=AE
Here zphamsp is the program name.
Question 7:
Is it possible to send arrays,data structures as a parameter to another program?
(Ans)
Yes it is possible and we have to call in the same way a parameter is passed in the program.
Ex:
darr1
s
2p 0 dim(10)
darr2
s
2p 0 INZ(1)
c
callB
'ARR2PGM'
C
PARM
ARR1
C
1
DO
10
C
ARR1(ARR2) DSPLY
C
ADD
1
ARR2
C
ENDDO
c
SETON
LR
called program

- 127 -

Tips n Facts
DARR1
S
2P 0 DIM(10)
DI
S
2P 0 INZ(1)
C
*ENTRY
PLIST
C
PARM
ARR1
C
1
DO
10
C
EVAL
ARR1(I)=I
C
ADD
1
I
C
ENDDO
C
SETON
LR
Here the array is passed as a parameter and the values after callb is 1 to 10
Question 8:
What is the difference in between CALL,CALLB,CALLP
(Ans)
Call is a dynamic call where the control will be transferred when the program Is executed where as Callb
and Callp are static calls.
A module is a non executable program and it contains one or more procedures. If you have modules
without procedure then it means that it is having only one default procedure and in case we can use
CALLB. But if a module is having more than one procedure then we can give explicitly the procedure name
to be called in case of CALLP
Out of these three Callp is the most efficient one.
Question 9:
What is the new name for as/400?
(Ans)
Iseries 400 is the new name given to as/400 by IBM now.
Question 10:
How to see the source of copy books included in a program while compiling or debugging?
(Ans)
While Compiling the program give *list instead of *source which will expand all the copy books.
Question 11:
How to retrieve the value from data area and how to change the value of a data area?
(Ans)
ds
s
10a
dg
s
10a inz('i hate u')
c
*dtaara
define data1
s
c
*lock
in
s
c
eval
s=g
c
out
s
c
s
dsply
c
seton
lr
I created a data area by using the command crtdtaara and give the length as 10a and value as I love you
Statement *dtaara
define data1
s
*lock
in
s
will copy the content into a temporary variable s
and now we are changing the value of s as I hate you and now by using out command the value of the
data structure will be changed

Question 12:
How you will avoid multiple users updating the same record?
(Ans)
While displaying the records in the screen we will be getting the timestamp Along with the actual data.
Store this in output data structure and while updating check weather the previous time stamp is the same
timestamp before updating. If the record is updated by another user then the time stamp will be changed
and if it does not matches then throw the error message Record is already updated by another user else
update the records with current time stamp
Program1
Store the time stamp and this time stamp will come as a input to the second program
Program 2
Here wstmst1 contains the input time stamp and check this matches with the database.If matches Update
else send error message
C
K1CDFL
CHAIN
ZPCDFLR
80

- 128 -

Tips n Facts
C
C
C
C
C
C
c
C
C

MOVEL
WSTMST1
WSTMST
IF
CDMOTS=WSTMST
TIME
CDMOTS
UPDATE ZPCDFLR
ELSE
EVAL
ERROR=1
LEAVE
ENDIF
ENDDO

Question 13:
What will %size and %elem keywords will do?
(Ans)
%size will display the size of the variable where as %elem will display the array dimension.
darr1
s
3s 0 dim(1000)
c
eval
c=%size(arr1)
c
eval
d=%elem(arr1)
c
c
dsply
c d
dsply
c
seton
lr
In the above program c will be 3 and d will be 1000
Question 14:
What will you format a number by using as/400?
(Ans)
By using Editw Keyword
For example if you want to print 1234567890.12 as $1,234,567,890 dollars and 12 cents then the edit
word must contains $ , , , &dollars&and& &cents.
Here & will be used to add a space and a blank space represents the variable. So for printing and 12 cents
we will give as &and& 12&cents. Where & represents blanks space in edit word and actual blank space is
the variable 12.
dsalary
dedit
damount
c
c
amount
c

s
c

12p 2 inz(1234567890.12)
'$ , , , &dollars&and& &cents
s
40a
eval
amount=%editw(salary:edit)
dsply
seton
lr

amount: $1,234,567,890 dollars and 12 cents


Question 15
How you can schedule a job to run periodically?
(Ans)
We have to create a job scheduler for running a job periodically. Here we can make a job to run once or
periodically at a given date and time. . We can create a job scheduler by using addjobscde command.
We can list all the job scheduler running by using the command wrkjobscde and we can delete a job
scheduler by using rmvjobscde or we can reschedule the job by using chgjobscde.
Question 16:
How you can bind a C module with a RPG Program?
(Ans)
Create a C module of type c
void logit (char *t)
{
printf("'%s'\n",t);
}
And bind this program by calling it as a module in RPG program
D txt
S
40A INZ('Hello, world !')
D logit
PR
EXTPROC('logit')

- 129 -

Tips n Facts
dtxt

c
c

CALLP
return

value OPTIONS(*STRING)

logit(%TRIMR(txt))

Create program for this rpg by binding with the c module and call this program.
Question 17
How to debug a batch job?
(Ans)
Hold the batch job to be debuged by using wrkactjob command and having option 3. Set the pointer in the
batch program to be debuged by using strdbg and then call the strsrvjob command and start the service
program which will enter into the debug mode. After entering into debug mode release the job that is hold
before.
Question 18
Explain briefly about Non join Logical File.
(Ans)
Logical files can be derived from 1 to 32 physical files and so a logical file can have a maximum of 32
Record formats.
If a logical file is derived from single physical file without joining then it is single record format logical file.
Single record format logical file:
Refaccpth is applicable for Non join logical file only and meaning is refer the access path from the physical
or the logical file in the file level entry.

PFILE is applicable only for non join logical file in record level entry.
R RECPF2
PFILE(PF02)
K EMPNAME
Here the employee files key will be changed from empno to empname.
Output of this query is
No
1
2
3

NAME
SHYAM
RAMBABU
SASI

ADDRESS1
ADDRESS2
CITY
29,ARUNA NAGAR
PUTHUR
TRICHY
TN
29,ARUNA NAGAR PUTHUR
TRICHY
TN
53,KULALAR STREET

STATE

ZIPCODE
17

17
CUMBUM

TN
54
******** End of report ********
Here runqry will select all the records in pf02.
R RECPF2
PFILE(PF02)
EMPNAME
15A
CITY
10A
K EMPNAME
Here the attribute size of city is changed from 30 to 10 and also the key value
is changed.
The output of this query is
EMPNAME
CITY
SHYAM
TRICHY
RAMBABU
TRICHY
SASI
CUMBUM
R RECPF2
EMPNAME
CITY
EMPNO
K EMPNAME
O EMPNO
The output of this is
EMPNAME
CITY
SHYAM
TRICHY
RAMBABU
TRICHY

PFILE(PF02)
15A
10A
5S 0
CMP(GT 2)
empno
1
2

- 130 -

Tips n Facts
Here the employee number 3 is omited since it is greater than 2.
Multiple record non join logical file will select records from 2 or more physical files by referring to only one
logical file
1) Each record format is always associated with one or more physical file.
2) The same PF can be used in more than one record format.
Question 19:
Explain Inner join or natural join and left outer join.
(Ans)
Natural join
In case of natural join only the matching records in between the joining file will be selected.
If the pf of 2 files is like this
PF01
R JP1REC
EMPNO
5S 0
EMPNO
EMPNAME

PF02
R JP2REC

5S 0
20A

EMPSAL 15P

0
K EMPNO
The records in the 2 files are as follows
Empno
Empname
1
shyam
1000000
2
sundar
2000000
3
rambabu
1000000

K EMPNO
Empno

Empsal
1
2
4

Then in case of natural or inner join the records selected are


Empno
1
2

Empname

Empsal

shyam
sundar

1000000
2000000

where as in Left outer join all the records from primary file and the matching records
from the secondary file will be selected.
The output is
Empno
Empname
Empsal
1
shyam
1000000
2
sundar
2000000
3
rambabu
0
Note that the salary will be defaulted to default values and the employee number 4 is not
selected since this is the secondary file.
R JL1REC
J

JFILE(JP01 JP02)
JOIN(1 2)
JFLD(EMPNO EMPNO)
JREF(JP01)

EMPNO
EMPNAME
EMPSAL
K EMPNO
Where as in inner join we have to specify jdftval in file level entry
JDFTVAL
R JL2REC
JFILE(JP02 JP01)
J
JOIN(1 2)
JFLD(EMPNO EMPNO)
EMPNO
JREF(JP02)
EMPNAME
EMPSAL
K EMPNO
JFILE: It is similar to indicate that this is a Join logical file and it must have more
than 2 physical files
Join : It indicates what are the files to be joined in this case. We can represent the
position of the files. There must be one primary file and can have more than 1 secondary
files.
JFLD which fields we are going to join
JREF represent the primary file reference field.
JDFTVAL represents that it as a left outer join.

- 131 -

Tips n Facts
If we are joining more than one Physical files then we can represent it as follows.
If the first two files are the same JP01 and JP02 and the third file to be joined is JP05
Which is having these fields
R JP1REC
Empno
address
Empno
5s 0
1
Trichy
Address 20a
2
Cumbum
K empno
Then the result is
1
shyam
1000000
2
sundar
2000000
which fetches the matching record in all the three files.
JDFTVAL
R JL5REC
JFILE(JP01 JP02 JP05)
J
JOIN(JP01 JP02)
JFLD(EMPNO EMPNO)
J
JOIN(JP02 JP05)
JFLD(EMPNO EMPNO)
EMPNO
JREF(JP01)
EMPNAME
20A
EMPSAL
15P 0
ADDRESS
K EMPNO
Question 20
What will FOR opcode will do?
(Ans)
dn
s
5s 0 inz(10)
di
s
5s 0
* for(i=0;i<n;i++)
c
for
i=1 to n
c
i
dsply
c
endfor
* for(i=n;i<1;i--)
c
for
i=n downto 1
c i
dsply
c
endfor
* for(i=5;i<40;i=i+10)
c
for
i=5 by n to 40
c
i
dsply
c
endfor
c
c
for
i=5 to 40 by n
c
i
dsply
c
endfor
c
* for(i=5;i<40;i=i+10)
c
seton

trichy
cumbum

lr

Question 21
What are the various stages for a job after it is submitted?
(Ans)
Jobqueue, Active job and OUTQ are the three stages after the job has been submitted.
Question 22
What are the difference between non join logical files and join logical files
(Ans)
Non Join Logical Files
We can able to insert or delete or update records
using non join logical files.
DFU can be used to display Non join logical files
1-32 record format can be specified
Commitment control is used

Join Logical Files


Insertion, updating or deletion of records is not
possible in join logical files
DFU is not available
Only one record format can be specified
Commitment control is possible

- 132 -

Tips n Facts
Question 23
Explain Self join in detail
(Ans)
In a employee physical file there are 3 fields named empno,empname and mgrid.
Manager is also an employee and he has an employee id in the same table with some other as manager.
We want to query the records with the fields empno,empname and manager name. So based on the
manager id we have to select the corresponding employee id and select the employee name and move
that
as
the
manager
name.
DDS of Physical File
SEU==>
PFTEST
FMT PF .....A..........T.Name++++++RLen++TDpB......Functions++++++++++++++++++
*************** Beginning of data *************************************
0001.00
A
R EMP
0002.00
A
EMPID
5 0
0003.00
A
EMPNAME
20
0004.00
A
MGRID
5 0
****************** End of data ****************************************
Data in Physical File
EMPID EMPNAME
MGRID
000001 10,001 Sebi Joseph C.
50,001
000002 10,002 Purushottam
50,002
000003 10,003 Sameer Dighe
50,003
000004 10,004 Sharada Menon
50,004
000005 10,005 Saju Paul C.
50,005
000006 50,001 Shivaram Pasuvan
90,001
000007 50,002 Praveen K. Gaurav
90,002
000008 50,003 Lionel King
90,003
000009 50,004 Sam Mathew Varghese
90,004
000010 50,005 Anil Jandyam
90,005
****** ******** End of report ********
FMT LF .....A..........T.Name++++++.Len++TDpB......Functions++++++++++++++++++
*************** Beginning of data *************************************
0001.00
A
R EMP
JFILE(PFTEST PFTEST)
0002.00
A
J
JOIN(1 2)
0003.00
A
JFLD(MGRID EMPID)
0004.00
A
EMPID
JREF(1)
0005.00
A
EMPNAME
JREF(1)
0006.00
A
MANAGER
RENAME(EMPNAME) JREF(2)
0007.00
COLHDG('MANAGER')
****************** End of data ****************************************
Output of Join Logical File
Line

....+....1....+....2....+....3....+....4....+....5.
EMPID EMPNAME
MANAGER
000001 10,001 Sebi Joseph C.
Shivaram Pasuvan
000002 10,002 Purushottam
Praveen K. Gaurav
000003 10,003 Sameer Dighe
Lionel King
000004 10,004 Sharada Menon
Sam Mathew Varghese
000005 10,005 Saju Paul C.
Anil Jandyam
****** ******** End of report ********
Question 24:
What is a field reference file?
(Ans)
This is a physical file which does not have any data and contains only the field descriptions and these
fields are referred in other pf by using ref and reffld.
This is the third type of file along with PF and LF.
Question 25
What will runsqlstm will do?

- 133 -

Tips n Facts
(Ans)
If we want to execute set of sql statements (only insert, update and delete and no select is allowed) then
we can write all the sql statement to be included with the source type as sql. Then use strsqlstm to
execute the program
RUNSQLSTM SRCFILE(SHYAMRLIB/TESTSHYAM) SRCMBR(SQL1) COMMIT(*NONE)
Question 26
What is the advantage of Opnqryf over SQLRPG?
(Ans)
opnqryf
Opnqryf will come along with os/400 system and no
need to have any additional package needed to
execute it.
Opnqryf is faster as compared to sqlrpg
Opnqryf Is nothing but a dynamic logical files which
will be created and the records are queried and
finally the logical files are deleted and OPNQRYF
provides that facility

sqlrpg
We need to have sqlrpg installed in as/400 system
which involves additional cost to the programmers
It is slower
SQLRPG is imbedding sql statements directly within
SQL Statement

Question 27
What is the equivalent command to setll *loval in CL
(Ans)
POSDBF with file position as *start will set the file to the beginning or using ovrdbf and specify the
keyfield value by rrn value or by giving *start.

Question 28
What is the difference between OPM, EPM and RPGILE?
(Ans)
OPM
EPM
Open Program Model is the old Extended program model will
RPG/400 system, which will not support PASCAL, FORTRAN and
allow a program type to call other programming concepts.
another program type.
Version is V1R2

RPGLE
It
supports
mixed
program
support in
which you
can
combine
any
program
with
another type of program
Version is V2R3

Question 29
What is the difference between Bind by value and Bind by reference?
(Ans)
Bind by value
Bind by Reference
Here all the modules to be bounded are physically In this case we are binding the programs by using
copied into the main program object.
service programs which contains a reference to the
modules that has been called and the modules are
not physically copied into the program objects
The program will be executed even when you delete The program will not execute when the bind
all the modules that have been called.
modules are deleted.
Bind by value is faster than bind by reference
It is not as faster as bind by value

Question 30
How to create a service program and what are the steps involved in this?
(Ans)
While creating service program we can create a binder program where we can refer the modules or
procedures or even data types to be used by the program, which is using service program. If we are
having 100 procedures in a module and if you want to specify only some procedures to be bind in the
service program we can create the binder program.
STRPGMEXP SIGNATURE('BND')
EXPORT SYMBOL('PGM1')
ENDPGMEXP
Here there are 2 programs PGM1 and pgm

- 134 -

Tips n Facts
PGM1
S
S
S
EVAL
SETON

DA
DB
DC
C
C

2P 0 INZ(8)
2P 0 INZ(8)
2P 0
C=A+B

PGM
CALLB PGM1
SETON
LR
LR

Then we create the binder program, which will give authority to only one module named PGM1
Then create the service program with binding program incorporated. If no binder program is incorporated
then all the modules will be taken as default
CRTSRVPGM SRVPGM(QTEMP/SRVPGM) MODULE(QTEMP/XXXX) SRCFILE(IDCPGRRSP/SHYAMR
ILE) SRCMBR(BND)
DSPSRVPGM Will helps us to display the details about the service program that has been created.
We can also create a bind directory for a service program where we can bind all the modules together and
if we do like this then there is no need to bind all the programs and we can compile the program straightly
by using crtbndrpg even it has more than 1 module.
CRTBNDDIR BNDDIR(QTEMP/BNDDIR)
ADDBNDDIRE BNDDIR(QTEMP/BNDDIR) OBJ((*LIBL/SRVPGM *SRVPGM))
The type of service program that is created is *srvpgm.

Question 31
What is an activation group?
(Ans)
Activation group is the boundary set for similar programs. Activation group is also a storage space in
memory.
Consider for example the following scenario
1)
2)

CLP has a ovrdbf command and calls a rpg program


RPG program performs a read operation and the pointer is now in the second program and now
call the program 3
3) RPG program that also do a read operation which will read the second record since the pointer is
in the second position and then return to 2nd program
In the above situation when the control transfers from 3 rd program to the 2nd program then it will read
the 3rd record since the 2 nd record is already read in program 3. But we need to read the 2 nd record
according to the logic but this is not possible in any OPM programs. But in ILE there is a solution for
this problem by giving a common activation group for 1 st and 2nd program and have a separate
activation group for the 3rd program while creating the program itself and this will avoid all the
problem we faced before.
In some situation we want to share between 2 programs then we can give the activation group in *job
level in which the changes in one program will be affected in another program.
Types of activation group levels:
*new : In this case every time you call the program an new activation group will be created which this
case will not be used mostly.
*caller: If we dont know the type of the program that is calling then we can specify *caller where the
activation group will be the same of the program that is calling.
Named activation group: We can give our own named for different activation group

Question 32
What are the statements that are affected by activation group?
(Ans)
1) OVRDBF
2) OPNQRYF
3) STRCMTCTL
4) DLTOVR
5) OPNDBF

Question 33
What are the statements, which is not used in CLLE that is used in CLP?
(Ans)

- 135 -

Tips n Facts
1)
2)

RCLRSC which is replaced by RCLACTGRP


TFRCTL

Question 34
Write a brief note on procedures used in RPGLE
(Ans)
1) Defining the Prototype:
Prototype will specify the following things
1) Parameter type
2) Sequence of the parameter
3) Return variable and its type
4) It tells the name of the procedure and also the type of the call.
It will avoid all the run time problems like parameter mismatch by specifying the prototype like this
2) Prototype interface:
It is like the *entry parameter where we will specify the parameters that are received in this program.
3) IMPORT and EXPORT
If you want to specify the procedures to be used by the external programs then we can specify EXPORT in
your procedure. If you dont want then leave it blank. It is similar like giving private or public in JAVA.
4) Global and local variables
If you declare a variable in main procedure then it will be accessible in all its sub procedure and this is
global declaration and if you specify the declaration in the sub procedures then it will not be accessed in
other procedures or in the main procedure.
5) RETURN
If we specify return in the sub procedure then it means that we are returning something to the calling
program. We can return a maximum of only one variable to the calling program.
6) Recursion
A procedure calling to it self is known as recursion
7) Pass by value/Pass by reference
In case of pass by reference we are passing the address of the parameters and not the actual value and
so the changes in the called procedure will affect the value in the calling programs. In OPM programs we
are using only call by reference and in RPGLE we have the option to pass the parameter by value by giving
the keyword VALUE
8) CALLP/Expression
We can call the procedure by using CALLP command if it is not having any return type and by an
expression if it returns any value
Example
EVAL C=PROC1(A:B)
Example program doing recursion using procedure.
Called procedure:
H NOMAIN
DRECUR
PR
3S 0
DA
2S 0
*
DB
S
3S 0 INZ(1)
PRECUR
B
EXPORT
D RECUR
PI
3S 0
D A
2S 0
C
IF
A<>1
C
EVAL
B = B*A
C
EVAL
A = A-1
C
CALLP
RECUR(A)
C
ENDIF
C
RETURN B
PRECUR
E
*
Calling program
DVAL
S
2S 0 INZ(5)

- 136 -

Tips n Facts
DFACT
DRECUR
DA
C
C
C
FACT
C

S
PR

3S 0 INZ(1)
3S 0
2S 0

EVAL
FACT = RECUR(VAL)
DSPLY
SETON

LR

Question 35
What is program entry procedure (PEP) and User entry procedure (UEP)
(Ans)
If we are binding many modules together to form a program then we have to specify which module has to
take control first when it has been called and that module is called as PEP for that program.
User entry procedure is the first statement that takes the control when a program has been called. For
example in C programs main( ) will be executed first when it has been called and like wise in RPG the
statement coded in C spec will take the control first.

Question 36
Explain about FMTDTA in detail.
(Ans)
Here there is a pf of the following attributes
R REC1
EMPNO
5S 0
EMPNAME
20A
ADDRESS
25A
DOB
8S 0
And this physical file is having the following records
Empno name
address
dob
1 shyam
trichy
11,021,999
2 tom
pune
11,122,002
3 ccc
jjhhj
11,021,999
We want to sort the file based on address in ascending order then we have to code the format data in the
following way. The type of the file is FMT
IPRH and IPRF are used to add the attributes of format data.
HFILE 025A
X
pf02
FNC00260050
address
FDC00010058
Here we want to sort the physical file based on the address and the length of the field to be sorted is 25.
If we want to sort based on more than 1 field (address,dob) then give the length as 33(25+8)
HFILE 025A
X
pf02
The address position starts from 26 th position to 50 and we have more fields declare all the fields by taking
IPRF Spec
FNC00260050
address
After coding all the fields to be sorted give the total length of all the fields in the file. Here the file pf02 has
a length of 58 and we declare it as follows
FDC00010058
The type of this program is anything even a text file. After coding the sorting manner we have to make
use of format data command to create a file that contains the sorted record.
FMTDTA INFILE((IDCPGRRSP/PF02)) OUTFILE(QTEMP/PF02) SRCFILE(IDCPGRRSP/SHYA
MRILE) SRCMBR(FMT)
This will copy the records into PF02/qtemp and the records will be sorted on address.
Output after sorting:
EMPNO EMPNAME
ADDRESS
DOB
3 ccc
jjhhj
11,021,999
2 tom
pune
11,122,002
1 shyam
trichy
11,021,999

Question 37
What is the difference between FMTDTA and OPNQRYF
(Ans)

- 137 -

Tips n Facts
FMTDTA
It will sort the records sequentially based on the
position of the record.
If any changes in the attribute size of a pf then we
have to change the program specification also
FMTDTA is bit faster in process than opnqryf.

OPNQRYF
It will sort the records based on the field values.
If there is any change in the attribute size it will not
affect the program specification also.
OPNQRYF is slower as compare to FMTDTA if we are
processing millions of records.

Question 38
How you can import and export a data type between 2 programs
(Ans)
If you are using an export statement when declaring a variable then the data type can be imported in any
modules that is bind either by value or by reference. So in this case we can pass values in between
modules instead of using plist and *entry.
Program 1
DDD
S
2S 0 EXPORT INZ(1)
C
CALLB
'EXP01'
C
DD
DSPLY
C
SETON
LR
Program 2
ddd
c
c

s
eval
seton

2s 0 import
dd=6
lr

In the above example the value of the variable DD will be passed to the next program and it value is
changed in the second program without using *entry and plist

Question 39
How you can use pointers in RPGLE
(Ans)
Pointer is concept of referring the variable in the basis of address. We can make many variables or data
structures that refer the same address space by using this pointer.
dbase_address
s
*
ddsname1
ds
based(base_address)
dfirname
10a
dlasname
10a
ddsname2
ds
30
c
eval
base_address=%addr(dsname2)
c
eval
dsname2='shyam
sundar'
c
firname
dsply
c
lasname
dsply
c
seton
lr
Here in the above example we declare the pointer base_address and we make the datastructure dsname1
assigning to that pointer. We declare another data structure and till now the memory is not allocated to
the pointer. Then by using the command
c
eval
base_address=%addr(dsname2)
we are allocating the address space to the pointer and since the data structure dsname1 is also referring
this any change to dsname2 will affect dsname1. So assign some values to dsname2 and we can see the
values in dsname1 also. Here the firname and lasname will print as shyam and sundar respectively.

Question 40
Discuss about option keyword in detail
(Ans)
options(*varsize) : It is similar to declaring the variable as varchar instead of char. So if we declare a
variable with size 100 and if you initialize with shyam then it will allocate only 5 spaces.
Options(*nopass): This means that this parameter can be passed or even omitted
Options(*omit): We can give both *nopass and *omit for a single variable.

- 138 -

Tips n Facts
Options(*string): If we are passing string to the called program and if it is expecting the pointer then in
such case we can give this option.
Please refer the question 16 for further clarification

Question 41
Explain EXTPGM in detail
(Ans)
If we want to call a procedure dynamically then we can make use of this command
d prot1
pr
extpgm('qcmdexc')
d cmdstr
1000 options(*varsize)
D
CONST
d cmdlen
15s 5
D
CONST
d const1
3 options(*nopass)
D
CONST
D Cmds
C
'DSPWSUSR'
c
callp
prot1(cmds:%len(cmds))
c
seton
lr
In the above program example we are passing 3 variables to qcmdexc command for listing cl command.

Question 42
Explain O Spec and use of EXCEPT Opcode in detail
(Ans)
O-Spec is used for printing records and except opcode is equal to writing the record format name in case
of RLU.
We are printing all the records in the physical file pf02 whose has empno,name and address as the fields
by using O-spec and except opcode.
fpf02
if e
disk
fqsysprt o f 132
printer
dss
s
20a inz('--------------------')
c* *loval
setll
rec1
c
read
rec1
80
c
except header
c
*in80
doweq
*off
c
except detail
C
read
rec1
80
c
enddo
c
seton
lr
*
oqsysprt e
header
o
ss
20
o
ss
40
oqsysprt e
detail
o
empno
5
o
empname
25
o
address
45
****************** End of data *************************
The output of the spooled file is
---------------------------------------00001shyam
trichy
00002tom
pune
00003ccc
jjhhj
Question 43
Explain CURPOS keyword used in Display file in detail.
(Ans)
If you want to position the cursor to a certain position in the screen then we can use the CURPOS
keyword. In record level input keyword we have to associate 2 variables and we have to declare these 2
variables as a hidden field by taking F4 with the size of 3,0.
And in the program indicate the position that the cursor to be moved. It will make the control of the cursor
to move there.
CURPOS Keyword is having higher priority than setting the cursor through Position cursor or through
SFLRCDNBR keywords.

- 139 -

Tips n Facts
Ex
FDSPF001 CF E
WORKSTN
C
EVAL
ROW=6
C
EVAL
COLUMN=20
C
EXFMT
RECPOS
C
SETON
LR
Here in the above example the cursor will be at 6 th row and 20th column. Here row and column are the 2
variables associated in CURPOS with size as 3,0
Question 44
How to display all the members present in a physical file
(Ans)
By using DSPFD we can copy all the members in a source physical file into another temporary file. Then
we can display the members which is a field in the temporary file by reading it sequentially or by reading
with the key.
DSPFD
FILE(SHYAMRLIB/TESTSHYAM)
TYPE(*MBRLIST)
OUTPUT(*OUTFILE)
FILEATR(*ALL)
OUTFILE(SHYAMRLIB/SHYAM2)
Here all the members in the source physical file testshyam is copied into a temporary file named shyam2.
To copy all the member list we have to give the type as *MBRLIST.
Then we can retrieve the members by using any sql statements or through any program.
Question 45
Explain build in function %dec , %dech and %decpos
(Ans)
%dec is used to get the output in a decimal format
%dech is use to half round the numbers to the nearest largest or lowest numbers
ex
DB
S
6s 2 INZ(54.78)
DA
S
6s 2
Then
C
EVAL
A=%DECh(B:6:0) value is 55
C
EVAL
A=%DECh(B:6:1) value is 54.80
C
EVAL
A=%DECh(B:6:2) value is 54.78
%DECPOS will return the number of decimal positions for a given variable. If we declare a variable as 16,7
then
c eval a=decpos(b) will return 7 which is the number of decimal positions.
Question 46
Explain PREFIX keyword and RENAME keyword in detail.
(Ans)
If 2 files are declared in a program and if both the files is having same record format then we have to use
rename keyword to rename the record format name
Ex
PF01
PF02
R REC1
R REC1
EMPNO
5S 0
EMPNO
5S 0
EMPNAME
15A
EMPADD
15A
Then in the file specification we have to declare as
FPF01
IF E
K DISK
FPF02
IF E
K DISK RENAME(REC1:REC2)
And in the program if you have a statement
Read rec1 then it means you are reading PF01 where as the statement
READ REC2 means that you are reading PF02
PREFIX is used to rename the fields in one file .In the above example if the attribute size of empno in
PF02 is different from PF01 (EX EMPNO 4S 0 ) Then 2 variables are declared with different attributes but
with same name. So the program will give a compile time error. But if you give PREFIX in keyword level
FPF02
IF E
K DISK PREFIX(X)
Then it will prefix Xto all the fields in pf02. In the above case empno and empaddress is refered as
xempno and xempadd which will avoid compile time errors.
Example
FPF01
IF E
K DISK
FPF05
IF A E
K DISK PREFIX(X)
C
*LOVAL
SETLL
REC1

- 140 -

Tips n Facts
C
*LOVAL
SETLL
REC2
C
EVAL
XEMPADD='TRICHY'
C
EVAL
XEMPNO=1
C
WRITE
REC2
C
SETON
Here a record will be inserted in the file pf05

LR

Question 47
Explain Serial Cursor in detail in SQLRPG
(Ans)
SQLRPG is also used to select records dynamically like an OPNQRYF and a logical file. We have to include
sql statements in between RPGLE programs and the type of the program is SQLRPGLE.
We can use SQLRPG for selecting a single record or a group of records.
Single record selection
D@DLNM
S
50a
C/EXEC SQL SELECT DLNAME into :@DLNM FROM TEST01
C/END-EXEC
C
C
@DLNM
DSPLY
C
C
SETON
LR
If we want to select multiple records at a time then we can go for cursor.
Cursor can be classified into 2 types
1) Serial Cursor
2) Scrollable Cursor.
If we are reading the records from 1 st to the last records sequentially then such type of cursor is known as
serial cursor. We cannot able to set the pointer in between and read a record in serial cursor. It is similar
to Sequential file in Cobol.
Steps involved in creating Serial Cursor
1) We have to declare the cursor.
2) We have to open the cursor.
3) Fetch the cursor and this step will be in loop until the end of the record is reached perform this
step.
4) When all the records are read then close the cursor.
Declare the cursor:
We have to specify the records to be selected in this step
C/Exec SQL
Declare C1 cursor for
C+
Select EMPNO,EMPNAME from PF02
C/End-Exec
In the above case we are selecting 2 fields from the file PF02 in the cursor C1
To open the cursor
C/Exec SQL Open C1
C/End-exec
To make the loop to continue until the end of the record is reached we can make use of the statement
whenever not found
C*
C/EXEC SQL Whenever not found
c+ go to close
c/End-exec
*
C
NEXT
TAG
*
C/EXEC SQL Fetch C1 into :tnum,:tname
C/END-EXEC
Here the file PF02 has been read sequentially and the values are moved into temporary variables TNUM
and TNAME
Close the cursor
C/EXEC SQL
C+ CLOSE C1
C/END-EXEC

- 141 -

Tips n Facts
Example program1 which reads the record from pf02 and writes in the printer file PF02
FPRIN
O E
PRINTER
DTNUM
S
5S 0
DTNAME
S
15A
*
C/Exec SQL
Declare C1 cursor for
C+
Select EMPNO,EMPNAME from PF02
C/End-Exec
*
C/Exec SQL Open C1
C/End-exec
C*
C/EXEC SQL Whenever not found
c+ go to close
c/End-exec
*
C
NEXT
TAG
*
C/EXEC SQL Fetch C1 into :tnum,:tname
C/END-EXEC
*
C
MOVEL
TNUM
NUM
C
MOVEL
TNAME
NAME
*
C
WRITE
DETAIL
C
GOTO
NEXT
C close
tag
*
C/EXEC SQL
C+ CLOSE C1
C/END-EXEC
C
SETON
LR
Program2: Which reads from 2 file
FPRIN2
O E
PRINTER
*
DTNUM
S
5S 0
DTNAME
S
15A
DTSALARY
S
15S 0
C/Exec SQL
Declare C1 cursor for
C+
select pf02.empno,pf02.empname,pf03.salary from pf02,pf03
c/End-exec
*
C/Exec SQL
C+ Open C1
c/End-Exec
*
C
NEXT
TAG
C/Exec SQL
c+ Fetch c1 into :tnum,:tname,:tsalary
C/End-exec
*
C
IF
SQLCOD=100
C
GOTO
CLOSE
C
ENDIF
c
movel
tnum
num
c
movel
tname
name
c
movel
tsalary
sala
c
WRITE
DETAIL
c
GOTO
NEXT
*
c
close
tag
c/exec sql
c+ close c1

- 142 -

Tips n Facts
c/end-exec
*
C

SETON

LR

If the values in pf01 and pf02 are like this


******************PF02******************************
EMPNO EMPNAME
ADDRESS1
ADDRESS2
1 SHYAM
JHJK
JHKJH
******** End of data ********
******************PF03******************************
EMPNO YRMT
SALARY
1
201
20,000
2
201
120,000
******** End of data ********
Then output will be
1
SHYAM
20000
1
SHYAM
120000
If select condition is like this
C+
select pf02.empno,pf02.empname,pf03.salary from pf02,pf03
c+
where pf02.empno=pf03.empno
Then output will be
1
SHYAM
20000
Question 48
Explain SQLCOD in detail
(Ans)
SQLCOD is a special keyword used which contains a value based on the type of error. If there is no error
then sqlcod will be 0. If the end of the file is reached then the error code will be 100. We can make use of
this error code to check all the types of error condition.
In the above program we can rewrite as follows
*
C/Exec SQL
C+ Open C1
c/End-Exec
*
C
NEXT
TAG
C/Exec SQL
c+ Fetch c1 into :tnum,:tname,:tsalary
C/End-exec
*
C
IF
SQLCOD=100
C
GOTO
CLOSE
C
ENDIF
Which is equivalent to whenever not found statement used before.
Similarly sqlwn0 is used to find any warning messages is there in the sql statement executed
Ex
Sqlwno dsply
Question 49
Explain WRKQRY in detail
(Ans)
We can create any queries by using wrkqry programs. We can create any complex query and we can copy
the output to any out file and we can use that file to retrieve the selected records.
The advantage of using wrkqry is it is 100 percent bug free since the code is only on SQL.
Question 50
Is it possible to pass parameter list to a Query file
(Ans)
It is possible to pass parameters to a query created. While creating the query choose select records option
and give the condition with :
Example empno eq :empno
After this is entered in the "Select Records" panel, you will be presented with a " Specify Dependent Value
Qualifiers" panel. Key in a "1" and key in the name of the Query. Exit and save the Query as normal.
Finally run the Query with the STRQMQRY command and specify the
keyword ALWQRYDFN(*YES) and set the variables using the SETVAR keyword. For

- 143 -

Tips n Facts
example:
STRQMQRY QMQRY(yourlib/yourqry) ALWQRYDFN(*YES) +
QMFORM(*QMQRY) SETVAR((empno 12))
Note that if the parameter to be passed is alpha, you must enclose
the value in a set of triple quotes. For example:
SETVAR((STATE ''' FL''')
Question 51
How to retrieve the records that sound like something
(Ans)
If I want to retrieve all the records that has the pronunciation like sam then we can write a query like this
SELECT EMPNO,empname
FROM pf02
WHERE SOUNDEX (empname)=SOUNDEX ('sam')
that will retrieve all the empname which sounds like sam.
Here employee having name like shyam,sham,sam,shiyam will get retrieved
Question 52
How to find the square/square root,cube/cube root of a number in ile
(Ans)
dval
s
2s 0 inz(4)
dsqrt
s
2s 0
dcuberoot
s
2s 0
dpower5
s
2s 0
c
eval
sqrt=val**(1/2)
c
sqrt
dsply
c
eval
val=9
c
eval
cuberoot=val**(1/3)
c
cuberoot
dsply
c
eval
val=2
c
eval
power5=val**(5)
c
power5
dsply
c
seton
lr
Question 53
Explain CALLPRC in detail
(Ans)
If you want to call a procedure in CL then we will go for CALLPRC command.This works like this
Calling CL Program
pgm
DCL
VAR(&A) TYPE(*DEC) LEN(5 0) VALUE(5)
DCL
VAR(&b) TYPE(*dec) lEN(5 0) VALUE(5)
CALLPRC PRC(PROC1) PARM(&A &B) RTNVAL(&b)
endpgm
This program sends 2 numbers a and b to the procedure PROC1 and it get back the added value of a and
b
Called RPG program
HNOMAIN
dPROC1
pr
5 0
da
5 0
db
5 0
*
PPROC1
B
export
DPROC1
PI
5 0
da
5 0
db
5 0
c
return a+b
PPROC1
E
Tips
fndstrpdm

- 144 -

Tips n Facts
Question 54
How to grant and revoke authorities to other users
(Ans)
We can use GRTOBJAUT to give authority to particular users or to public. We can also restrict the type of
access weather to give read/compile/delete authorities to the user.
GRTOBJAUT OBJ(SHYAMRLIB/SHYAMRILE) OBJTYPE(*ALL) USER(*PUBLIC) AUT(*ALL)
Here for a source physical file shyamrile is given *all access to the public and any user can access all the
members in shyamrile source file
To revoke a authority given by the user use RVKOBJAUT command
Ex
RVKOBJAUT OBJ(SHYAMRLIB/SHYAMRILE) OBJTYPE(*ALL) USER(*PUBLIC) AUT(*ALL)
Question 54
What is the advantage of using CHGPF for compiling a physical file over CRTPF
(Ans)
If a physical file is having 100 logical files attached to it and millions of records is there in it then if we
want to change a field or add a new field or change a attribute in the file we have to delete all logical files
associated and recompile the physical files and then all logical files. Also we have to use CRTDUPOBJ and
CPYF to copy back the records. By using CHGPF command all the logical files associated are recompiled
automatically and the records are also copied after it is created.
This future is there from version V4 in as/400 system. The disadvantage of using this is we cannot able to
drop a field or we cannot able to reduce an attribute size by using this command.
Question 55
Explain %PARMS usage in ILE programming
(Ans)
If a program is called by more than one program but with different parameter list then we can make use
of %PARM to differentiate between the programs called. It is similar to method overloading concept in
JAVA.
For example program c is called by both a and b with 3 and 2 parameters.
Program A
c
pl01
plist
c
parm
a
20
c
parm
b
20
c
parm
c
20
c
eval
a=5
c
eval
b=3
c
call
'C'
PL01
C
C
DSPLY
C
SETON
LR
Program B
c
pl01
plist
c
parm
a
20
c
parm
c
20
c
eval
a=5
c
call
'C'
PL01
C
C
DSPLY
C
SETON
LR
Program C
c
*ENTRY
PLIST
c
parm
a
20
c
parm
b
20
c
parm
c
20
*
C
IF
%PARMS = 2
C
A
ADD
6
B
C
ELSE
c
A
ADD
B
C
C
ENDIF
C
SETON
LR
The output is 11 if called from b and 8 if called from a.
Question 56
Explain basic OPNQRYF in detail.
(Ans)

- 145 -

Tips n Facts
OPNQRYF is used to dynamic selection of records from the file. I will not create any access path to retrieve
the record from the physical file but it will create Open data path to retrieve the records.
Simple Opnqryf program that selects the records from the PF02 is given below
pgm
DCL
VAR(&VAL) TYPE(*CHAR) LEN(10) value('SHYAM')
DCL
VAR(&VAL1) TYPE(*CHAR) LEN(5) value('1')
OVRDBF
FILE(pf02) SHARE(*YES)
OPNQRYF FILE((SHYAMRLIB/PF02)) QRYSLT('empname +
*EQ "' *cat &val *CAT '"' *BCAT +
'*AND EMPNO *EQ' *BCAT &VAL1)
CPYFRMQRYF FROMOPNID(PF02) TOFILE(QTEMP/PF02) +
MBROPT(*REPLACE) CRTFILE(*YES)
RUNQRY
QRYFILE((QTEMP/PF02))
DLTOVR
FILE(PF02)
CLOF
OPNID(PF02)
endpgm
Another simple program that selects all the records based on joining date equals current date is given
below
pgm
DCL
VAR(&CURDATE) TYPE(*CHAR) LEN(6)
DCL
VAR(&CONDATE) TYPE(*CHAR) LEN(10)
DCL
VAR(&QUERRY) TYPE(*CHAR) LEN(60)
RTVSYSVAL SYSVAL(QDATE) RTNVAR(&CURDATE)
CVTDAT
DATE(&CURDATE) TOVAR(&CONDATE) FROMFMT(*MDY) +
TOFMT(*YYMD) TOSEP(-)
CHGVAR
VAR(&QUERRY) VALUE('DDATE *EQ "' *CAT +
&CONDATE *CAT '"')
OVRDBF
FILE(PF02) SHARE(*YES)
OPNQRYF FILE((SHYAMRLIB/PF02)) QRYSLT(&QUERRY)
CPYFRMQRYF FROMOPNID(PF02) TOFILE(QTEMP/PF02) +
MBROPT(*REPLACE) CRTFILE(*YES)
RUNQRY
QRYFILE((QTEMP/PF02))
DLTOVR
FILE(PF02)
CLOF
OPNID(PF02)
Endpgm
Question 57
Explain KEYFLD keyword used in OPNQRYF command in detail.
(Ans)
KEYFLD
If you want to change the key field of a physical/Logical file then we will go for Keyfld parameter in
OPNQRYF command. For example physical file PF02 is having empno as the key and we want to change
the key to empname then it will accompalish by using the KEYFLD keyword
pgm
OVRDBF
FILE(pf02) SHARE(*YES)
OPNQRYF FILE((SHYAMRLIB/PF02)) KEYFLD((EMPNAME))
CALL
PGM(RPG003)
DLTOVR
FILE(PF02)
CLOF
OPNID(PF02)
endpgm
RPG003
FPF02
IF E
K DISK
DEMPNAME
S
15A INZ('SHYAM')
C
READ
RECPF2
C
EMPNAME
DSPLY
C
SETON
LR
And if the records present in pf02 is
EMPNO EMPNAME
ADDRESS1
ADDRESS2
1 SHYAM
ARUNA NAGAR
PUTHUR
2 SUNDAR
ARUNA NAGAR
PUTHUR
3 JAYAPRAKASH
Then display will print JAYAPRAKASH since the keyfld changes the key from empno to empname and
jayprakash is the first record based on empname as the key.

- 146 -

Tips n Facts
If you use Descend in OPNQRYF then it will print SUNDAR
OPNQRYF FILE((SHYAMRLIB/PF02)) KEYFLD((EMPNAME +
*DESCEND
))
We can also dynamically changes the key used in the program by passing keyfld as a variable
pgm
DCL
VAR(&FLD) TYPE(*CHAR) LEN(1) VALUE('Y')
OVRDBF
FILE(pf02) SHARE(*YES)
IF
COND(&FLD *EQ 'Y') THEN(DO)
OPNQRYF FILE((SHYAMRLIB/PF02)) KEYFLD((EMPNAME +
))
ENDDO
ELSE
CMD(DO)
OPNQRYF FILE((SHYAMRLIB/PF02)) KEYFLD((EMPNO +
))
ENDDO
CALL
PGM(RPG003)
DLTOVR
FILE(PF02)
CLOF
OPNID(PF02)
endpgm
Here if the fld value is Y then keyfld is empname and the output displayed is JAYAPRAKASH else if the fld
value is N then KEYFLD is empno and the output displayed is SHYAM.
Question 58
Explain FORMAT and MAPFLD keyword used in OPNQRYF command in detail.
(Ans)
FORMAT
If we are joining one or more physical files and we want to retrieve some records based on some condition
then we have to create another physical file and the values will be retrieved from this physical file created.
The file created is a dummy file and it does not have any records. For example if there are 2 physical files
PF02 and PF03
R RECPF2
R RECPF3
R RECPF8
EMPNO
5S 0
EMPNO
5S 0
EMPNO 5S
EMPNAME
15A
YRMT
4S 0
EMPNAME 15 A
ADDRESS1
30A
SALARY 15P 0
CITY 30A
ADDRESS2
30A
K EMPNO
SALARY 15P 0
CITY
30A
K YRMT
STATE
2A
ZIPCODE
5P 0
EXTZPIP
4P 0
DUMMY
5A
DDATE
L
K EMPNO
If we want to select fields empno,empname,city and salary from files pf02 and pf03 then we need to
create a physical file pf08 which has 4 fields as above (pf08). Then we can create the opnqryf as follows
pgm
OVRDBF
FILE(PF08) TOFILE(SHYAMRLIB/PF02) SHARE(*YES)
OPNQRYF FILE((PF02) (PF03)) FORMAT(PF08) +
QRYSLT('salary *gt 20000') KEYFLD(*NONE) +
JFLD((PF02/EMPNO PF03/EMPNO)) +
MAPFLD((EMPNO 'PF02/EMPNO'))
CALL
PGM(RPG004)
CLOF
OPNID(PF02)
DLTOVR
FILE(PF08)
endpgm
RPG004
FSHYAM01 O E
PRINTER
FPF08
IF E
DISK
C
READ
PF08
80
C
DOW
*IN80=*OFF
C
EVAL
DEMPNO=EMPNO
C
EVAL
DEMPNAME=EMPNAME
C
EVAL
DCITY=CITY
C
EVAL
DSALARY=SALARY
C
WRITE
DETAIL

- 147 -

Tips n Facts
C
READ
RECPF8
80
C
ENDDO
C
SETON
LR
Records in PF02 is
EMPNO EMPNAME ADDRESS1
CITY
1 SHYAM
ARUNA NAGAR
TRICHY
2 SUNDAR
ARUNA NAGAR
TRICHY
3 JAYAPRAKASH
CHENNAI
and the records in PF03 is
EMPNO YRMT
SALARY
1
201
220,000
2
201
120,000
1
202
320,000
1
202
420,000
1
203
20,000
Then the output of this
Empno name
CITY
SALARY
1
SHYAM
TRICHY
220000
2
SUNDAR
TRICHY
120000
1
SHYAM
TRICHY
320000
1
SHYAM
TRICHY
420000
Here in the above example the common field in between the 2 files is empno.If we are trying to join 2 or
more physical/logical files and if both files is having a common fields then we need to represent those
fields in mapfld keyword.In the above example empno is the common field.
Since we have qryslt of selecting records greater than 20000 also the record 203 does not came.
If we want to select all the records in the file pf02 with salary greater than 20000 which is present in pf03
then we can use the same format of pf02.
pgm
OVRDBF
FILE(PF02) TOFILE(SHYAMRLIB/PF02) SHARE(*yes)
OPNQRYF FILE((PF02) (PF03)) FORMAT(PF02) +
QRYSLT('salary *gt 20000') KEYFLD(*NONE) +
JFLD((PF02/EMPNO PF03/EMPNO)) +
MAPFLD((EMPNO 'PF02/EMPNO'))
CALL
PGM(RPG004)
CLOF
OPNID(PF02)
DLTOVR
FILE(PF02)
endpgm
Question 59
Explain %wldcrd, %range in detail
(Ans)
%wldcrd
OPNQRYF FILE((PF02)) QRYSLT('empname *eq +
%WLDCRD("S*Y*M*")')
will select all the records which contains s as the first character.y as the second character and m as the
third character and remaining thing can be anything.
%RANGE
Range will select all the records in the given list.
Case 1 will return all the employees whose name lies in between shyam and sundar. For example if there
are 5 employees arun,senthil,srinivas,steve,uma then this query will return senthil,srinivas and steve
which is in between the range.
OPNQRYF FILE((PF02)) QRYSLT('empname *eq +
%range("SHYAM" "SUNDAR")')
Case 2 will retun all the employees in the range 1 t0 3. If there are 5 employees 1,2,3,4,5 then it will
return 1,2,3 in this case.
OPNQRYF FILE((PF02)) QRYSLT('empno *eq +
%range(1 5)')
Case 3 will return all the fields in between the given 2 dates
OPNQRYF FILE((PF02)) QRYSLT('ddate *eq +
%range("2002-02-02" "2003-02-02")')
Question 60
How you can implement Virtual field concepts using OPNQRYF
(Ans)
Virtual Field :

- 148 -

Tips n Facts
Consider the physical file PF03 in question 58 and if we want to generate a report by sorting all the
records in the file based on net salary where net salary = salary 0.12 * Salary . Actually net salary is
not present in any of the file but it is referring salary present in PF03 and in this case net salary is called
as the virtual field. Virtual field is nothing but the field that is not physically existing but derived from
other field(s).
The above requirement will be solved by the following ways.
Create a dummy file pf09 with no members which is similar to pf03 and also adding the new field net
salary. Since no member or record is present physically present create this file as mbr(*none) condition.
PF09
REF(PF03)
R RECPF9
EMPNO
R
YRMT
R
SALARY R
NET
R
REFFLD(SALARY)
K EMPNO
K YRMT
Then we have to write the opnqryf program using Format and MAPFLD keyword as follows.
pgm
OVRDBF
FILE(PF09) TOFILE(SHYAMRLIB/PF03) SHARE(*YES)
OPNQRYF FILE((SHYAMRLIB/PF03)) +
FORMAT(SHYAMRLIB/PF09) QRYSLT(*ALL) +
KEYFLD((NET *DESCEND)) MAPFLD((NET +
'salary - salary*0.12'))
CALL
PGM(RPG005)
CLOF
OPNID(PF03)
DLTOVR
FILE(PF09)
endpgm
and RPG005
FSHYAM01 O E
PRINTER
FPF09
IF E
DISK
C
READ
PF09
80
C
DOW
*IN80=*OFF
C
EVAL
DSALARY=net
C
WRITE
DETAIL
C
READ
RECPF9
80
C
ENDDO
C
SETON
LR
Will print all the records sorted on the basis of net salary in descending order.
Refer the fields present in pf03 in the question 58 and it will generate the output as follows.
369600 4200 4200 *12=3696.00
281600 3200 3200 * 12 = 2816.00
193600 2200 2200 * 12 = 1936.00
105600 1200 1200 * 12 = 1056.00
17600 2000 2000 * 12 = 176.00
Thus by using format and mapfld we can achieve Virtual field concept in OPNQRYF.
Question 61
Explain the usage of QSYSTRNTBL in detail.
(Ans)
This is used to convert all the data in the file into upper case. For example I have the following data in my
physical file
Empname = SHyam SHYAM shyaM shYam and shyam. If I do a simple select empname eq SHYAM then I
will retrieve only one record SHYAM. But if you want to do Ignore case in your opnqryf you need to use
this system interface program called QSYSTRNTBL which converts all the fields into upper case and then
do the select.
pgm
OVRDBF
FILE(PF02) SHARE(*YES)
OPNQRYF FILE((PF02)) QRYSLT('%strip(%XLATE(EMPNA
QSYSTRNTBL)) +
*EQ
+
%WLDCRD("S*Y*M*")')
CPYFRMQRYF FROMOPNID(PF02) TOFILE(QTEMP/PF02) +
MBROPT(*REPLACE) CRTFILE(*YES)
RUNQRY
QRYFILE((QTEMP/PF02))

- 149 -

Tips n Facts
CLOF
OPNID(PF02)
DLTOVR
FILE(PF02)
endpgm
In the above program all the 5 fields are selected.
%STRIP keyword is used to remove the leading and the trailing blanks in a particular field.
Question 62
How you change the color of a source code by using a ILE program
(Ans)
All the ile source will have 3 fields associated with it named SRCSEQ, SRCDAT, SRCDTA. The srcseq will
have the line numbers associated and the srcdat is the are in between 72 to 80. The actual data presented
will be presented in srcdta.
In srcdta the position 1 is storing the color attribute and default will be blank and so we are getting green
color in all the source. If we want to change the color of a commented line then we need to change the
color attribute to the desire color.
This can be illustrated by the program given below.
fshyam
uf e
disk
ddata
ds
31
dattr
1
1
d*arrdfn
1
2
d*spec
6
6
dcomment
7
7
d*opcode
26
31
c
read
shyam
C
DoW
Not %EOF(Shyam)
c
movel
srcdta
data
*
c
if
comment='*'
c
eval
attr=x'28'
c
endif
*
c
movel
data
srcdta
c
update testshyam
C
Read
Shyam
c
enddo
c
seton
lr
The comment will be in the 7 th position of srcdta and if we find * in that position then we are changing the
color of that line.
To run this program we need to override the source physical file in which we are implementing the
changes.
OVRDBF FILE(SHYAM) TOFILE(SHYAMRLIB/TESTSHYAM) MBR(*ALL)
And this file we are using in our ile program. Once the program was written and the file is being
overridden compile the program and call the program. Then you can see all the members in the source
physical file testshyam will have a red color display in all the commented lines.
Things to be taken care: We cannot able to compile the ile program before it is overridden else we will
get a compile time error.
You have to press f7 key to see the comment line for the first time
Question 63
Write a simple CL program to read all the records in a physical file sequentially
(Ans)
PGM
DCLF
FILE(SHYAMRLIB/PF02) RCDFMT(RECPF2)
LABEL1:
RCVF
RCDFMT(RECPF2)
MONMSG
MSGID(CPF0864) EXEC(GOTO CMDLBL(END))
SNDMSG
MSG(&EMPNAME) TOUSR(SHYAMR)
END:

GOTO LABEL1
SNDMSG
MSG('END') TOUSR(SHYAMR)
ENDPGM

Question 64
Explain the usage of VARLEN keyword in Physical file creation and varying keyword in RPGLE
(Ans)

- 150 -

Tips n Facts
VARLEN is a powerful keyword which is used in memory management. It is equivalent to varchar data
type in most of the programming languages. VARLEN work like this.
If there is a field called remarks is there and it attribute size is 255 and the user is entering normally less
than 50 characters of remarks in average. For example there are 100 such records then actual memory
allocation will be 25500 in case if we are not using VARLEN and 5200 in case of the user using VARLEN.
VARLEN variables will have 2 parts associated with it
First 2 characters contain the actual length of the data and the second part stores the actual data. If we
are moving Extension charges as the remarks then varlen variable will reserve 17+2 spaces in the
memory and not 255 characters and so 236 spaces are saved in the memory.
Example of declaring the file with varlen is
R RECPF1
EMPNO
5S 0
EMPNAME
10A
VARLEN
K EMPNAME
And another file without using VARLEN
R RECPF2
CUSNO
5S 0
CUSNAME
3A
K CUSNAME
We cannot able to use MOVE or MOVEL statement if you use VARLEN and we need to use eval. If we want
to make use of move or movel then we need to proceed as follows.
FTEMP01 IF E
K DISK
FTEMP02 IF E
K DISK
*
D
ds
DEMPNAME
1
12 VARYING
DFLDLEN
5 0 overlay(EMPNAME:1)
DFLDVAL
10 overlay(EMPNAME:3)
*
C
*LOVAL
SETLL
RECPF2
C
READ
RECPF2
C
DOW
*IN80=*OFF
*
C
CUSNAME
DSPLY
C
MOVEL
CUSNAME
FLDVAL
C
fldval
CHAIN
RECPF1
81
C
EMPNO
DSPLY
C
ENDDO
c
SETON
LR
The above program illustrates the access of varlen keyword.
1.

How will you check whether a command as given error or not?


By using the command MONMSG with suitable message identifier.

2.

How many ways you can copy records?


CPYF
CRTDUPOBJ

3.

In CL how to read a file?


RCVF

4.

In CL which command is equivalent to EXFMT?


SNDRCVF

5.

Difference between Interactive call and Batch call (SBMJOB).


If case of Interactive call it is a sequential execution. Where as in case of SBMJOB if there are
three programs called Eg: PGMA, PGMB and PGMC. Whether or not PGMA is ended PGMB and
PGMC is called.

- 151 -

Tips n Facts

6.

What is the difference between MOVE and EVAL


Using MOVE we can move values from variable of one Data type to another. In case of EVAL both
the variable types should be of same type.
MOVE just moves value from one variable to another. But EVAL first initializes the variable and
then it moves the values.

By what all ways we can insert values in a file?


CPYF
STRDFU
In STRSQL by using INSERT statement

8.

By what all ways we can view records in a file?


STRDFU
RUNQRY command
DSPPFM
In STRSQL by using SELECT statement

9.

How to find fields associated for a particular file?


Using DSPFFD (Display File Field Description)

10. What is the CL Command to find all the logical files associated for a particular physical file?
DSPDBR
11. What is the use of DSPPGMREF?
The Display Program References (DSPPGMREF) command provides a list of the system objects
referred to by the specified programs.
12. What is use of SETLL, SETGT, READ, READE, READP, REDPE, CHAIN?
SETLL:
It will Position the pointer in a file equal to or greater than the value specified in FACTOR1 field.
SETGT:
It will Position the pointer in a file greater than the value specified in FACTOR1 field.
READ:
It will read the records sequentially in a file. Mainly used in sequential file.
READE:
It will read the equal records, based on the value specified in FACTOR1 field.
READP:
It will read the prior records, sequentially in a file.
REDPE:
It will read prior equal records, based on the value specified in the FACTOR1 field.
CHAIN:

- 152 -

Tips n Facts
It is used in Indexed file.
Its Equivalent to STELL & READE. First it will Position the record in the file and then it will read
the specific record.
13. What is difference between DOW and DOU?
DOU will execute at least one time, control will enter into the loop and only after that it will check
for the condition. But in case of DOW it will first check the condition, only when the condition is
true it will enter the DO loop.
14. What is the difference between LEAVE and ITER?
LEAVE:
Quits the loop and the control will be transferred to the statement following the ENDDO
statement.
ITER:
It quits that particular iteration and control goes back to the DO statement
15. How will you eliminate leading and trailing blanks for a string.
Using %trim
16. How will you Debug when an application is running in a production environment.
a.

If the job is already running, using WRKACTJOB first we need to hold the job. (or) If the
job is not running then while submitting include this parameter
SBMJOB CALL (PGMA) HLD (*YES)

b.

Note the Job Number, Job Name & User.

c.

Issue STRSRVJOB with the Job Number, Job Name & User.

d.

STRDBG

e.

Release the job.

f.

Start Debugging.

g.

ENDDBG

h.

ENDSRVJOB

17. When will you go for a multiple occurrence data structure


If we want multiple Dimensional Array
18. While declaring what is the following meant for
S - Standalone field
DS - Data Structure
PR Prototype
PI Procedure interface
C Constant
SYNON
1.

Types of File relations?


Defined as
Owned by

- 153 -

Tips n Facts
Refers to
Extended by
Includes
2.

Types of file to field relation?


Known by
Qualified by
Has

3.

How many types of file are available in synon/2e?


Reference file (Master file)
Capture file (Transaction file)
Structure file (Field reference file)

4.

Types of Accesspath
Physical, Update, Retrieval, Resequence, Query, Span.

5.

5.

Built in Functions available in Synon


*ADD, *COMMIT, *COMPUTE, *MOVE, *MULT, *QUIT, *DIV, *CONCAT, *SUBSTRING
etc.,
Types of Objects in Synon
CRT, CHG, DLT, SLTRCD, EDTRCD

6.

Virtual Field
It is logically present in many files but physically present only in one file.

7.

If you want to avoid system performance Degradation due to Virutalization. What will you do?

Transaction file might contain many Virtual fields. So while opening the transaction file it might take
sometime, as all the records in the virtual field as to be dumped into the transaction file. So we need to
minimize the use of Virtual field.
8.

In Data Modeling what is the effect when we give *None or *All for Sharing.

When we give *All for Sharing - If same fields exists in both the files. Declaring the fields and its
attributes in one file is enough.
When we give *None for Sharing - If same fields exists in both the files. Declaring the fields in one file
is enough. But attributes as to be defined separately
9.

What will happen when you hide, drop a field?


Drop Field is not used.
Hide Field is not visible to the user. We can access at any point of time.

10. Type of EDTRCD


Edit record (1 screen)
Edit record (2 screen)
Edit record (3 screen)
11. What is Assimilation?
Process of retrieving existing externally described OS/400 file definitions into SYNON/2E design
model.
The Command is YRTVPFMDL
12. What is differentiation?

- 154 -

Tips n Facts
The process in data-modeling of creating new entities by splitting a current entity into two separate
entities.
13. What are the functions created by default for a REF file
CHGOBJ, CRTOBJ, DLTOBJ, EDTFIL & SELRCD
14. Difference between EXCEXTFUN and EXCINTFUN
Execute external functions allows to specify a high level program using an action diagram.
Implemented as separate program and has its own action diagram. Parameter of VRY is allowed.
Execute internal functions allows to specify a portion of an action diagram for repeated use in other
functions.

15. Does a RTVOBJ have to be coded before a DLTOBJ


No
16. Does an EDTFIL automatically read the database file it is built over?
Yes
17. Does a PMTRCD automatically read the database file it is built over?
No
18. Difference between EDTTRN and EDTFIL
EDTTRN Loads an entire subfile.
EDTFIL - Only loads one page of a subfile at a time.
19. Name the Access paths which are created automatically for every REF or CPT file
Physical Access path
Update Access path
Retrieval Access path
20. What are two ways to define a Select/Omit access path?
Dynamic & Static
21. What does ICF do on an action diagram line?
Insert a case statement and prompt.
22. What are the roles a parameter can take
RST, POS, MAP, VRY
23. What are different types of context
DB Context: DB1 & DB2
Device contexts: CTL, RCD, DTL, 2ND, 3RD, CUR, NXT, KEY
System contexts: JOB, PGM
Program contexts: PAR, WRK
Literal contexts: CON, CND
24. What is RTVMSG?
The RTVMSG function returns a message to the calling program. Using the message text we can
perform any number of process such as moving a character string from a database file into a field.

- 155 -

Tips n Facts
25. What is EXCMSG?
This function specifies that a request message is to be executed. The request may be any CL, OS/2
or Unix command.
26. Various data types available in Synon/2E
CDE, NBR, PCT, REF, STS, TXT, VAL, VNM, DTE, NAR, QTY, TME, IGC, SGT, PRC
27. Object types in Synon
File, Relation, Condition, Function & Access path
28. How will you Submit a Batch job in Synon
Using EXCMSG
29. Various message functions available
EXCMSG, RTVMSG, SNDCMPMSG, SNDERRMSG, SNDINFMSG, SNDSTSMSG

1. CRTRPGPGM :
USRPF parameter :
Specifies the user profile under which the compiled RPG/400 program is processed. The profile
of either the program owner or program user is used to process the program and control which objects
can be used by the program , including the authority that the program has for each object. If a program
already exists, it will not be updated to a new userprofile.
*user : The user profile of the user running the program is used.
*owner : the user profiles of both the programs owner and user are used when the progrm is
processed. The collective sets of object authority in both user profiles are used to tand access objects
during the programs processing time. Objects that are created durning the processing of the program are
owned by the programs user.
2. DSPPGMREF : Display Program References

- 156 -

Tips n Facts
The Display Program References (DSPPGMREF) command provides a list of the system objects referred to
by the specified programs.
RPG
*FILE, *DTAARA, and *PGM
CL
*FILE, *PGM, and *DTAARA these details will be listed.
3. Level Checking
When files are created, a level checking value will be assigned to the record fomrat.
When a program which uses this file is compiled, it will save the level checking value of all the record
formats used by the program.
At execution time, the program will cross check the saved level check value with that of the file
at runtime. if both
mismatches, it will give a level check error.
4. Journaling
5. SNDPGMMSG
6. Data Base File handling through CLP.
There can be only one file decalred in a CLP. This file should exist prior to compilation of the program.
Files can only be read through a CLP. writing cannot be done. When the program encouinters the
first RCVF command, it opens the file and reads the first record. At end of file, escape message CPF0864
is generated which can be minitored to see the end of file. RCVF is used for reading the file. It will read
the records one by one until the end of file is reached.
7.

Display files in CLP.


SNDRCVF
SNDF
RCVF

8. Maximum size of the file that can be opened using SEU editor
32764 records.
9. Multi format Logical files?????
10 . Field reference files: It wont be having data in it. This acts as a data dictionary.
eg: MARQUIP REF for MARQUIP.
11. Distributed Database file : DDMs
Keep these things in mind regarding DDMFs.
1) A DDMF is a "path" to data, not a data file.
2) You must have the same profile on the target machine, or set up your DDM connection to use a generic
profile (like QPGMR, and btw I think this is a terrible idea - make it sign on to the remote box with the
same profile!).
3) DDM connections seem to work pretty well for sequential I/O, but pretty lousy for lots of random I/O.
Your standard interactive application will work fine (provided you don't go nuts with database activity), but
any batch programs that perform lots of random I/O (CHAINs or START/READs) will become a real
performance DOG!
4) It seems that the remote profile will not show as having been used by the DDM signon. The "last
signon" date will not be updated. That profile attribute must only be updated when you sign on to a
terminal. Our shop has a facility to help us disable profiles that have gone unused for a period of time.
Well, if the profile is not marked as used by the DDM connection, our utility wants to disable that profile.
When it does, the DDM connection fails. Bummer.
12 I would like to know if there is any way i can use FTP commands in a CL program. I would like to
schedule this FTP job and make it to fire at a particular time during the day.Presently,it is done manually
by giving the FTP command and then typing in the FTP commands in the FTP prompt.Please let me know if
there there are ways other than FTP to download data from other servers like the mainframe. Thanks in
advance.
Ans:

- 157 -

Tips n Facts
This can be done by creating a WQCLSRC member to hold your FTP commands. Each record (source line)
in your WQCLSRC member will represent one command. For example your first line would be: username
password
In your CL program you will have to do an OVRDBF to override the INPUT file for your FTP process to the
WQCLSRC member you created as follows: OVRDBF FILE(INPUT) TOFILE(LIBRARY/WQCLSRC)
MBR(NEWMEMBER)
This instructs FTP to use your WQCLSRC member to input commands. After doing the override, just start
FTP as follows: FTP REMOTE_SYSTEM
13. to add trigger ot a PF - ADDPFTRG
remove trigger from a PF - RMVPFTRG
Some System values.
QINACTMSGQ - Help
Inactive message queue. Specifies the action the system takes when an interactive job has been inactive
for an interval of time (the time interval is specified by the system value QINACTITV). The interactive job
can be ended, disconnected, or message CPI1126 can be sent to the
message queue you specify.
If the specified message queue does not exist or is damaged when the inactive time out interval is
reached, the messages are sent to the QSYSOPR message queue.
All of the messages in the specified message queue are cleared during an IPL. If you assign a user's
message queue to be QINACTMSGQ, the user loses all messages that are in the user's message queue
during each IPL.
A change to this system value takes effect immediately. The shipped value is *ENDJOB.
QINACTITV
Inactive job time-out. Specifies when the system takes action on inactive interactive jobs. The system
value QINACTMSGQ determines the action the system takes. Local jobs that are currently signed-on to a
remote system are excluded. For example, an interactive job that is currently using the Start Pass
Through (STRPASTHR) command.
the value can be *none or 5- 300
15 .Where is the code for the signon display fo the as400. How do u customize it for your own company?
The SIGNON screen DDS will be in QGPL/QDDSSRC member QDSIGNON. U can
customize this member & compile it. ending and restarting a subsystem will bring the new screen to
effect.
If you want to change this, we can go and change the subsystem entry for initial screen to give the
QDSIGNON library so that next time when the subsystem comes up it will show the SIGNON screen from
that library and file.
16. When you copy the file using
WRKOBJ & option 3, the trigger attached with the file also will be present in the target file.
If you use CPYF command(create file *yes) , the trigger wont be duplicated.
17. For executing a PC command from the AS/400.
STRPCO - Start PC organizer.
STRPCCMD - Start PC command.
18. Ineractive Source Debugger (ISDB)
The Interactive Source Debugger (ISDB) tool provides an interactive debugging environment for
CL, COBOL, or RPG programs.
Note: The library QTEMP is required for ISDB to run. ISDB uses the library QTEMP to access files such as
the log file.
To start it:
1. Specify the necessary STRISDB parameters for your program.
2. Press Enter. ISDB is started.
The source of the program is displayed in the ISDB Source display, and you can debug the program using
the features provided there
ENDISDB

- 158 -

Tips n Facts
19. When we read a file using RCVF in a CLP, if the eof file reahed , the message CPF00864 is returned.
20 .
The order in the DDS is
1. UNIQUE
2. RECORD Format
3. List of fields.
4. Key list
5. Select/Omit Criteria.
REFACCPTH - Refer Access Path.
QMQRY- Query manager Query
AS/400 has got a tool called Query Manger. Using this we can create and run queries at run time by
passing parameters.
(A couple of months ago we went over the Midrange Computing Nov. 94 article - "Query Management
Magic". The article states how to use SQL statements with query management.)
This is helpful because queries called up from menu options can be run in batch and still have their
selection criteria entered by the user via a display program. (If you do not have a display program pass
the variable to the query and only call the query it will prompt you for the variables - but it's pretty
cryptic.)
In order to create a query using query management:
1. First, create a QQMQRYSRC source file using the CRTSRCPF command (if one does not exist).
2. Create a source member containing an SQL statement.
Columns . . . :
1 71
Browse
MPILIBB/QQMQRYSRC SEU==>
------------------------------------------------------------ MPI222Q
*************** Beginning of data***********************************
0000.01 INSERT INTO MQFLIBB/MPI123
0001.00 SELECT A.ORDNO, C.ENGNO, B.ENGNO, A.ORQTY, B.UNMSR, A.DPTNO, .REFNO, 0001.01
A.JOBNO, A.FITEM, A.FDESC, A.SSTDT, A.ODUDT, A.OSTAT
0002.00 FROM AMFLIBB/MOMAST A, AMFLIBB/ITEMASA B, AMFLIB/ITEMASA C 0003.00 WHERE (A.SSTDT
<= &START) AND (A.SHPKT <> '1') AND (A.ACREC='A')
0003.01
AND ((A.OSTAT ='10') OR (A.OSTAT='40')) AND (A.FITEM = B.ITNBR) 0004.00
AND
(A.FITEM = C.ITNBR)
****************** End of data ****************************************
3. After saving the source member create the query management query using the command: CRTQMQRY
QMQRY(library/query name)
Note: The query library must be in your library list or you will get an error message.
Also - After creating a query you always get a message at the bottom of your screen that a warning was
returned by the query manager.
4. To run a query from a CL program use the command:
STRQMQRY QMQRY(query name)
To run the query above I used the CL Command:
STRQMQRY

QMQRY(MPILIBB/MPI222Q) SETVAR((START &P002))

where START is the name of the variable I use in my query and &P002 is the CL variable being passed.
22 . DSPPGMVAR :
The Display Program Variable (DSPPGMVAR) command shows the current value of one or more program
variables in a program that is being debugged. The variables can be specified either by their variable
names or by their machine-instruction object-definition-table-vector (MI ODV) numbers. A maximum of
10 variables can be specified.
23. TRIGGER --When you issue CRTDUPOBJ command (Option 3 in wrkobj screen) , for a file which has a trigger
attached to it, it checks whether the Trigger program is available in the

- 159 -

Tips n Facts
1.What is a Sub System?
2. From a programming perspective, How can a job description be used to control the environment in
which a program runs?
3. What is the difference between the system and user portions of library list?
4. What is the relation between output queues, Spool files & Printers?.
5. Provide an example of how a library list can be used to set up a development environment?
6. What is the concept of single level storage?
7. Define Mirrored & RAID-5 DASD protection.
8. What is the process access group(PAG) on an AS/400
Retrieval of Workstation's OUTQ & Printer
Response 1
The Retrieve Device Description (QDCRDEVD) API with format DEVD0600 provides this information. The
Output Queue, Output Queue Library, and the Printer can be found at decimal offsets 334, 344, and 354
respectively.
This API can be found in the Configuration APIs chapter of the System API Reference
Response 2
If
you
really
do
mean
workstation
and
not
job:
You will need to use the QDCRDEVD API. Format DEVD0600 contains the information you are asking for.
If
you
RtvJobA

really

mean

job

information

and

not

workstation:

Scheduling a Job to get executed automatically at some specified time or time interval
WRKJOBSCDE - Work Job Schedule Entry.
Here we can specify the Frequency, Scheduled Date, Scheduled Day , Time. Also you can specify dates to
be omitted.
STRCPYSCN : This command will allow you to see the display in another user's screen.
Steps: Issue an STRCPYSCN command with the target screen's device ID.
Then the system will send a break message to the target user. The user can respond with G or C. If the
response is G, the copy screen will start functioning.
To stop the CPYSCN, the target devise should issue the command ENDCPYSCN or do a SIGNOFF.
The system value which says whether the previous shutdown was normal or abnormal - QABNORMSW. It
will be 0 if the shut down was normal else it will be 1.
The system values cannot be passed as parameter to a program.
Q. I've been using the Q* APIs in ILE RPG and CL programs for >several years with no problems, but I
can't locate the bindable APIs >on my AS/400. Where can I find these APIs?
A. The ILE bindable APIs are found in service programs located in >library QSys. Binding directory QILE in
library QSys contains a >directory entry for each of these service programs. When you compile ILE objects
that use a bindable API, specify this binding directory >for the BndDir parameter and the compiler will find
the necessary >objects.
30th March 2001.
If you ever needed a command line where it was not accessible (for example, after a long-running query
displays your output, while viewing your spooled report, during a test of your new display files, or for just
looking at your joblog), then use Command Line On Demand.
This can be done in two ways:
1.SETATNPGM QCMD -- Please note that this goes away after your job ends.

- 160 -

Tips n Facts
2.CHGUSRPRF yourprofile ATNPGM(QCMD) -- This change is permanent. Every time you need the
command line, press your attention key and behold -- the Command Entry line. Want to view your joblog?
Press F10!
Code
SETATNPGM QCMD or CHGUSRPRF yourprofile ATNPGM(QCMD)
Using QCMD, you will get the Command Entry screen, not the Command Line Window. To get to the
Command
Line
Window
use
QUSCMDLN
instead.
**************************************************************88888
If you would like to give error messages with COLOR based on severity, use the HexaDecimal color codes
to send Colored Error messages. You can change the program to send messages with different colors
based on severity.
Code
PGM
DCL
DCL
DCL
DCL
DCL
DCL
DCL
DCL
DCL
DCL
DCL
DCL
DCL
DCL
DCL
RTVMSG

PARM(&MSGID)
VAR(&MSG) TYPE(*CHAR) LEN(78)
VAR(&MSGID) TYPE(*CHAR) LEN(7)
VAR(&SEV) TYPE(*DEC) LEN(2)
VAR(&MSGDTA) TYPE(*CHAR) LEN(78)
VAR(&BLUE) TYPE(*CHAR) LEN(1) VALUE(X'3A')
VAR(&WHITE) TYPE(*CHAR) LEN(1) VALUE(X'22')
VAR(&RED) TYPE(*CHAR) LEN(1) VALUE(X'28')
VAR(&GREEN) TYPE(*CHAR) LEN(1) VALUE(X'40')
VAR(&PINK) TYPE(*CHAR) LEN(1) VALUE(X'38')
VAR(&TURQ) TYPE(*CHAR) LEN(1) VALUE(X'30')
VAR(&YELL) TYPE(*CHAR) LEN(1) VALUE(X'32')
VAR(&RIMG) TYPE(*CHAR) LEN(1) VALUE(X'21')
VAR(&UNDER) TYPE(*CHAR) LEN(1) VALUE(X'24')
VAR(&DELIM) TYPE(*CHAR) LEN(1) VALUE(X'20')
VAR(&COLOR) TYPE(*CHAR) LEN(1)
MSGID(&MSGID) MSGF(QCPFMSG) MSG(&MSG) SEV(&SEV)

IF
COND(&SEV = 00) THEN(CHGVAR VAR(&COLOR) +
VALUE(&WHITE))
IF
COND(&SEV > 00) THEN(CHGVAR VAR(&COLOR) +
VALUE(&PINK))
IF
COND(&SEV >= 30) THEN(CHGVAR VAR(&COLOR) +
VALUE(&YELL))
IF
COND(&SEV >= 60) THEN(CHGVAR VAR(&COLOR) +
VALUE(&RED))
CHGVAR
CHGVAR

VAR(&MSGDTA) VALUE(' ' *CAT &COLOR *CAT &MSG)


VAR(&MSGDTA) VALUE(&MSGDTA *TCAT &DELIM)

SNDPGMMSG MSG(&MSGDTA)
ENDPGM
*********************************************************
Connect to a different AS/400 system while working on another and comeback when finished.
Connect to one system while working on another
This technique works with V4R4--make sure that the AS/400 is in the TCP/IP Host table entries.
From one AS/400 system command line type:
TELNET "AS/400 system name"
New Sign-on display will appear for the new AS/400 system

- 161 -

Tips n Facts
Log-on to the new system
When finished working you can sign-off, then hit ESC key then option 99 to end telnet.
You should come back to your previous AS/400 session after ending Telnet.
SQL Tips 10th Aug 2001
Connecting to a remote database.
Command : CONNECT Press F4.
This will ask you whether you want to connect to Local or remote database. Choose remote database.
Then you can prompt on the new screen which you get, to see which are the remote databases available.
If you dont have any Entry, you can change or ADD entries in to the Relational Database Directory Entry
by sing the command WRKRDBDIRE.
Is there a way to determine in a CL program when a user has pressed F3 or F12 to cancel the Run Query
(RUNQRY) command?
There sure is. In fact, here are two methods, courtesy of Tom Liotta of PowerTech Group
( http://www.400security.com <http://www.400security.com> ) and Carsten Flensburg.
Pressing F3 or F12 places a character 1 in byte 103 or 104 respectively.
To test for the use of these keys, Tom uses the QUSRJOBI (Retrieve Job Information) API. Tom provided
his code, which I have modified slightly.
First, I shortened the lines that were too long for the format of this newsletter. Second, I added the return
commands to the do groups.
Third, I added the OUTTYPE(*PRINTER) parameter to the RUNQRY
command. That's not necessary, but trapping a cancel request probably makes more sense when output is
to be sent to a printer, since OUTTYPE(*DISPLAY) causes RUNQRY to be prompted repeatedly
until the operator cancels it. In other words, the test will always prove true
with OUTTYPE(*DISPLAY), so why bother to test it?
Tom had separate tests for F3 and F12. If you don't care which key the operator pressed, you can combine
the two conditions under one IF statement and have only one do group.
Tom adds, "This code can be used in many cases for functions that do not
send messages when canceled. I believe this is standard for UIM-based functions."
dcl &a_len *char 4 /* Bin Data/Entry length */ dcl
/* length is variable. It */
/* must be in &A_LEN.
*/
dcl

&a_rcv

*char 1000 /* Receiver Variable, the */

&msgdta *char 256

dcl &Action *char 20 +


value( 'RUNQRY RCDSLT(*YES)' )
Qsys/runqry Range1 outtype(*PRINTER) rcdslt(*YES)
/* ---------------------------------------------------*/ /*
---------------------------------------------------*/
chgvar

%bin( &a_len 1 4 )

Qsys/call QUSRJOBI
&a_rcv
+
&a_len
+
'JOBI0600'
+
'*'
+
'
' +
)

Test for cancel

307

(+

- 162 -

*/ /*

Tips n Facts
/*

Test job status for *CANCEL (F12)

if ( %sst( &a_rcv 104 1 ) *eq '1' )

*/

do

chgvar
&msgdta
(+
'Action' *bcat +
&Action *bcat +
'cancelled.' +
)
Qsys/sndpgmmsg msgid( CPF9897 ) +
msgf( QSYS/QCPFMSG ) +
msgdta( &msgdta ) +
msgtype( *INFO )
return
enddo
/*

Test job status for *EXIT (F3)

*/

if ( %sst( &a_rcv 103 1 ) *eq '1' )

do

chgvar
&msgdta
(+
'Action' *bcat +
&Action *bcat +
'cancelled.' +
)
Qsys/sndpgmmsg msgid( CPF9897 ) msgf( QSYS/QCPFMSG ) +
msgdta( &msgdta ) +
msgtype( *INFO )
return
enddo
/* --------*/ /*

RUNQRY was not canceled

*/ /* ------------------------------------*/

The second method comes from Carsten Flensburg. He uses the


QWCRTVCA (Retrieve Current Attributes) API to query the two attributes holding the flags for F3 and F12,
then resets the two job attributes using the QWCCCJOB (Change Current Job) API.
Load the following code into an RPGLE source member named GETXIT. Compile it using the Create Bound
RPG Program (CRTBNDRPG) command. (You can recompile it as a module and, if you wish, add it to a
service program.)
**-- Parameter: -------------------------------------------- D Fkey
s
3
**-- QWCRTVCA API: ---------------------------------------- D CurAtr
Ds
D AtNbrAtrRtn
10i 0 D AtAtrLen1
10i 0 D AtAtrKey1
10i 0 D
AtAtrDtaTyp1
1a
D
3a
D AtAtrDtaLen1
10i 0 D F12
1n
D
3a
D AtAtrLen2
10i 0 D AtAtrKey2
10i 0 D AtAtrDtaTyp2
1a
D
3a
D AtAtrDtaLen2
10i 0 D F3
1n
D
3a
**
D CurAtrLen
s
10i 0 Inz( %Len( CurAtr )) D FmtNam
s
8a Inz( 'RTVC0100' )
D KeyFldNbr
s
10i 0 Inz( 2 ) D KeyFlds
Ds
D
10i 0 Inz( 301 ) D
10i 0 Inz( 503 )
**-- QWCCCJOB API: ---------------------------------------- D ChgAtr
Ds
D CaAtrFldNbr
10i 0 Inz( 2 ) D CaAtrKey1
10i 0 Inz( 1 ) D CaAtrLen1
10i 0 Inz( 1 )
D CaAtrVal1
1a Inz( '0' ) D CaAtrKey2
10i 0 Inz( 2 )
D CaAtrLen2
10i 0 Inz( 1 )
D CaAtrVal2
1a Inz( '0' ) **
D ApiError
Ds
D AeBytAvl
10i 0 Inz( 8 ) D AeBytRtn
10i 0 Inz( 0 ) **
C
*Entry
Plist

- 163 -

Tips n Facts
C
C
C
C
C
C
C
C
C
C
C
C
C
C
**
C

Parm
Fkey **
Call
'QWCRTVCA'
Parm
CurAtr
Parm
CurAtrLen C
Parm
KeyFldNbr C
Parm
ApiError **
Call
'QWCCCJOB'
Parm
ChgAtr
Parm
ApiError **
Select
When
F3
Eval
Fkey
= 'F3' C
Eval
Fkey
= 'F12' C
Eval
Fkey
= *Blanks C

Parm
Parm

FmtNam
KeyFlds

When
F12
Other
EndSl

Return

To test this routine, create a CL program called QRY001CL from the following source code:
Dcl

&Fkey

Runqry Q1
Call
If

*Char

RcdSlt( *YES ) OutType( *PRINTER )

GETXIT &Fkey
( &Fkey

*GT ' ' ) GoTo EndPgm

/* ...continue processing

*/

Endpgm:
EndPgm
QRY001CL executes the RUNQRY command specifying that the record select panel should be presented
before execution. Then it calls the GETXIT RPG/IV program to have it check if the Exit or Cancel key was
pressed.
I have read that DSN-less connections are faster for Active Server Pages than using ODBC DSN
connections. How can I connect to my AS/400 without a DSN, and why would I want to?
A DSN, or Data Source Name, is defined via the ODBC Driver manager in the Windows Control Panel. This
causes an entry to be made into the system registry that records all of the connection information you
enter into the Control Panel. The problem with using a DSN is that every time you connect to the AS/400,
the target computer must look up the connection information in the Windows registry. This is not a factor
if you are casually connecting from applications like Excel, Access, or SQLThing, but if you are using Active
Server Pages, these registry lookups do add a small amount of time to the connection process. Using a
DSN-less connection will give you finer control of connection attributes; in fact, you can control your
connection attributes on a page-by-page basis. In addition, by not requiring a DSN, your application or
Web pages are easier to distribute to target computers (i.e., you do not have to go to the target computer
and use the control panel to create a DSN). There are many connectivity options that you can use when
connecting to the AS/400. These options can cause your connection string to become quite complex.
Instead of typing in all of the options, you can let Windows create a connection string for you by creating
a Universal Data Link (UDL) file. A UDL file is a file-persisted set of information that tells a database
program where and how its data files are stored on a computer or network and how to connect to a data
source. In this case, you will use the UDL file as a quick way to build an ODBC or OLEDB connection
string. First, open a Command Prompt window, switch to a directory you want to use, type COPY CON
A.UDL, and press the Enter key. Next, press the F6 key to send a ^Z command to the console. You should
see the text, "1 file copied" and then be returned to a command prompt. You have just created a zero
length file called A.UDL in your target directory.
Next, pull up Windows Explorer, right click on the A.UDL file, and select the Properties menu. This will
open an interactive window where you can set the provider and all connection options for that provider.
Once you have your settings correct, press Apply, then OK to save the UDL information. Next, open the
UDL file with a text editor (e.g., Notepad), and voila, you have a pre-formed, almost-perfect connection
string. But there is one problem with the string: it still points to an ODBC DSN. To make the string perfect,
remove the DSN information from the extended properties and replace the single quotes (')with double
quotes (") so the string will not be confused in your ASP page. Finally, after the string

- 164 -

Tips n Facts
"Provider=MSDASQL.1;" place the following information: Driver=Client Access ODBC Driver (32-bit). This
string lets the MSDASQL OLEDB provider know that it should use the Client Access ODBC driver when it
attempts to connect. Here is a code snippet that shows a proper connection string with lots of options:
ConStr = "Provider=MSDASQL.1;Driver="
ConStr = ConStr & "Client Access ODBC Driver (32-bit);Password=SECRET;" ConStr = ConStr & "Persist
Security
Info=True;User
ID=HFA;Extended"
ConStr
=
ConStr
&
"Properties=""SYSTEM=172.16.2.200;CMT=0;"
ConStr = ConStr & "DBQ=WEBOE,HD1100PD,HD1100PO;NAM=0;"
ConStr = ConStr & "DFT=5;DSP=1;TFT=0;TSP=0;DEC=0;XDYNAMIC=1;" ConStr = ConStr &
"RECBLOCK=2;BLOCKSIZE=32;SCROLLABLE=0;"
ConStr
=
ConStr
&
"TRANSLATE=1;LAZYCLOSE=1;LIBVIEW=0;
ConStr = ConStr & "REMARKS=1;CONNTYPE=0;SORTTYPE=0;
ConStr = ConStr & "PREFETCH=0;DFTPKGLIB=QGPL;LANGUAGEID=ENU;" ConStr = ConStr &
"SORTWEIGHT=0;SSL=2;MAXFIELDLEN=32;"
ConStr
=
ConStr
&
"COMPRESSION=1;ALLOWUNSCHAR=0;"
ConStr
=
ConStr
&
"SEARCHPATTERN=0;MGDSN=0;""" Set Con1 = Server.CreateObject("ADODB.Connection" Con1.Open
ConStr
For
more
information,
check
my
company's
Web
site
at
http://www.sqlthing.com
<http://www.sqlthing.com> in the coming weeks for a more complete look at how the settings for
connections can effect performance.
I would like to know, If there is a way of loading the data onto the memory without accessing
the file. As the no. of users accessing the same data would be more.So I would like to load the
data into the memory. or use a pointer concept(RPG ILE) to access the data from the memory,
Rather than the file.
The Set Object Access (SETOBJACC) command temporarily changes the speed of access to an object by
bringing the object into a main storage pool or purging it from all main storage pools. An object can be
kept main storage resident by selecting a pool for the object that has available space and does not have
jobs associated with it. Repeated use of the command can cause a set of objects to be resident in a main
storage pool.
I have recently started using Run SQL Statement (RUNSQLSTM) and have saved myself a lot of time.
Instead of taking hours to develop an RPG program, I can whip up a functionally equivalent SQL statement
in a few minutes. However, I have one slight problem. RUNSQLSTM produces a status report that prints
out on the users' printers. They are annoyed, and it's a waste of paper. How can I keep these reports from
printing?
You would probably benefit from creating an output queue, say QUSRSYS/GARBAGE, to which you could
direct unwanted output. You can add a job schedule entry (ADDJOBSCDE) to clear the queue automatically
each day.
To direct the output of RUNSQLSTM to the new garbage queue, issue the Override with Printer File
(OVRPRTF) command for file QSYSPRT, as the following CL code illustrates:
OVRPRTF QSYSPRT OUTQ(QUSRSYS/GARBAGE)
RUNSQLSTM SRCFILE(mylib/SQLSRC) SRCMBR(mymbr) COMMIT(*NONE) DLTOVR QSYSPRT

With SQL, Sometimes Less Is More(Processes that happen when we issue an SQL statement)
Most of the consulting work that I do involves helping companies with SQL access issues against their
OS/400 legacy systems. Typically, these companies are doing Active Server Pages or Java Server Pages to
display information from the system via the Web. This week, I want to share one of the most common
performance problems that I see in my practice and how you can avoid sending me or another consultant
money by proactively solving the problem.
The issue is something I call "lazy-fare" programming. When you program using record level access, you
are used to opening a physical file or logical file and having all of the fields available to your program just
by referencing them. Usually, when RPG programmers construct SQL statements, theytend to use the SQL
* character to indicate to SQL to return all fields from the physical file. (A lot of SQL programmers are

- 165 -

Tips n Facts
guilty of this shorthand, too, by the way.) So, the following statement might be found in an ASP or JSP
page to list customers that match an inquiry screen:
SELECT * FROM CUSMAS WHERE CUSNAME LIKE 'ABC%'
Now, this is fine and dandy SQL. If there is a logical file associated with the physical file with the
CUSNAME field as the first
key, it will probably return records quite quickly. However, the number of
records per second that a query can return is directly effected by the number of fields in the physical file.
To wit: If CUSMAS has 10 fields, the query will run really fast, probably more than 2,000 records per
second. But, if CUSMAS has 150 fields, the query will return noticeably slower, probably under 750 records
per second.
<<Communications and memory>>
It is important to understand what is happening during the processing of the SQL statement on both the
client and the server to understand why there is such a huge disparity in performance outlined in the
example above.
On the client side, whether you are using a Java program or a Visual Basic program with Active-X Data
Objects (ADO), the following steps occur when you attempt to run the above query:
* Preparation
* Execution
* Fetch
In the preparation phase, the query is sent to the server and the server parses the SQL statement to
determine what information (fields) the client wants and where the information comes from (physical file).
The AS/400 query optimizer then looks at the physical file and its associated logical files to determine the
best way to get the data that you want. Once this is done, the optimizer has what is called an execution
plan. Having a plan on how to get the data, the AS/400 then gets information from the system catalogue
about each field that your query is asking to return and sends this information (metadata) back to the
client application. The metadata consists of the name of the field, the data type, length, etc. Once the
client application gets the metadata, it constructs objects in memory to hold the returned query
information. At this point, the client can send the AS/400 an execution request. The execution request
causes the AS/400 to look for the data that satisfies the query request by using the execution plan that it
formulated. Once it finds records that satisfy the request, the AS/400 sends an acknowledgement
message to the client that the execution request is complete.
Having received the notification, the client can then request that the AS/400 return one or more records
from the open query using by issuing a fetch request. The AS/400 will acknowledge this request with one
or more records from the open data path. (That one or more caveat depends on how the client issues the
fetch request and the size of the fetch buffers. But that is a different column...) Now that you understand
what is happening during the execution of an SQL query, lets examine why SELECT * is a bad idea.
<<Practical Applications>>
If you use SELECT * and a physical file contains only ten fields, then only 10 pieces of metadata are
returned to the client application. Then, the client application only has to allocate 10 buffers to hold the
returned fields. The AS/400 only has to read 10 fields of information per record and only has to transform
10 fields from internal representation to pretty client-side representation. Now, contrast this with a
physical file that contains 150 fields of information. The AS/400 has to look up and return metadata on
150 fields. The client has to interpret 150 pieces of metadata to allocate objects or buffers to hold 150
pieces of information. The AS/400 has to read 150 fields and transform them from internal storage format
to pretty client format. Also, since the number of fields is larger, the size of the records is larger, so fewer
records fit into a transmission buffer causing more packets to be sent and acknowledged in transferring
the information. Easy to understand, right?
Ok, so why is SELECT * bad? It's like my momma used to tell me, only put on your plate what you are
going to eat. Most of the programs I see that have SELECT * do not require all of the fields in the physical
file, just 5 or 10. Why squander your resources gathering data that you are not going to look at anyway?
Name your fields and you increase the throughput of your information, thereby increasing the scalability of
your system on both the client and server side.
If you don't believe me, here are a few numbers from the real world. I had a client that was doing the
above-mentioned customer listing web page. His query was a SELECT * going against a physical file with
179 columns of information. His program was only using 15 fields of information from the result set.

- 166 -

Tips n Facts
Before he changed the query, the execution phase of the query took .4 seconds and the records per
second clocked in at 250. After changing the query to only ask for the fields required, the execution phase
went from .4 seconds to .1 seconds (less metadata and client memory allocation), and the records per
second returned from the AS/400 went to over 1,200. Also, the time it took for JSP to render the page
went from 2.2 seconds down to .9 seconds.
Remember, less is sometime more.
Run CL Commands From Interactive SQL
Question:
When I am using Interactive SQL/400 (i.e., STRSQL) and need to run
a CL command, I have to exit SQL, run the command, and re-enter SQL. Is there any way to run system
commands within an interactive SQL session?
Answer:
Here's the deal. IBM has not provided a way to run CL commands from an SQL session, but you can create
a stored procedure to run them. Here are two examples to get you started.
The first one creates a stored procedure, called EXCCMD, to run program QCMDEXC:
CREATE PROCEDURE mylib/exccmd
(IN cmd CHAR (32000), IN len DEC (15,5)) LANGUAGE CL NOT DETERMINISTIC
NO SQL
EXTERNAL NAME QSYS/QCMDEXC
PARAMETER STYLE GENERAL
Once you have created this stored procedure, you will be able to run CL commands using the SQL CALL
command:
call exccmd ('wrkoutq garbage',15)
Here's the SQL command to create a stored procedure called CMD, which brings up a pop-up window like
the one you get when you press F21 from Screen Entry Utility (SEU):
CREATE PROCEDURE mylib/cmd
LANGUAGE CL
NOT DETERMINISTIC
NO SQL
EXTERNAL NAME QSYS/QUSCMDLN
PARAMETER STYLE GENERAL
To run CL commands, type the following command in your interactive SQL session:
call cmd
To resume entering SQL commands, press Enter with an empty command line, or press F12.
Running SQL commands from CLP
Sample content of the SQL member
The member name is SAMPLESQL the source file name is QCLSRC. Member type is SQL.
INSERT INTO CHAM/SPLF (SPLF) VALUES('TEST VLAUE DPK')
CL Program to in invoke the SQL.
Source File./Member --- QCLSRC/SQMPLESQLC
Member Type
-- CLP
The content is
RUNSQLSTM SRCFILE(CHAM/QCLSRC) SRCMBR(SAMPLESQL) +
COMMIT(*NONE)
The program fetches the SQL source at runtime. So, even if we change the content of the SQL file, we
need not recompile the CLP Program.

[Home]

- 167 -

Tips n Facts
Frequently Asked Questions
This is a long page of text, and takes about 30 seconds to load on a 28.8 dial-up line.
Table of Contents

1.

How do I declare a table or array in RPG IV?

2.

Where can I buy copies of Bob Cozzi's books on RPG IV and other topics?

3.

How do I declare an array with a dynamic number of elements?

4.

How do I do concatenation in RPG IV like I do in CL?

5.

What good are the %TRIM, %TRIML and %TRIMR built-in functions?

6.

Are there any useful C runtime functions that I can call from RPG IV? And what are they?

7.

What's the difference between CHAIN and SETLL? Is there a performance advantage?

8.

Can you clear up the confusion in the different releases of RPG IV and OS/400 and ILE?

9.

How does the CONST keyword work with Procedure parameters?

10.

What is the current list of available built-in functions in Version 4, Release 4 of OS/400?

11.

Why doesn't the new %CHAR built-in function work with numeric values?

12.

How do I use the new File Built-in Functions?

13.

What is the new E operation extender used for by the operation codes?

14.

What is the RUNSQLSTM (run SQL Statement) command and how do I use it?

15.

What's new in Version 5 and RPG IV?

16.

How do I handle the Error and LR indicator on a CALL, when using CALLP?

17.

How do I enable a "workstation time-out" feature in RPG?

18.

What is the range of the 'I' (integer) data types in RPG IV?

19.

What service program do I need to bind to when using CGI RPG IV?

20.

How do I debug a remote (i.e. "batch") job from an interactive job?

21.

How do I convert character to numeric?


How do I declare a table or array in RPG IV?

To declare an array or table, use the RPG IV definition specification. The "D spec" allows you to code the
array or table on a single line. The keyword to use is DIM (dimension). This is where you specify the
number of elements in the table or array. For example, to create an array named ITEMS with 200
elements, each 10 characters in length, the following Definition spec can be used:
.....DName+++++++++++EUDS.......Length+TDB.Functions++++++++
D Items
S
10A Dim(200)
To declare an array that is also used as a data structure subfield, you must declare the array within the
data structure. Unlike RPGIII, RPG IV does not allow the array to be declared, and then used as a data
structure subfield. The following technique illustrates declaring an array as a data structure subfield:

- 168 -

Tips n Facts
.....DName+++++++++++EUDS.......Length+TDc.Functions++++++++
D MyDs
DS
D CustNo
7P 0
D MonthlySls
11P 2 Dim(12)
You cannot code the same array as a stand-alone field and as a data structure subfield in the same
program in RPG IV.
Back to Top
Where can I buy copies of Bob Cozzi's books on RPG IV and other topics?
All of Bob Cozzi's books are available through retail stores, or directly from Midrange Computing
magazine. Have you book store order any title (from Midrange Computing) or call Sheila Gough at
Midrange Computing at:
U.S. Orders: (800) 477-5665 or (619) 931-8615

Ext. 208

Outside the US:


In Europe, dial: 44 (0) 171-344-3863
In the Asia Pacific region please call: 61-2-9976-3153
Midrange
5650
El
Carlsbad,
CA
Voice: 619-931-8615 Fax: 619-931-9935

Camino

Real,
92008,

Computing
#225
USA

Click here to link to the MC web page for ordering and information:
You can also order directly from the web, by searching Amazon.com for my books, and then ordering
them. Click here to go to our page that simplifies searching Amazon.com for Cozzi's RPG books.
Back to Top
How do I declare an array with a dynamic number of elements?
In RPG IV, the new (V3 R7) ALLOC, REALLOC and DEALLOC operation codes can be used to allocate
memory. This means that at run time, you can go out to the system and ask it to assign storage to the
program that was not allocated to the program when it was evoked.
These operation codes can be used to allocate memory up to 16MB. The allocation can be assigned to a
pointer variable. In RPG IV, pointers have the data-type of asterisk (*). All that is needed is to allocate
memory to a pointer that is used with the BASED keyword of the desired dynamic array. The example that
follows illustrates this technique:
.....DName+++++++++++EUDS.......Length+TDc.Functions++++++++++++++++++
D DynoArr
S
7P 0 Dim(10000) based( pDynoArr)
D nSize
S
10i 0
.....CSRn01..............OpCode(ex)Extended-factor2++++++++++++++++++
C
Eval
nsize = %size(DinoArr) * 64
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq
C
Alloc
nSize
pDynoArr
** We now have enough storage allocated for 64 elements.
C
Eval
nsize = %size(DinoArr) * 70
C
ReAlloc nSize
pDynoArr
** We have changed the allocation to enough storage for 70 elements
C* ... code to use the array goes here...
C
Dealloc(N)
pDynoArr
** We have just returned the storage to the system.
To increase or decrease the number of elements in the dynamic array, use the REALLOC operation code.
Simply change the number of bytes that need to be allocated, and call REALLOC with the new size in
Factor 2 and the original pointer variable in the Result field. REALLOC allocates new storage of the size
specified, and copies the original data to that new location. Then it frees ("deallocates") the original
storage.

- 169 -

Tips n Facts
IMPORTANT: Always remember to DEALLOC anything you ALLOC. That is always free up memory that you
have allocated otherwise memory leaks will be created.
If you are not on V3 R7, you can still use dynamic memory by calling one of the system APIs or linking
into the QC2LE binding directory and calling the C runtime MALLOC and DEALLOC functions.
Back to Top
How do I do concatenation in RPG IV, like I do in CL?
In the initial release of RPG IV, the plus sign can be used to do simple concatenation. When the expression
of any of the enhanced operation codes includes string expressions, then the plus sign is considered a
concatenation operator. In later release of RPG IV, the built-in function %EDITC can be used to allow
numeric fields to participate in simple concatenation.
The example below illustrates the basic concatenation (line 4) and the enhancement introduced in OS/400
V3 R7.
.....FFILENAME++IFEASFRlen+LKeylnKFDEVICE+.Functions++++
0001 FCUSTMAST IF E
K
Disk
.....CSRn01..............OpCode(ex)Extended-factor2+++++++++++++++++++++++++++
.....CCRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq
0002 ** RPG IV on OS/400 V3 R1 and later...
0003 C
CustNo
Chain
CustMast
73
0004 C
Eval
Msg = CustName + ' is ' + CM_Status
0005 ** RPG IV on OS/400 V3 R2 and V3 R7 and later...
0006 C
Eval
Msg = 'Customer: ' + %EditC(CustNo:'Z') +
0007 C
' is ' + CM_Status
In addition, the traditional RPG IV CAT operation code can be used for concatenation.
Back to Top
What good are the %TRIM, %TRIML and %TRIMR built-in functions?
The use of the TRIM functions is very limited, in that they support only the use of character variables and
data structures. Numeric fields, and zero-fill values are not supported. They do, however, provide some
useful function for string handling. For example, in RPG IV, one line of code is all that's needed to leftadjust a value within a field. For example:
.....CCRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq
C
ExFmtCustMaint
C
Eval
CustName=%TrimL(CustName)
Typically, the %TRIM function is the only one of the three that get used. The other two, however, do have
their place.
%TRIM removes trailing and leading blanks from a field, and returns the remaining value, in place, within
the expression. The returned value is treated similar to a constant value with leading or trailing blanks.
%TRIML removes leading blanks (trim-left) from a field, and returns the value in place, within the
expression.
%TRIMR removes trailing blanks (trim-right) from a field, and returns the value in place, within the
expression.
The table below illustrates the mechanics of the TRIM functions.
Built-In
Function

Original Value

%TRIM(compname)

' The IBM Corp.

' 'The IBM Corp.'

%TRIML(compname) ' The IBM Corp.

' 'The IBM Corp.

%TRIMR(compname) ' The IBM Corp.

' ' The IBM Corp.'

Returned Value

'

It would be wonderful if the TRIMx functions also supported a second parameter that indicated the
character to be trimmed. It could default to blanks, but would accept any value. The internal MI
instruction TRIML actually does this already, but TRIML and TRIMR do not directly map to this MI

- 170 -

Tips n Facts
instruction. In addition, it would be even nicer if the second parameter supported multiple characters. That
is you would be able to specify %TRIMR(CompName : ' .') and it would strip off blanks and periods from
the end of the COMPNAME field. -- Dreamer...
Back to Top
Are there any useful C Runtime APIs that I can call from RPG IV?
There are several C runtime APIs available to the RPG IV developer. In OS/400 version 3, release 1 the
scope of these APIs is limited.
The CALLB operation code can be used to directly call the C runtime APIs, provided they don't require
"pass by value" parameters.
In V3 R2 and later, parameters can be passed by reference or by value. In addition, Prototypes are
supporte for calling procedures written in RPG IV or other languages.
The current list of C-related runtime functions is large. To support these functions in your RPG IV
programs you need to compile the program so that it runs in a normal activation group, and binds to the C
runtime library. A binding director is conveniently provided for just this purpose. For example:
CRTBNDRPG pgm(myPgm) DFTACTGRP(*NO) BNDDIR(QC2LE)
By specifying DFTACTGRP(*NO) and BNDDIR(QC2LE), you open up your RPG IV program to the world of C
runtime functions. These functions include high-level math and time formatting routines. See the RPG
Developer Network News articles on integrated these functions in RPG IV for more information.
Another cool thing about QC2LE is that the ILE C/400 runtime includes the full set of open AS/400 MI
instructions. That is the AS/400 assembly language can be called directly from RPG IV by prototyping their
C/400 functions. For example, to call the Convert Characters to Hexadecimal Symbols MI instruction, you
would call the 'cvthc' C runtime function. For example:
The following RPG IV code should compile on any version of OS/400 that includes RPG IV.
.....DName+++++++++++EUDS.......Length+TDc.Functions++++++++++++++++++
D szCharVal
S
20A Inz('ABCDEFG')
D szHexVal
DS
D szHex1
LIKE(szCharVal)
D szHex2
LIKE(szCharVal)
D nCharLen
S
9B 0
.....CSRn01..............OpCode(ex)Extended-factor2++++++++++++++++++
** if you want to avoid converting trailing blanks, use this stmt.
C
''
CheckR szCharVal
nCharLen
** or if you want to convert trailing blanks, use this stmt.
C
Eval
nCharLen = %size(szCharVal) * 2
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq
** This converts '123' to 'F1F2F3'
C
CALLB
'cvthc'
C
Parm
szHexVal
C
Parm
szCharVal
C
Parm
nCharLen
** This converts 'F1F2F3' to '123'
C
CALLB
'cvtch'
C
Parm
szCharVal
C
Parm
szHexVal
C
Parm
nCharLen
Just a few things to remember when using the C runtime APIs.

The names are case-sensitive. That is 'cvthc' must be specified in lower case or it will not be
found.

These functions are located in the OS/400 C-runtime library and must be bound using the QC2LE
binding directory.

- 171 -

Tips n Facts

Parameters that require pass-by-value restrict the API to being called with newer releases of RPG
IV, via procedure prototypes.

C functions that have return values cannot be called by RPG IV under OS/400 version 3, release
1.

Until you move to V3 R2 or, even better, V3 R7, the number of interfaces that can be accessed by
RPG IV is limited. In fact, the HexToChar, CharToHex functions are about all that are useful.

Under later releases of RPG IV, procedure prototypes allow access to all of the C runtime
functions. This includes those nice little date and time formatting functions, such as asctime.

For more details and examples of using procedure prototypes with the C runtime library, see the article on
interfacing RPG IV with the C/400 language runtime library on the RPG Developer Network News page.
What's the difference between CHAIN and SETLL? Is there a performance advantage?
There are two important differences between CHAIN and SETLL.
1.

The CHAIN operation applies a record lock to files that are open or update. The SETLL operation
does not apply the lock.

2.

The CHAIN operation copies the record's data to the input buffer for the program. The SETLL
operation does not.

More Details
The CHAIN operation performs a random GET operation to the database file. If the operation is successful,
the data in the record is copied to the input buffer. If the CHAIN operation fails, a record-not-found
condition is signaled, typically via Resulting Indicator 1. If the database file has been opened for UPDATE,
the CHAIN operation places a record lock on the retrieved record. No other application can access this
record for update while this lock is applied. Furthermore, if another program has issued a lock to the
recording being accessed, the CHAIN operation will wait for the the database time-out period. If the record
is released during that period, the CHAIN operation continues. If the record is not released by the other
program, the CHAIN operation fails with an exception.
CHAIN with NO LOCK
The CHAIN operation supports the NO LOCK operation extender (the old "half-adjust" column). In RPG III
you specify an N in the operation extender column, in RPG IV, you specify CHAIN(n) for the operation
code. Using NO LOCK allows you to access a record without a record lock being applied, regardless of the
way in which the file is open. The record's data, however, is still copied to the input buffer when NO LOCK
is specified.
The SETLL operation performs a quasi READ LESS THAN OR EQUAL operation. If the operation is
successful, a READ PRIOR is performed. The database record's data, however, is not copied to the input
buffer, nor is there a record lock applied to the accessed record. Hence, SETLL is probably the operation
code to use for testing the existence of a record. However, if the record needs to be retrieved, CHAIN
more effective.
Performance
If your requirement is to check for the existence of a record, traditionally the CHAIN operation is used.
However, since CHAIN copies the record's data to your program's input buffer, there is additional overhead
required for the CHAIN operation. The SETLL can be used to effectively accomplish the same task as the
CHAIN test. Use SETLL with resulting indicator 3 (equal). If this indicator is set on, a record exists whose
key matches they value specified in Factor 1. If your requirement is that the record eventually be updated,
subsequent to the existents test, you should consider using of CHAIN.
Back to Top
Can you clear up the confusion in the different releases of RPG IV and OS/400 and ILE?
RPG IV is the next generation of the RPG language. RPG III is the original version of AS/400 RPG/400. The
name "AS/400 RPG/400" is that given to the IBM compiler package for distribution on the AS/400. This
compiler package compiles various versions of RPG, including RPGII and at least two releases of RPGIII.

- 172 -

Tips n Facts
As of OS/400 Version 3 release 1, IBM changed the name of this compiler package to "AS/400 ILE
RPG/400". The reason for this name change was to identify that fact that the compile now includes a
version of RPG that targets the Integrated Language Environment (ILE), that is RPG IV.
ILE was first shipped in OS/400 Version 2, Release 3. However, only the C language compiler produced
code that targeted this environment. First, a word about ILE.
ILE is the new, "native" runtime environment for Programs, on the AS/400. Under OS/400 Version 2
Release 3, IBM introduced a new program model. This basically means that new features and interfaces
became available. However, IBM did not just port some runtime environment to the OS/400 operating
system, it actually re-wrote code, and wrote new code that, essentially, changed the way OS/400 works.
This new code provides support for a mixed set of high-level languages.
Previously, RPG and CL had their own little runtime environment, COBOL had it's own, C had it's own, and
so on. Under ILE, all programming languages run in ILE. The same "environment" is used for COBOL, C,
RPG and CL.
However, to take advantage of ILE, new compilers needed to be created. As for RPG, rather than convert
the existing RPGII and RPGIII compilers, IBM, who was designing a new version of RPG anyway, decided
to target ILE with the new compiler. This would simultaneously provide a new version of RPG and an ILE
targeted compiler.
Names Are Important
A good friend of mine once said, "names are important" in the programming world. If a field is called
"Rhinoceros", does it represent its use or purpose? Okay, so perhaps in traditional RPG "Iguana" is a
better choice for this example. (Shorter name.)
During the development of RPG IV, two distinct issues arose. First, the internal name for RPG IV, was "ILE
RPG". This was not a code name, but rather the name IBM used to refer to the new compiler. After all, it
was targeting ILE, why not refer to it as "ILE RPG"? Second, the re-architecture of RPG came into
question.
Unfortunately, the internal name "ILE RPG" began to be leaked out to the public. Several magazine writers
and IBMers not involved in the development of RPG IV continued to use the term "ILE RPG" when referring
to RPG IV. I suppose these people still refer to the AS/400 as SilverLake or perhaps even Olympic.
Then when IBM announced the compiler package or product name as "AS/400 ILE RPG/400" it only added
to the confusion. IBM dropped the ball when promoting the RPG IV name. They are, after all, set up to
market their products with their product names. The name of one programming language included in a
product that contains nearly seven full compilers isn't high priority.
RPG IV is the version of RPG that targets ILE. OS/400 V3R1 compatible RPG IV can also target what is
now called "the original program model" or simply OPM. OPM is just a name that has been given to the
original runtime environment of RPG and CL under OS/400. This is the environment in which RPGIII and
CL run. Under ILE, however, the original native environment is emulated, that is, ILE isn't an environment
at all, it is native OS/400, whereas, OPM is now an environment under ILE. Some very clever
programming and design went into this, don't you think? Not very many other operating systems, if any,
provide this kind of continuity.
RPG IV -- Release what?
RPG IV was first shipped with OS/400 Version 3, Release 1. This is now referred to as RPG IV release 1.
But don't worry about remembering releases of RPG IV.
Under OS/400 Version 3, Release 6, IBM enhanced RPG with procedures, many more built-in functions,
and several new data types. This is referred to as RPG IV release 2.
Then, OS/400 Version 3, Release 2 was announced. It brought the original release of RPG IV (on the CISC
boxes) up to the same level as RPG IV under V3R6. Are you confused yet? Me too!
Under OS/400 Version 3, Release 7, IBM added a couple of enhancements, most notably they increased
the length of a field name to a number so large not even magazine authors that don't write real-world
code could complain about it anymore. They also added one or two new data types, rounding out RPG IV
so that it supports all AS/400 data types, except variable length fields. This version of RPG IV is known as
RPG IV Release 3.

- 173 -

Tips n Facts
The following table identifies the current releases of RPG IV. Note that RPG IV releases do not necessarily
coincide with releases of the operating system.
RPG
Release

IV

OS/400 Version/Release

CISC or RISC

V3 R1

CISC

V3 R6

V3 R2

V3 R7

RISC

V4 R2

RISC

V3
R5
See note 1

V4 R3

RISC

V4 R4 (February 1999)

RISC

V4 R5 (Summer 2000)

RISC

RISC
CISC

(speculation)

CISC

NOTE 1: It is speculated that IBM may ship a final "clean up" release of OS/400 for CISC that would
included a large level of compatibility with OS/400 V4 R5.
The release levels of RPG IV are only important if you want to keep track of that kind of thing. One
disappointing issue is that unless you stay on the most current release of OS/400, you don't get all the
cool new features in RPG IV. Even if you stay current, you can't target prior releases if you use any of the
new features. In fact, even if you use a new feature that doesn't depend on an operating system
enhancement, it can't be used for back releases. This is because of the way the TGTRLS (target release)
feature has been implemented. Basically, if you're on V4 R2 and you do a TGTRLS(V3R2M0) the compiler
calls the actual compiler for V3 R2. It doesn't have a built-in syntax checker that says "This feature
requires an OS/400 upgrade so don't allow it, or this one is okay so accept it." It iscalling the same
"binary" compiler code that is on any old V3 R2 system.
Which means, for example, that if you want to take advantage of the new compiler directives, but you
often have to target a prior release, you can't use those directives. For example, /IF DEFINED does
nothing for the executable code that's generated, but is not supported when TGTRLS(V3R2M0) is
specified. ;( Bummer!
So now we know about RPG IV release levels and how the term "ILE RPG" got into our vocabulary. So let's
clear up another term, the name of the RPG language. The big one is the term "RPG/400". There is not
programming language called "RPG/400". The language most often called "RPG/400" is RPGIII. However,
back in the System/38 days, the System/38 RPG language was called RPGIII. When the AS/400 was
announced, programmers wanted to give themselves an advantage on their rsum. So they began calling
AS/400 RPGIII, "RPG/400". Then to make matter worse, when RPG IV was announced, programmers
thought that the number "IV" in "RPG IV" was less than the "400" in "RPG/400". So they decided to call
RPG IV, "ILE RPG". Well let's set the record straight. The table below lists the RPG language names, their
incorrect name, and the proper name.
Commonly
used
Wrong Name

Formal Name

Proper (correct) Name

- 174 -

Tips n Facts
RPG/36

System/36-compatible RPGII

RPGII

RPG/38

System/38-compatible RPGIII

RPGIII

RPG/400

RPGIII

RPGIII

ILE RPG

RPG IV

RPG IV

Back to Top
How does the CONST keyword work with Procedure parameters?
If you are certain that the called procedure will NOT modify a parameter, the CONST keyword can provide
several benefits.
1.

It automatically converts a field of a similar data type, to the length and type required by the
parameter.

What this means, is say a parameter is a 15 position pack field, with 5 decimals. Normally, you'd have to
specify a Pdk(15,5) field for the parameter. However, if the parameter is read-only, you can specify CONST
on the Prototype and Procedure Interface for the parameter. When you do this, the compiler automatically
converts the value (say it's a literal of 27) to the size and type required by the parameter. This works
really cool with DATE fields. A date for any format can be passed as a parameter value when that
parameter value is CONST.
2.

Performance is improved because the compiler can generate more optimized code for the CONST
parameter.

CONST can be used on calls to procedures or programs. We use it all the time when calling QCMDEXC
from within RPG IV. All three parameters of the QCMDEXC program are CONST values. The example code
below can be used as the PROTOTYPE to call QCMDEXC from within RPG IV. To call it using this prototype,
specify something like: CALLP run('addlible myLib' 14) in your calculation specs.
.....DName+++++++++++EUDS.......Length+TDc.Functions++++++++++++++
D Run
PR
ExtPgm('QCMDEXC')
D cmdstr
3000A Const Options(*VarSize)
D cmdlen
15P 5 Const
D cmdDbcs
3A Const Options(*NOPASS)
Note: if you're using CodeStudio or IBM's Code/400 as your RPG IV editor under Windows, you could
simply highlight the above source code within your Internet Browser, and copy it to the Windows
clipboard. Then activate CodeStudio (or Code/400) and use the Paste function to insert the code directly
into the editor. Pretty cool, huh? <g>
Back to Top
Why doesn't the %CHAR built-in function work with numeric values?
Under the initial release of OS/400 Version 4, Release 2, the %CHAR built-in function was introduced.
However, the function, as designed, only converted DATE values to character values. This proved to be too
restrictive a use for this function. In OS/400 V4R4 IBM will added function to %CHAR allowing it to convert
all forms of non-character data to character. In that release %CHAR works with numeric values.
D Amount
C

Eval

7P 2 Inz(123.45)
text = 'The amount is: ' + %Char( amount )

The TEXT field would contain the following after the EVAL operation is performed:
'The amount is: 123.45'
Unlike %EDITC, the %CHAR built-in function trims off leading blanks. However, %EDITC provides much
more editing power than %CHAR. Use %CHAR for basic number to character conversion.
Back to Top

- 175 -

Tips n Facts
How do I use the new File Built-in Functions?
OS/400 Version 4, Release 2 RPG IV supports the elimination of the Resulting Indicators. In their place,
several new built-in functions have been introduced. Most of these new built-in function provide
information about the result of File operations similar to the Result indicators. But instead of coding
Resulting indicator 3, for example, to check for the end-of-file condition, you simply check the value of
the %EOF built-in function.
The built-in functions that replace the Resulting Indicators include:
%FOUND, %EOF, %EQUAL. In addition, there are %OPEN, %STATUS, and %ERROR. Mysteriously missing
is %LOCK to check for a record lock condition.
%FOUND returns an *ON or *OFF condition if the previous File operation returns a record-found condition.
This is particularly useful on the CHAIN operation. Realize, however, that when CHAIN sets on Resulting
indicator 1, a not-found condition is signaled. Whereas, without coding Resulting Indicator 1, the %FOUND
built-in function returns the found condition.
%EOF can be used to check for end-of file, beginning of file, or subfile full conditions. A READ and READE
return %EOF=*ON if the end of file is reached. READP and READPE return %EOF=*ON if the beginning of
file is reached. The WRITE operation returns %EOF=*ON if the WRITE operation to a subfile detail record
returned a subfile-full condition.
%EQUAL is used by the SETLL operation to indicate that it detected a record in the file with a key equal to
that of the value specified in Factor 1. Since SETLL does not read the record, does not lock the record, and
does not copy the data into the input buffer, SETLL is much faster and less of an impact on the
performance of the application than other operations, such as CHAIN. Use CHAIN when you need to
retrieve the record, use SETLL and %EQUAL when you need to only check for the existence of a record.
%OPEN is used to check to see if a file has already been opened. The built-in function returns *ON if the
file is opened, otherwise it returns *OFF.
Back to Top
What is the new E operation extender used for?
The new (E) operation extender is used to cause the %ERROR and %STATUS built-in functions to be
initialized after an operation is performed. That is, these built-in functions and the E operation extender
are used in place of Resulting Indicator 2 on all operation codes that currently support Resulting Indicator
2 as an error condition.
For example, to check to see if a record is locked, you would code the following:
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq
C
CustNO
Chain(E) CustMast
C
if
%ERROR = *ON
C
Select
C
When
%STATUS = 1221
C
exsr
UpdateNoRead
C
When
%STATUS = 1218
C
exsr
RecdLocked
C
endSL
C
ELSE
C
if
%FOUND( CustMast )
C
exsr
whatever...
C
endif
C
endif
The concept is to first check %ERROR for a generalized error condition, and then check %STATUS for the
specific error. Note that no resulting indicators are used in the previous example. The normal not-found
condition is checked using the %FOUND built-in function rather than testing Resulting Indicator 1.
Back to Top
What's new in OS/400 Version 5 RPG IV?
So much is new in RPG IV with OS/400 Version 5, that I wrote an article about it. Read my article about
the enhancements to RPG IV in OS/400 Version 5.
There are a few significant enhancements in RPG IV in OS/400 Version 4, Release 4.

- 176 -

Tips n Facts

The %CHAR built-in function has be fixed. It now functions like it was supposed to in the first
place. You can wrap a numeric value in %CHAR and a nicely edited character form of the number
is returned. The edited form includes the decimal, trimmed off leading blanks, and a negative
sign.

The FOR loop provides a free-format version of the DO operation code. With the FOR operation,
you can begin a loop operation and continue iterating through the loop until a variable equals a
limit value. The syntax for the FOR operation is enhanced with the TO, BY and DOWNTO
keywords. The TO operation indicators the upper limit for the looping, while the BY keyword
identifies the increment value for the loop counter. Alternatively, you can specify the DOWNTO
keyword to loop backwards from a large value to a small value.

The OPENOPT keyword is added to the Header specification. This keyword can be used along with
its one and only parameter *INZOFL to cause overflow indicators to be set off when their
corresponding printer file is closed and then re-opened during the program. So use
OPENOPT(*INZOFL) when needed.

In subroutines, the LEAVESR operation can now be used to exit a subroutine immediately.
Effectively this is a "glorified goto" operation that branches to the ENDSR statement of a
subroutine.

Back to Top
How do I handle the error and LR indicator on a CALL, when using CALLP?
The short answer is, you can't. The long answer is, it depends on the OS/400 release level.
In releases prior to OS/400 V4 R2, there is no way to detect the LR situation. Errors are trapped either by
specifying the PSSR subroutine, or using an ILE error/event handling API. In V4R2 and later, its a little
easier. RPG IV supports the %ERROR built-in function. This built-in allows you to test the result of the
CALLP operation. Unfortunately, we have to use a silly "E" operation extender. Apparently it is easier to
code CALLP(E) and then check the status of %ERROR for a *ON or *OFF condition than it is to not use (E)
and still check %ERROR. %ERROR is only set when the E operation extender is used. ;(
As for checking if the called program set on LR before returning, the use of CALLP does not provide this
capability.
Back to Top
How do I enable a "workstation time-out" feature in RPG?
There are five things required to provide a time-out option on any interactive workstation file. This
capability allows an RPG program to receive control before an end-user presses a Function key or Enter.
Some of the uses for this kind of function include:

Providing a marquee for a schedule via a subfile

Update the time displayed on the workstation at regular intervals

Refresh the information, such as a news display, periodically

As mentioned, there are five things required to achieve workstation time-out. Those five things are:
1.

Add the INVITE keyword to the Workstation display file DDS. This is a file-level keyword.

2.

Use the WAITRCD parameter of CRTDSPF to set the desired time-out period.

3.

Add the MAXDEV(*FILE) keyword to the File specification for the Workstation device file.

4.

Write the desired display file formats to the display using the normal methods.

5.

Use the READ operation code to read Display File name, not the Record format name.

You must avoid using EXFMT to the display file as this operation code does not support workstation timeout.

- 177 -

Tips n Facts
FMarquee
F

CF

WORKSTN MAXDEV(*FILE)
SFILE(detail:rrn)

C
Write
Header
C
Write
Footer
C
Do
12
rrn
C
Write
Detail
C
enddo
C
Write
SFLCTLFMT
C
Read
Marquee
Back to Top
What Binding Directory Do I need to bind to when using CGI RPG IV?
The QTCP library contains the service program named QTMHCGI which includes access to all the necessary
objects to accessing any Qtmh* API. So set the BNDSRVPGM parameter to QTMHCGI in QTCP.
If V4R2 or earlier use QTMHCGI service program:
>> BNDSRVPGM(QTCP/QTMHCGI)
If later than V4R2 use:
>> BNDSRVPGM(QHTTPSVR/QZHBCGI)
Back to Top

How do I debug a remote (i.e. "batch") job from an interactive job?


The ability to debug another job has been a long standing requirement for AS/400, now iSeries
programmers. It isn't as difficult as it may seem. Whether you need to debug a batch job, another
interactive job, or an HTTP server job (browser/CGI program), the following steps can get you started.
Starting Debug for a Remote Job
1.

2.

Determine the job name of number for the job you need to debug.

Use WRKACTJOB and note the Job name, number and user profile ID.

If debugging a CGI program, look in the joblog of the job for CPF message HTP2001.

Run the Start Service Job (STRSRVJOB) command specifying the job to be debugged

o
3.

Run Start Debug (STRDBG) on the program to be debugged

o
4.

e.g., STRSRVJOB JOB(012345/usrid/jobname)

e.g., STRDBG PGM(libnam/pgmname) UPDPROD(*YES | *NO)

At this point the program in the remote job is under debug control from your job

You can now set break points (if you're debugging an RPG IV program, the source will
have already been displayed).

Press F12 from within the debugger to return to CMD entry after setting your break
points.

5.

Evoke the program in the remote job. If you you're doing a web browser session, hit the SUBMIT
button.

6.

You interactive job will "break" at the debug break points and you can debug application
normally.

Ending Debug for a Remote Job


Ending the debug session should be done in the following sequence.

- 178 -

Tips n Facts
1.

From your debugging session, run the End Debug (ENDDBG) command

2.

Then run the (End Service Job) ENDSRVJOB command

Your session is no longer controlling the remote job. The remote job continues normally.
Special Considerations when Debugging a Web Browser/CGI Program
To debug a CGI program that is evoked from a Web Browser session running from the standard IBM HTTP
Web Server, you need to do the following in addition to the above.
Before Starting Debug for a Web Browser/CGI Session/Program

End the HTTP Server using the following CL command:

ENDTCPSVR *HTTP

WARNING!!! -- You MUST include *HTTP as the parameter for ENDTCPSVR otherwise all
TCP/IP server jobs (including telnet, ftp, smtp, etc.) will be ended. And this is a bad
thing. IBM sucks for making *ALL the default for ENDTCPSVR.

Restart the HTTP Server using the following CL command:

STRTCPSVR *HTTP HTTPSVR(DEFAULT '-minat 1 -maxat 1')

This restarts the HTTP server with once instance of each job type (one for CGI, one for
Java, etc.)

Using WRKACTJOB in the QHTTPSVR subsystem location the jobs running.

The job whose joblog contains the CPF message HTP2001 is the one to be debugged.

After Finishing the Debug Session

End the HTTP server using the following CL command:

ENDTCPSVR *HTTP

Restart the HTTP server using the following CL command, unless your shop has another process
for starting the HTTP server:

STRTCPSVR *HTTP

Your system should be back to normal.


Back to Top
How do I convert character to numeric
In OS/400 Version 5, Release 2 RPG IV was enhanced such that the %DEC and %INT built-in functions
now support a character value on their first parameter. Simply specify the character field or literal value as
the first parameter for %DEC, then indicate the length and decimal positions and the built-in function
converts the character field to numeric. The %INT function works similar, except no length attributes are
required since it only works with whole numbers.
D szWebFVal
S
C
Eval
Back to Top
The

7A Inz('123.45')
AmtDue = %DEC(szWebVal : 5:2)

RPG
Copyright

1997-1999
Revised: January 16, 2003.

Robert

- 179 -

Developer
Cozzi,
Jr..

All

rights

Network
reserved.

Tips n Facts
How to share data across more than one module?
Serializing access to modules using the THREAD(*SERIALIZE) control specification keyword ensures
sequential access to global data within each module, but it does not ensure sequential access to shared
data across modules. It is up to the programmer to ensure that only one thread can access shared data at
one time.
Two or more modules can access same data, if

IMPORT/EXPORT keywords are used on the definition specifications


Files are shared across modules
Data is based on a pointer where the pointer is available to more than one module

For Example:
Procedure A in Module A passes a pointer to procedure B in module B, and procedure B saves the pointer
in a static variable. Now both modules have access to the based storage at the same time as the thread
running in module A is accessing the storage. Once procedure B returns, another thread could call a
procedure in module B and access the based storage. Serialization of access to static storage within
modules A and B would not prevent simultaneous access of the same storage in each module.
*------------------------------------------------------------------------*.--------------.
*|
|
*|some storage |<----------------pointer to shared storage
*|
|(called MyPtr in module A)
*'--------------'(saved as a static variable in module B)
*Module A
*Global variables in Module A
D MyPtr
S
*
D SomeStorage
S
10A based(MyPtr)
*
C
eval SomeStorage ='Init value'
C
callp ProcB(MyPtr)2
C
eval SomeStorage =*BLANKS 3
*------------------------------------------------------------------------*Module B
*Global variables in Module B
D SavedPtr
S
*
D SomeStorage
S
10A based(SavedPtr)
*ProcB in module B
P ProcB
B
export
D ProcB
PI
D PtrParm *
C
eval SavedPtr = PtrParm 6
C
return 7
P
E
*ProcB2 in module B
P ProcB2
B
export
D ProcB2
PI
D PtrParm
*
C
if SomeStorage ='Init value'8
C
....
C
return
P
E

- 180 -

Tips n Facts
How to Avoid Deadlock Between Modules
In some situations, it may be necessary to control the synchronization of modules using facilities other
than the THREAD(*SERIALIZE) control specification keyword. For example, consider the situation where
two procedures are being called at the same time: PROC1 and PROC3. Even though there is no actual
recursive calling; if PROC1 calls PROC4, it will wait for MOD2 to unlock; and if PROC3 calls PROC2, it will
wait for MOD1 to unlock. The procedures will not be able to complete their calls, since each module will be
locked by the thread in the other module. This type of problem can occur even with serialization of calls to
a module and is referred to as deadlock.
Thread-1

Thread-2

MOD1

Proc 1

MOD2

Proc 3

CALLP PROC4
------

CALLP PROC2
------

Proc 2

Proc 4

..

..

Deadlock Example
This example shows that you cannot access more than one procedure in the same module at the same
time using ILE RPG synchronization techniques.
To avoid the problem in the above example and ensure thread safe applications, you can control the
synchronization of modules using techniques provided by C or by platform functions. Any callers of PROC1
or PROC3 for each thread should do the following:
1. Restrict access to the modules for all threads except the current thread, always in the same order
(MOD1 then MOD2)
2. In the current thread, call the procedures in the modules (PROC1 and PROC3)
3. Relinquish access to the modules for all threads in the reverse order of step 1 (MOD2 then MOD1).
One thread would be successful in restricting access to MOD1. Since all users of MOD1 and MOD2 use the
protocol of restricting access to MOD1 and MOD2 in that order, no other thread can call procedures in
MOD1 or MOD2 while the first thread has restricted access to the modules. In this situation you have
access to more than one procedure in the same module at the same time, but since it is only available to
the current thread, it is thread safe.
This method should also be used to synchronize access to shared storage.
|
Table 33. Built-In Functions
Name Arguments Value Returned
Function
Example
%ABS numeric expression absolute value of expression
Syntax :- %ABS(numeric expression)
Description: - This function will return absolute
value of the numeric expression specified in the
parameter.
If the value of the numeric expression is negative
value then the built in function will return a value
with the negative Sign removed.
Example :D Fld1
S
6p 3 INZ(-123.456)
/free
Fld1 = %ABS(Fld1);
// Fld1 is now 123.456
/end-free

- 181 -

Tips n Facts
%ADDR variable name address of variable

Syntax :- %ADDR(Variable)
%ADDR(Variable(Index)
%ADDR(Variable(expression)
Description: - This Built in function will return the
address of the specified variable. It may only be
compared with and assigned to items of type
basing pointer.

%ALLOC number of bytes to allocate pointer to allocated


storage

Example :D Fld1
S
2p 0 INZ(99)
D Ptr
S
*
D Result S
2p 0 BASED(Ptr)
/free
Ptr = %ADDR(Fld1);
Dsply Result;
// Result is now 99
/end-free
Syntax :- %ALLOC(num)
Description :- This Built in function will returns a
pointer to a newly allocated heap storage of
the length specified
Example :/free
Pointer = %ALLOC(200);
// Allocate an area of 200 bytes
/end-free
Syntax :- %CHAR(expression {:format})

%CHAR graphic, UCS-2, numeric, date, time,


or timestamp expression {: date, time,
or timestamp format}
value in character format

Description: - This Built in function converts


graphics, numeric, date, time and time Stamp to
Character value.
D
D
D
D

Date
Time
Fld1
Result

Example :S
D
S
T
S
6P 2
S 50

inz(D2001-11-20)
inz(T22.23.44)
inz(22.11)
varying

/free
Result = It is + %CHAR(Time :*USA) + on
+ %CHAR(Date :*USA);
// Result is now It is 12:33 PM on 11/20/2001
Result = %CHAR(Fld1);
// Result is now 22.11

%CHECK comparator string:string to be


checked{:start position}
first position of a character that is not in the comparator
string, or zero if not found

/end-free
Syntax :- %CHECK(Comparator :Base {:Start})
Description: - This built in function will returns
the first position of the string base that contains a
character that does not appear in string
comparator.
If all of the characters in Base also appear in
comparator then function will return 0.
Example :D String
S
D Start
S
D Pos
S
/free

- 182 -

6a inz(AACDEF)
2p 0 inz(3)
2p 0

Pos = %CHECK(A :String);

Tips n Facts
// Pos is now 3
Pos = %CHECK(C :String :Start);
// Pos is now 4
Pos = %CHECK(AACDEF :String);
//Pos is now 0
/end-free
%CHECKR comparator string:string to be
checked{:start position}
last position of a character that is not in the comparator
string, or zero if not found

Syntax :- %CHECKR(Comparator :Base {:Start})


Description :- This built in function will returns
the last position of the string base that contains a
character that does not appear in string
comparator.
If all of the characters in Base also appear in
comparator then function will return 0.
Example :D String
S
D Start
S
D Pos
S

6a inz(CDEFAA)
2p 0 inz(4)
2p 0

/free

Pos = %CHECKR(A :String);


// Pos is now 4
Pos = %CHECKR(F :String :Start);
// Pos is now 3
Pos = %CHECKR(AACDEF :String);
//Pos is now 0
/end-free
%DATE {value {: date format}} the date that corresponds to
the specified value,or the
current system date if none is specified

Syntax :- %DATE(expression :{Date Format})


Description :- This Built in function converts
value from Character, numeric or time Stamp to
Date
Example :D String
D Fld1
D Date
D TimeStam

S 8A
inz(04/05/96)
S 6P 0 inz(112001)
S
D datfmt(*ISO)
S Z

/free

%DAYS number of days number of days as a duration

Date = %DATE(String :*MDY);


// Date now contains 1996-04-05
Date = %DATE(Fld1 :*MDY);
// Date now contains 2001-11-20
Clear TimeStam;
Date = %DATE(TimeStam);
// Date now contains 0001-01-01
/end-free
Syntax :- %DAYS(Number)
Description: - This built in function converts a
number into a duration that can be added to a
date or time Stamp
Example :D Date1
S
D inz(D2001-11-20)
D Result
S
D
/free
Result = Date1 + %DAYS(15);
// Result is now 2001-12-05
Result = Date1 - %DAYS(10);
// Result is now 2001-11-10

- 183 -

Tips n Facts
/end-free
%DEC numeric expression {:digits:decpos} value in packed
numeric format

Syntax :- %DEC(numeric expression {:Precision :


Decimal Places})
Description: - This Built in function Converts the
value of the numeric expression to decimal
(packed) format.
Example
D Fld1
D Fld2
D Result

:S
S
S

7p 3 inz(1234.567)
9s 5 inz(73.73442)
15p 5

/free

%DECH numeric expression :digits:decpos half-adjusted value


in packed numeric format

Result = %DEC(Fld1) + 0.011;


//Result is now 1234.57800
Result = %DEC(Fld2 :5 :0);
// Result is now 73.00000
/end-free
Syntax
:%DECH(numeric
:precision :decimal places)

expression

Description: - This built in function is same as


%DEC except that if numeric expression is
a decimal or flat value than half adjust is
applied to the value of numeric expression
when converting to the desired position.
D Fld1
D Result

Example :S
9s 5 inz(73.73642)
S
15p 5

/free

%DECPOS numeric expression number of decimal digits

Result = %DECH(Fld1 :5 :2);


// Result is now 73.74000
/end-free
Syntax :- %DECPOS(numeric expression)
Description :- This built in function returns the
number of decimal positions of the numeric
variable
Example :D Fld1
S 8p 3 inz(123)
D Fld2
S
2p 0 inz(23)
D Result S 15p 0
/free
Result = %DECPOS(Fld2 * 2.01);
// Result is now 2
Result = %DECPOS(Fld1);
// Result is now 3
/end-free

%DIFF date or time expression: date or time


expression: unit
difference between the two dates, times, or timestamp
in the specified unit

Syntax :- %DIFF(Op1 :Op2 :*MS| *s| *MN| *H|


*D| *M| *Y)
Description: - This Built in function calculates
difference (Duration) between two date or time
values.
The first and second parameter must have the
same or compatible type.
The following Combination are possible :Date and Date
Time and Time

- 184 -

Tips n Facts
TimeStamp and TimeStamp
Date and TimeStamp
Time and TimeStamp
Example :D Date1
S D inz(D2001-11-20)
D Date2
S D inz(D2001-10-15)
D Time1
S T inz(T12.30.54)
D Time2
S T inz(T01.30.54)
D Result
S 15p 0
/free
Result = %DIFF(Date1 :Date2 :*D);
// No. of Days difference between two Dates 36
Result = %DIFF(Date1 :Date2 :*M);
// no. of month Difference between two Dates 1
Result = %DIFF(Time1 :Time2 :*H);
// No. of Hour difference between two times 11
Result = %DIFF(Time1 :Time2 :*MN);
// No. of minutes difference between two times
660
/end-free
%DIV dividend: divisor the quotient from the division of the two
arguments

Syntax :- %DIV(N :M)


Description :- This Built in function returns the
integer portion of the quotient that result from
dividing operands n by m
Example :D Fld1
S
8p 0 inz(123)
D Fld2
S
8p 0 inz(23)
D Result S
15p 0
/free
Result = %DIV(Fld1 :Fld2);
// Result is now 5
/end-free
Syntax :- %EDITC(numeric :editcode {:*ASTFILL
| *CURSYM })

%EDITC non-float numeric expression:edit


code {:*CURSYM | *ASTFILL |
currency symbol}
string representing edited value

Description: - This Built in function returns a


character result representing the numeric value
edited according to the edit code.
Example :D Salary
S 9p 2 inz(1000)
D Result
S 12A
/free
Result = %EDITC(Salary * 12 :A
:*CURSYM) ;
// Result is now $12,000.00

%EDITFLT numeric expression


representation of float

character

external

display

Syntax :- %EDITFLT(numeric Expression)


Description :- This Built in function converts the
value of the numeric expression to the character
external display representation of float
Example :D Fld1
S
8f inz(50000)
D Result A 10a Varying
/free
Result = %EDITFLT( Fld1);
// Result
+5.000000000000000E+004
/end-free

- 185 -

is

now

Tips n Facts
%EDITW non-float numeric expression:edit
word
string representing edited value

Syntax :- %EDITW(numeric :editword)


Description :- This built in function returns a
character result representing the numeric value
edited according to the edit word
Example :D Amount
S
9p 2 inz(1234567.89)
D Result
S 40a
D EditW
C
, , , , &Rupees&
&Paise
/free
Result = %EDITW(Amount :EditW);
// Result is now 12,3,4567 Rupees 89
Pasie
/end-free
Syntax :- %ELEM(Array Name)

%ELEM array, table, or multiple occurrence


data structure name
number of elements or occurrences

Description: - This Built in function returns


number of elements in the specified array, table or
multiple occurrence data structure.

%EOF {file name} 1 if the most recent file input operation or


write to a
subfile (for a particular file, if specified) ended in an
end-of-file or beginning-of-file condition
0 otherwise

Example :D Arr1
S
5A dim(10) varying
D Result S
2p 0
/free
Arr1(1) = Se;
Arr1(2) = En;
Result = %ELEM(Arr1);
// Result is now 10
/end-free
Syntax :- %EOF(File Name)
Description: - This built in function returns 1, if
the most recent read operation or write to subfile
ended in an end of file or beginning of the file
condition, otherwise it return 0.
Example :F Infile IF E K Disk
/free
Read Infile;
Dow not %EOF(Infile);

%EQUAL {file name} 1 if the most recent SETLL (for a


particular file, if
specified) or LOOKUP operation found an exact match
0 otherwise

%ERROR 1 if the most recent operation code with extender E


specified resulted in an error
0 otherwise

- 186 -

Read Infile;
Enddo;
Syntax :- %EQUAL(File name)
Description: - This Built in function returns 1 if
the most recent relevant operation found an exact
match, otherwise it returns 0.
Example :F CustFile IF E K Disk
/free
// check if the file contains a record with a
key matching Cust
Setll Cust CustFile;
If %EQUAL(CustFile);
// an exact match found in the file
endif;
/end-free
Syntax :- %ERROR
Description: - This Built in function returns 1, if
the most recent operation with extender E

Tips n Facts
specified resulted in an error condition.
Example :/free
Exfmt(e) Inrec;
If %ERROR;
Exsr CheckError;
Endif;
/end-free
Syntax :- %FLOAT(numeric expression)

%FLOAT numeric expression value in float format

Description: - This Built in function converts the


value of the numeric expression to float format.

%FOUND {file name} 1 if the most recent relevant operation


(for a particular
file, if specified) found a record (CHAIN, DELETE,
SETGT, SETLL), an element (LOOKUP), or a match
(CHECK, CHECKR, SCAN)
0 otherwise

Example :D Fld1 S 5p 0 inz(1)


D Fld2 S 5p 3 inz(3)
D Result S 5p 3
/free
Result = %FLOAT(Fld1 / Fld2);
// Result is now 0.333
/end-free
Syntax :- %FOUND(File Name)
Description: - This Built in function returns 1, if
the most recent relevant file operation found a
record, a string operation found a match, or a
Search operation found an element.
Example :F CustFile IF E K Disk
/free
// Check if the customer is in the file
Chain Cust CustFile
If %FOUND(CustFile);
Exsr Handle;
Endif;
/end-free
Syntax :- %GRAPH(chat-expr | grap- expr |UCS2
expr {:ccsid)})

%GRAPH character, graphic, or UCS-2


expression
value in graphic format

Description :- This Built in function converts the


value of the expression from character, graphic or
UCS 2and returns a graphic value

%HOURS number of hours number of hours as a duration

Syntax :- %HOURS(number)
Description: - This Built in function converts a
number into a duration that can be added to a
Time or Time Stamp value.
Example :D Time1 S T inz(T11.12.10)
D Time2 S T
/free
Time2 = Time1 + %HOURS(1);
// Time2 is now 12.12.10
/end-free
Syntax :- %INT(numeric expression)

%INT numeric expression value in integer format

Description: - This Built in function converts the


value of the numeric expression to integer. Any
Decimal digits are truncated
Example :-

- 187 -

Tips n Facts

%INTH numeric expression half-adjusted value in integer


format

D Fld1 S 5p 3 inz(12.345)
D Result S 5p 3
/free
Result = %INT(Fld1);
// Result is now 12.000
/end-free
Syntax :- %INTH(numeric expression)
Description: - This Built in function is same as
%INT except that if the numeric expression is a
decimal or float value, half adjust is applied to the
value of the numeric expression when converting
to integer type.

%LEN any expression length in digits or characters

Example :D Fld1 S 5p 3 inz(12.789)


D Result S 5p 3
/free
Result = %INTH(Fld1);
// Result is now 13.000
/end-free
Syntax :- %LEN(expression)
Description: - This built in function can be used
to get the length of a variable expression.

%LOOKUPxx argument: array{:start index {:number


of elements}}
array index of the matching element

%MINUTES number of minutes number of minutes as a


duration

Example :D Fld1
S 5p 3
D Fld2
S 10A varying inz(ABCD)
D Result S 5p 0
/free
Result = %LEN(Fld1);
// Result is now 5
Result = %LEN(Fld2);
// Result is now 4
/end-free
Syntax :- %LOOKUP(arg :array {:Starting Index
{:number of elements }})
Description: - This Built in functions returns the
array index of the item in array.
Example :D Array1 S 2A dim(5) ascend
D Index
S 2p 0
/free
Array(1) = A;
Array(2) = C;
Array(3) = E;
Array(4) = G;
Array(5) = I;
Index = %LOOKUP(C :Array1);
// Index is now 2
Index = %LOOKUPLT(F :Array1);
//Index is now 3
Index = %LOOKUPGT(H :Array1);
// Index is now 5
/end-free
Syntax :- %MINUTES(number)
Description: - This built in function converts a
number into a duration that can be added to a
time or time stamp value.
Example :D Time1 S

- 188 -

T inz(T11.12.10)

Tips n Facts

%MONTHS number of months number of months as a duration

D Time2 S
T
/free
Time2 = Time1 + %MINUTES(10);
// Time2 is now 11.22.10
/end-free
Syntax :- %MONTHS(Number)
Description: - This built in function converts a
number into a duration that can be added to a
date or time Stamp
Example :D Date1
S
D inz(D2001-11-20)
D Result
S
D
/free
Result = Date1 + %MONTHS(2);
// Result is now 2002-01-20
Result = Date1 - %MONTHS(2);
// Result is now 2001-09-20
/end-free

%MSECONDS number of microseconds number of microseconds


as a duration

Syntax :- %MSECONDS(number)
Description: - This built in function converts a
number into a duration that can be added to a
time or time stamp value.
Example :D Time1 S

Z inz(Z'2001-11-2105.05.00.429010')
T

D Time2 S
/free
Time2 = Time1 + %MSECONDS(10);
// Time2 is now 2001-11-2105.05.00.42902
0

%NULLIND null-capable field name value in indicator format


representing the null indicator
setting for the null-capable field

/end-free
Syntax
%NULLIND(fieldname)
Description
The %NULLID bult-in-function can be used to
query or set the null indicator for null-capable
fields. The built-in function can be used if the
ALWNULL(*USRCTL) keyword is specified on a
control specification.
Example
h ALWNULL(*USRCTL)
FBLTINF IF E
DISK
/free
READ BLTINF;
if %nullind(Namefld);
dsply 'Error';
endif;
*inlr = *on;
/end-free
In the above example the message Error is
displayed whenever the file BLTINF has a record
with field Namefld value as NULL.

- 189 -

Tips n Facts
%OCCUR multiple-occurrence data structure
name
current occurrence of the multiple-occurrence data
structure

Syntax
%OCCUR(datastructurename)
Description
%OCCUR gets or sets the current position of a
multiple-occurrence data structure.
Example
D mds
DS
OCCURS(10)
/free
N = %OCCUR(mds);
// N = 1
%OCCUR(mds) = 7;
N = %OCCUR(mds);
// N = 7
/end-free
In the above example initial the N value is 1. Mds
data structure occurrence is set to 7 using
%OCCUR.
Syntax
%OPEN(file_name)

%OPEN file name 1 if the specified file is open


0 if the specified file is closed

Description
%OPEN returns 1 if the specified file is open. A
file is considered to be open if it has been opened
by the RPG program during initialization or by an
OPEN operation code.
Example
FQSYSPRT O F 132
PRINTER USROPN
/free
IF not %open(QSYSPRT);
OPEN QSYSPRT;
Endif;
/end-free
In the above example-using %OPEN a check is
made to ensure whether the file QSYSPRT is
opened. If file QSYSPRT is not opened the same is
opened using OPEN statement.
%PADDR procedure or prototype name address of procedure or
prototype
%PARMS none number of parameters passed to procedure

Syntax
%PARMS
Description
%PARMS returns the number of parameters that
were to the procedure in which %PARMS is used.
Example
C
*ENTRY PLIST
C
PARMS
COUNT
20
C
C
C

%REALLOC pointer: numeric expression pointer to allocated


storage

- 190 -

IF
%PARMS<1
No Parms DSPLY
ENDIF

In the above example since the received


parameters count is one the message No Prams' is
not displayed.
Syntax
%REALLOC(ptr:num)
Description
%REALLOC changes the heap storage pointed to
by the first parameter to be the length specified in
the second parameter.
Example
/free
// Allocate an area of 200 bytes
pointer = %ALLOC(200);

Tips n Facts

%REM dividend: divisor the remainder from the division of the


two arguments

%REPLACE replacement string: source string


{:start position {:source length to
replace}}
string produced by inserting replacement string into
source string, starting at start position and replacing the
specified number of characters

%SCAN search argument:string to be


searched{:start position}
first position of search argument in string or zero if not
found

%SECONDS number of seconds number of seconds as a


duration

- 191 -

// Change the size of the area to 500 bytes


pointer = %REALLOC(pointer:500)
/end-free
In the above example the area of pointer is
changed from 100 to 200 using %ALLOC built in
function.
Syntax
%REM(n:m)
Description
%REM returns the remainder that results from
dividing operand n by m. The two operands must
be numeric values with zero decimal positions.
Example
DA
S
10I 0 INZ(123)
DB
S
10I 0 INZ(27)
D DIV
S
10I 0 INZ
D REM
S
10I 0 INZ
/free
DIV = %DIV(A:B) // DIV is now 4
REM = %REM(A:B) // REM is now 15
/end-free
In the above example the variable REM has a
value 15 that is arrived using built-in-function
%REM.
Syntax
%REPLACE(replacement string: source string
{:start position {:source length to replace}})
Description
%REPLACE returns the character string produced
by inserting a replace string into the source,
starting at the start position and replacing the
specified number of characters.
Example
D VAR1
S
10I 0 INZ(Windsor)
VARYING
D RESULT
S
10I 0
VARYING
/free
result = var1 + , + ON
// result = Windsor, ON
//%Replace with 2 parameters to replace text at
beginning of string.
Result = %replace(Toronto; result);
//result = Toronto, ON)
/end-free
In the above example the variable RESULT is
replace with Toronto of first string var1.
Syntax
%SCAN(search argument : source string
{:start })
Description
%SCAN returns the first position of the search
argument in the source string or 0 if it is not
found.
Example
D source
S 15A INZ(Dr. Doolittle)
D pos
S
5U 0
/free
pos = %scan( oo : source);
/end-free
In the above example the variable pos has value 6
because oo begins at position 6 in Dr. Doolittle.
Syntax
%SECONDS(number)
Description

Tips n Facts

%SHTDN 1 if the system operator has requested shutdown


0 otherwise

%SIZE variable, array, or literal {:* ALL} size of variable or


literal

%SECONDS converts a number into a duration


that can be added to a time or timestamp value.
%SECONDS can be the right-hand value in an
addition or subtraction operation.
Example
D tmfld
S 8T
/free
tmfld = tmfld + %seconds(20);
/end-free
In the above example the variable tmfld contains
value 00:00:20 as initially tmfld has a value 0.
Syntax
%SHTDN
Description
%SHTDN returns 1 if the system operator has
requested shutdown; otherwise, it returns 0.
Example
/free
// if the operator has requested shutdown, quit
the program.
If %Shtdn;
QuitProgram();
Endif;
/end-free
In the above example if %SHTDN returns value 1
function Quit Program is executed to quit the
program.
Syntax
%SIZE (variable)
%SIZE (literal)
%SIZE (array{:*ALL})
%SIZE (table{:*ALL})
%SIZE
(multiple
occurrence
data
structure{:*ALL})
Description
%SIZE returns the number of bytes occupied by
constant or field. The argument may be a literal, a
named constant, a data structure subfield, a field,
an array or table name.
Example
D tmfld
Dvalue
/free

%SQRT numeric value square root of the numeric value

S 8T
S 5P0

value = %size(tmfld);
/end-free
In the above example the variable value has a
value of 8 that is arrived by the function %SIZE.
Syntax
%SQRT (numeric expression)
Description
%SQRT returns the square root of the specified
numeric expression.
Example
DP
S 5P0
/free
P = %SQRT (81);
/end-free
In the above example the variable P has value of 9
since square root of 81 is 9.

- 192 -

Tips n Facts
%STATUS {file name} 0 if no program or file error occurred
since the most
recent operation code with extender E specified
most recent value set for any program or file status, if
an error occurred
if a file is specified, the value returned is the most
recent status for that file

%STR pointer{:maximum length} characters addressed by


pointer argument up to but not
including the first x00

Syntax
%STATUS (file_name)
Description
%STATUS returns the most recent value set for
the program or file status. %STATUS is set
whenever the program status or any file status
changes, usually when an error occurs.
Example
/free
exfmt(e) Infile;
If %error;
Select
When %status < 01000;
// No error occurred.
When %status = 01211;
//Attempted to read a file that was
not open.
EndSL;
/end-free
In the above example the function %status is used
to identify the type of error that occurred on file
Infile and necessary routines are executed based
on the %status values.
Syntax
%STR (basing pointer {:max-length}) (righthand-side)
%STR (basing pointer {:max-length}) (left-handside)
Description
%STR is used to create or use null-terminated
character strings, which are commonly used in C
and C++ applications.
Example
D String1
D Fld1

S
S

*
10A

/free
Fld1 = < + %str(String1) +>;
// Assuming that String1 points to 123- where -
represents the null character, after the eval. Fld1 =
<123> .

%SUBDT date or time expression: unit an unsigned numeric


value that contains the specified
portion of the date or time value

/end-free
In the above example the function %str
terminates the null character that is present after
123.
Syntax
%SUBDT (value : *MSECONDS |*SECONDS |
*MINUTES |*HOURS|*DAYS|*MONTHS|*YEARS)
Description
%SUBDT extracts a portion of the information in a
date, time or timestamp value. It returns an
unsigned numeric value.
Example
/free
date = d1999-02-17;
time = t01.23.45;
num = %subdt(date:*YEARS);
// num value is 1999

- 193 -

Tips n Facts
num = %subdt(time :*MN);
// num value is 23
/end-free
In the above example the function %SUBDT
extracts the year and minutes from date and time.
Syntax
%SUBST (string :start {:length})

%SUBST string:start{:length} substring

Description
%SUBST returns a portion of argument string. It
may also be used as the result of an assignment
with the EVAL operation code.
Example
/free
string = Hello World;
string1 = %subst(string:7)
// String1 has the value World
/end-free
In the above example the function %SUBST
returns the portion of variable string from position
7.
%THIS the class instance for the native method
%TIME {value {: time format}} the time that corresponds to
the specified value,or the
current system time if none is specified

Syntax
%TIME {(expression {:time-format})}
Description
%TIME converts the value of the expression from
character, numeric, or timestamp data to type
time.
Example
/free
string = 12:34 PM;
time = %time(string:*USA);

%TIMESTAMP {(value {: timestamp format})} the timestamp


that corresponds to the specified value,or
the current system timestamp if none is specified

// time variable has a value t12.34.00


/end-free
In the above example the function %TIME
converts the string which is of character to a time
field.
Syntax
%TIMESTAMP {(expression {:ISO | *ISO0})}
Description
%TIME converts the value of the expression from
character, numeric, or date data to type
timestamp.
Example
/free
string = 1960-09-29-12.34.56.000000;
timest = %timestamp(string);
// timest now contains t1960-09-2912.34.56.000000

- 194 -

Tips n Facts

%TLOOKUPxx argument: search table {: alternate


table}
*ON if there is a match
*OFF otherwise

/end-free
In the above example the function %TIMESTAMP
converts the string which is of character to a
timestamp field.
Syntax
%TLOOKUP (arg : search-table { :alt-table})
Description
%TLOOKUP finds an exact match for specified
argument and search table.
Example
/free
*IN01 = %TLOOKUP (Paris:tab1);
IF %TLOOKUP(Thunder Bay:tab1:tab2);
//code to handle Thunder Bay
Endif
/end-free
In the above example the function %TLOOKUP
searches the string Thunder Bay in tables tab1 &
tab2. If found enters the If loop.

%TRIM string string with left and right blanks trimmed

Syntax
%TRIM (string)
Description
%TRIM returns the given string less any leading
and trailing blanks.
Example
D Location

/free
Location = %trim(

16A
Toronto, Ontario );

// Location will have value


Toronto,Ontario
/end-free
In the above example the function %TRIM trims
the string Toronto, Ontario and stores it in
variable Location.
Syntax
%TRIML(string)

%TRIML string string with left blanks trimmed

Description
%TRIML returns the given string less any leading
blanks.
Example
D Location

/free
Location = %triml(

16A
Toronto, Ontario );

// Location will have value


Toronto,Ontario
/end-free
In the above example the function %TRIML trims
the string Toronto, Ontario
and stores it in
variable Location.
Syntax
%TRIMR(string)

%TRIMR string string with right blanks trimmed

Description
%TRIMR returns the given string less any trailing

- 195 -

Tips n Facts
blanks.
Example
D Location

16A varying

/free
Location = %trimr(

Toronto, Ontario );

// Location will have value

Toronto,Ontario
/end-free
In the above example the function %TRIMR trims
the string

Toronto, Ontario and stores it in variable


Location.
%UCS2 character, graphic, or UCS-2
expression
value in UCS-2 format
%UNS numeric expression value in unsigned format

Syntax
%UNS(numeric expression)
Description
%UNS converts the value of numeric expression to
unsigned format. Any decimal digits are truncated.
Example
D P7
D result
/free

S
S

7P 3 inz(8236.567)
15P5

result = %uns(p7);
// result will have value 8236.000

%UNSH numeric expression half-adjusted value in unsigned


format

/end-free
In the above example the function %UNS
truncates all the decimal digits of field P7 and
stores it in variable result.
Syntax
%UNSH(numeric expression)
Description
%UNSH is like %uns except that if the numeric
expression is a decimal or float value, half adjust
is applied to the value of numeric expression when
converting to unsigned type.
Example
D f8
D result
/free

S
S

8f inz(173.789)
15P5

result = %unsh(f8);
// result will have value 174.00000
/end-free
In the above example the function %UNSH
truncates all the decimal digits of field f8 and
stores it in variable result.
Syntax
%XFOOT(array-expression)

%XFOOT array expression sum of the elements

Description
%XFOOT results in the sum of all elements of the

- 196 -

Tips n Facts
specified numeric array expression.

%XLATE from-characters: to-characters: string


{: start position}
the string with from-characters replaced by to-characters

Example
D result
S
15P5
/free
result = %xfoot(ARR);
// result will have the sum of all elements of array
ARR
/end-free
In the above example the function %XFOOT is
used to sum of all elements of array ARR.
Syntax
%XLATE(from :to :string {:startpos})
Description
%XLATE translates string according to the values
of from, to, and startpos. The first parameter
contains a list of characters that should be
replaced, and the second parameter contains their
replacements.
Example
D up
C ABCDEFGHIJKLMNOPQRSTUVWXYZ
D lo
C abcdefghijklmnopqrstuvwxyz
D String S 10A
/free
string = %XLATE(lo:up: rpg dept)
// result will have the value RPGT DEPT

%YEARS number of years number of years as a duration

/end-free
In the above example the function %XLATE
translates the string from lower to upper case.
Syntax
%YEARS(number)
Description
%YEARS converts a number into a duration that
can be added to a date or time-stamp value.
Example
/free
newdate = date + %YEARS(3)
/end-free
In the above example the function %YEARS will
add 3 years to date variable which is of type date.

Dear Siva,
>
>
Whatever I have the synon material, I am sending now to you on synon
> related data.. find the attachment and the text below copied...
>
>
If you prepare any material, PLEASE make sure to send me a copy ..
>
> Thank you
>
>
>
SYNON
>
> 1.
What is Data modelling?
>
Data modelling is a place where you can define file

- 197 -

Tips n Facts
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

and it's attributes.


2.
Define the File Relations. How many types?
Describe the connection between two files or between
a file and fields.
File relations are Defined as(optional), Includes,
Extended by, Owned by, Refers to.
3.
Define Field relations and explain each?
Field Relations is used to describe the key as well
as non key attributes of a file.
Known by : define a key attribute of
a file.
Has :
define a non key field
for a file
Qualified by : define a key attribute
for a file
4.
What is the difference between Refers to and Owned by relation?
Owned By - Implements the parent child relationship.
The key field of the owning file become a primary key of the owned file.
Refers to - the key field of the referring file
become the non key attribute of the referred file
5.
What is the difference between Known by and qualified by?
Known by
- It requires exact key match.
Qualified by
- doesn't require
exact key match, it will return either a previous or next value.
6.
How many types of files are available in Synon/2e?
There are 3 types of files are available.
a.
REF - Reference file(like a master file)
b.
CPT - Capture file(like a transaction file)
c.
STR - Structure file(it does have any file object, but it looks like
a field reference file)
1.
Which Version currently working with
Version 7
2.
What is the difference between REF and CPT files?
REF file is like a master file. CPT file is like a
transaction file.
8.
What is access path? How many types & explain each.
Access path is path through which you can retrieve
records. There are 6 types of access path is supported by SYNON. By
default Synon creates 3 access path namely Physical, Update and Retrieve
access paths.
User can create other 3 access path namely Re
sequence, Query and Span access path.
9.
What are the access paths will allow to change the key order?
Re sequence and Query access path will allow to
change the key order.
9.
Using which access path you can define a virtual field as a key?
Using QRY access path we can a virtual field as key.
9.
While generating QRY access path how many members(PF, CLP) being
created.
For mapping it creates Physical file, it creating a
QRY in CL program.
9.
Will synon (file)object will allow more than 13,000 records?
10.
Explain Known by, Owned by & Qualified by relations?
Known by - the record value will be identified using
known by relation.
Owned by - it is the first key in the owned file.
Qualified by - it is key field, it try to find out
nearest key value(either previous or next or exact)
9.
How many ways, you can lock a access path?
a.
Temporary lock - when PGMR open the function/access path, that
function will be locked temporally.
b.
Permanent lock - if the Designer has Object Ownership authority, he
can implement permanent lock
9.
How do you handle the access path maintenance in different
situations
a.
*IMMEDEATE

- 198 -

Tips n Facts
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

b.
c.
9.

*REBUILD
*DELAYED
What do you mean by self reference and give example...

9.
How do you delete a access path which is referred by some other
access path?
We can not delete a access path which is referred by
some other function/accesspath. If you want to delete, you have to remove
the (REF) relations then delete.
9.
How many types of functions available in Synon/2e?
a.
Standard function
b.
Built in function
c.
Function fields
d.
Message functions
9.
What is standard function and types?
Standard functions specify the program and
subroutines. User can write his won codes in the User point in the action
diagram.
a.
Database functions
b.
Device functions
c.
User functions
9.
What is Database functions & types?
Database function is a function, using this we can
do all file operations like Create, Delete, Update, Retrieve records. It
has 4 internal objects like,
a.
Create object
b.
Delete object
c.
Update object
d.
Retrieve object
9.
What is Device function & types?
Device function is a function, using this you can
design the Panel (Workstations) and Report design. It has both internal
and external functions.
a.
Print object
b.
Display record
c.
Display record 2 panel
d.
Display record 3 panel
e.
Prompt record
f.
Edit record
g.
Edit record 2 panel
h.
Edit record 3 panel
i.
Display file
j.
Edit file
k.
Select record
l.
Display transaction
m.
Edit transaction
n.
Print file
9.
What is User function & types?
Using this function, you can incorporate User
written programs and subroutines into the Synon/2e generated applications.
You can include these functions inside the action diagram or User written
HLL.
a.
Execute internal Function
b.
Execute User Source
c.
Execute External Function
d.
Execute user program
9.
What is Built in function and give some examples?
Using Built in function, you can do all arithmetic
operations, string manipulations and control operations like Commit and
rollback.
*ADD
*COMMIT
*COMPUTE (Using this we can do all arithmetic
operations like add, sub, mult & div)
CONCAT (It joins 2 string with the conditions (*none
= no blanks, *one = leave one blank, *all = leave all blanks))

- 199 -

Tips n Facts
>
*CVTVAR (It just convert the value of one type to
> another type)
>
*DATE DETAILS (It gives the date details like day of
> week, day of year, *month, leaf year etc)
>
*DATE INCREMENT (Using this we can add quantity of a
> given date and find out new date)
>
*DIV
>
*DIV WITH REMAINDER (Remainder value will move to
> another value)
>
*DURATION (It calculates duration between 2 dates)
>
*ELAPSED TIME (It calculates time (HH, MM, SS, MS)
> between 2 given time)
>
*EXIT PROGRAM (Leave)
>
*MODULO (It gives only remainder value)
>
*MOVE
>
*MOVE ALL (Move value (even constant) to
> variable(s))
>
*MULT
>
*QUIT (It is like a goto statement in RPG, it leaves
> from the entire action diagram)
>
*ROLLBACK (The changes will not be reflected when
> you use *ROLLBACK)
>
*RTVCND (It specifies that the name of a given
> condition is to be retrieved into a function field)
>
*SER CURSOR (It is equal to cursor position keyword
> in SDA)
>
*SUB
>
*SUBSTRING (Using this we can take a part of string
> from the base variable)
>
*TIME DETAILS (It is similar to date details Built
> in function)
>
*TIME INCREMENT (Using this we can add a quantity to
> a given time)
>
> 9.
What is Function field?
>
A function field is a field whose value is not
> physically stored in data base. But is derived from other fields or files.
> Using this we can,
> a.
SUM
> b.
Maximum
> c.
Minimum
> d.
Count
> e.
Derived
> f.
User
> 9.
What is a Message function and it's type?
>
It is a type of function, using this we can send
> messages to Workstation using synon/2e. the message function has
> a.
Send error message(using this we can pass a error message to the
> message queue)
> b.
Send information message(using this we can pass a information
> message to the message queue)
> c.
Send completion message(when a job is completed this message will
> appear)
> d.
Send status message(it gives information about the long running
> program's status to the message queue)
> e.
Retrieve message(it retrieve a message from message file to the
> function, using this you can concate even 2 database fields)
> f.
Execute message(Request message to be executed by the calling
> function)
1. Introduction
2. Process Model(Briefly)
3. Overstaying in the office
4. Approach for Analysis type of Tasks
5.
6.

Multiple Member Database Files


Data Que

- 200 -

Tips n Facts
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.

Data area
Message Q, Job Q, Out Q
Object, Types of Objects Object Attribute
LF and JLF max files that can be joined
DDM files Distributed Data Management file
Job Log, Error Message
CPYF Copy 2 files of different layout?
Journaling in AS/400
FRF and field reference in physical file
Access path
Level Check

18. QCMDEXE
19. Call and TFRCTL
20.
21.
22.
23.
24.
25.
26.
27.

DataQ in RPG (API) and CLP


Files declaration in CLP
SNDRCV in CLP / How to handle a file in CLP.
File OVERRIDE
OPNQRYF MAPFLD, KEYFLD
Can you submit an Interactive Job-(Yes)
Message handling in CLP SNDMSG, SNDPGMMSG...
What are switches (Job)

28. Recursive call of RPG not allowed but in CL.


29. Date conversion
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.

LR and Return
*LIKE DEFN
ILE features.
Primary file in RPG
DataStructures and diff types? Program status DS, File Info DA.
*PSSR subroutine? refer pgmstatus DS
LDA,GDA, User defined DA - IN and OUT command
Substring in CLP and RPG.
Is it possible to compile a RPG without SETON LR
Built in Functions
How many INFDS in an RPG Program 12D + 8Pr + 30Pfs

41. Subfiles Types of SFL


42. SFLNXTCHG
43. Current page in the subfile.
44.
45.
46.
47.
48.
49.
50.

Cursor location in a record format


CF and CA
Invite
Keep Assume
Overlay
RSTDSP
PUTOVR, OVRDTA

51. Message subfile


52. SFLRCDNBR
53. SFLCSRRRN
54.
55.
56.
57.

SQL
Select nth record
Types of Joins
Cursors Types of cursors

- 201 -

Tips n Facts

Changing the AS/400 Sign on Screen


Question:
Has anybody made any changes to the sign-on screen? I have a CL book that gives one example, but
would like some other ideas. Since I am new to DSPF's, could you post the file? I am not able to get mine
to compile and I am only adding two lines... Any help would be appreciated.
Answer:
If you're "new to DSPFs", the sign on screen seems like an unusual place to experiment. But if you're
determined, I'll make one suggestion first. Create a new interactive subsystem and use it to test your
display file rather than any of your normal, production, interactive subsystems. Compile your DSPF to one
of your work libraries and change your test subsystem to pick its sign on screen up from there. I hope this
is how you're already doing it. Anyway, the basics are simple. The easiest way to check to see if your
compiled file meets the requirements is to do a DSPFFD against your new DSPF and compare the field lists
line by line against the IBM-supplied QDSIGNON in QSYS. Basically, you can do anything you want to the
DSPF as long as the two listings match down the list of fields. That mostly means field names, lengths and
data types must match and the positions of the fields in the buffers must match. I assume you began with
the IBM-supplied source in member(QDSIGNON) of file(QGPL/QDDSSRC). That's the only reasonable way
to start.
SUBSYSTEM: KUMAA15
DSPF: LIBKA / ANISH_SO
Prevent Batch Jobs from Entering Interact. Subsystem
Question:
Has anyone got a neat way of preventing users from submitting batch jobs to a jobq associated with an
interactive subsystem? One way would be to add a routing entry to the inter-active subsystem that would
transfer any jobs not meeting the inter-active class type to be transferred to a batch jobq/subsystem.
Answer:
This is the only real way to do it, i.e., via a routing entry program, although resource security and holding
the job queue should also work fairly well. GRTOBJAUT OBJ(QINTER) OBJTYPE(*JOBQ) USER(*PUBLIC)
AUT(*EXCLUDE) or HLDJOBQ QINTER should do it for normal systems. Normal interactive jobs won't be
affected.
DB2/400 Index Limitations
Question:
The max nr of LF's you can generate on a PF ? And while on the subject, what would be the maximum
length of an index field ? Thanks for any responses.
Answer:
Maximum key length is 2000 characters made up of as many as 120 fields (a "first-changed-first-out"
index can have keys up to 1995 characters). Maximum logical files over a single physical file member are
3686.
Differences between RPG400, RPG IV, and ILE RPG
Answer:
In a nutshell, ILE is architecture. RPG400 is the current version of the RPG language and is available on
all AS400's. RPG IV has a lot of changes to the whole structure of the RPG language and is only available
starting with V3R7 (I think!) Both RPG400 and RPG IV can use ILE architecture.
Who's got the files open?
Question:
Our organization has a payroll application that requires the library to be saved before the payroll is run.
They currently have difficulty completing the backup because another user (we usually run about 400
online sessions) has one or more of the files open. They are going through a real time-consuming
procedure to find the culprits (They use WRKACTJOB and go from there). Does anyone know of a routine
or method to determine which users are currently using a file. The optimum solution would be a routine
that would generate a subfile containing the userid, program, and mode (e.g. RPG-INP). Help, we could
sure save a lot of time, and I could be a hero as well.
Answer:
WRKOBJLCK library/filename *FILE might be faster than WRKACTJOB.

- 202 -

Tips n Facts
Answer:
We do similar things... The way we accomplish it is with a simple CL program that does this:
1. See if anyone is currently using the file.
ALCOBJ OBJ((myLib/myFile *FILE *EXCL *FIRST)) WAIT(2)
2. If someone is using the file, display on screen.
MONMSG MSGID(CPFxxxx) EXEC(DO)
WRKOBJLCK OBJ(myLib/myFile) OBJTYPE(*FILE) OUTPUT(*)
GOTO to get back to ALCOBJ above.
ENDDO
Thats an easy way to do it. If you really want to get fancy, you might be able to write an RPG program
and use a subfile, as you suggested... you'd do that using the QWCLOBJL API. With this API you could
list all the objects locks into a user space, and read that space. Hope this helps.
.
Query/400 Question
Question:
hi everybody in query/400 if i have a file with salesman name , sales item and date sold is there a way to
print or put in a file the salesman name, the item sold and ONLY THE MOST CURRENT DATE SOLD ONLY.
any help would be appreciate
Answer:
In Select Report Summary Functions, choose MAX on your date field. Sort by salesman, item number
and date (in that order). Break on salesman, then item number. Run a summary (not a detail) report (in
Select output type and form). This assumes that you have "native" dates, or they are stored in YYMMDD
format in the file.
Changing CHGJOB to lock out psycho users
Question:
I have a user that has just discovered that CHGJOB can be used for more than changing job queues. I
know that most OS400 commands can have a different validation program attached to a command; I need
someone to tell me where I can find some really good instructions on how to modify or write a new
CHGJOB validation program.
Answer:
I would immediately restrict that user (and all non-programmers) from using the CHGJOB command. If
they have *JOBCTL authority, take that away, also. Such users can be dangerous. They think they know
more than they do. Only IS personnel should be allowed to change a job. We are getting set to take that
one step further: no one will be allowed to answer QSYSOPR messages except profiles in the group
QPGMR. We have had cases where someone answered such a message and it compromised data integrity.
It's our shop's policy that any message not relating to file allocation must be handled by a programmer.
Better to do that than to have the payroll or the commissions jobs blow up because someone answered
the message incorrectly.
Answer:
On my other 4 production AS/400s, this is pretty much how we manage those systems. On system #5,
however, this isn't an option for reasons which I won't waste the bandwidth trying to explain (trust me, I
have tried. I still need my job). Suffice it to say I need an alternative, which is to restrict the really bad
parts of CHGJOB from the users, but let them have access to almost as bad parts. Secretly, I am hoping
an IS auditor will come and write a really nasty audit review about this (I will get blamed for it, of course),
but then I will have no choice but to revoke the command.
Answer:
Ray, Okay, I should have guessed office politics was involved. Here's another idea: How about making sure
that in his USRPRF, the priority limit (I think the parameter is called PTYLMT) is set to whatever the jobs
normally get submitted at (say, 5). That way, he can't change the priority to something lower, for his jobs
or anyone else's. Check the JOBDs that the submitted jobs run under, then change your user's priority
limit to that. AFAIK, you can't restrict parts of the CHGJOB command. I suppose you could put in a VCP for
the CHGJOB command, but in this case, my opinion is that it's more trouble than it's worth to do. Besides,
when you upgrade releases, it will overlay your changes.
Answer:
I would revoke his authority to the command and write a new CL command only allowing the parameters
you allow him to change. As long as the program is set to adopt object owner authority, this should be no
problem.
Answer:
Why not just take away *JOBCTL authority from their user profile?
Answer:

- 203 -

Tips n Facts
They don't have *JOBCTL authority. Their special authority is *NONE. Besides, as I stated earlier, I cannot
cripple the command entirely, just restrict the RUNPTY, JOBPTY and TIMESLICE parameters. Why not just
take away *JOBCTL authority from their user profile?
Answer:
Question:
Is it safe to run RGZPFM (re-organize physical file member) against ALL AS/400 system files? I know there
can be a danger in re-organizing files that are accessed by relative record number. IBM documentation
doesn't seem to answer this.
Answer:
Depending on the number and sheer size of your physical files, it may not be safe to run it against all files
at one time. There may not be enough hours in a month to complete a task like that if you have big, big,
PF's. Besides that, don't waste your time on PF's that don't see a large number of deleted records. You
should display your files and take a look at the deleted record counts. We only do large accounting files
and, of course, OfficeVision files. When you find some files that need to RGZ'd, go ahead an experiment
with them to see how long they take to complete.
Answer:
Consider using REUSEDLT(*YES) instead of RGZPFM there are some considerations in the DATABASE
guide, but we've used it for years without problem.
Answer:
Well, time considerations apart, doing RGZPFM against a file that is accessed by relative record number,
and whose rrn's can be kept anywhere in the database isn't dangerous : it's a plain suicide. :-D
Fortunately, this isn't mostly the case, but you may have some (very) old applications that use this
technique. Watch out.
Answer:
If the file is being journaled, then the entire file will probably be written to the journal reciever because
journals work of RRNs.
Answer:
No, this is incorrect... when a journaled physical file member is reorganized, 1 entry is made to the journal
receiver.
Answer:
for QSYS/QADB* files I would use RCLSTG which rebuilds them
Timeslice Issues
Question:
Does anyone out there know how, or if, it is possible to include data areas in a journal. I can find no
reference to this, but guess that most transaction based systems are using data areas to keep the most
recent, or next available, transaction number in. Any help would be appreciated
Answer:
Why do you think so? Dataareas are scratch-paper type objects and can not be journaled.
Answer:
Though there is no direct system support for journaling of data areas, one could use the Commitment
Control APIs (found in the System API Reference) to build your own commit control support for data
areas.
Question:
What command do I issue to determine the OS version on my AS/400?
Answer:
Just issue the DSPSFWRSC (Display Software Resources) and then press F11. Look for the 5763SS1 or
5716SS1 entries. Last column is the software edition and release.
Answer:
Try: ===> DSPDTAARA QSS1MRI
I haven't seen this documented, but it's been on every AS/400 I've ever used. It apparently provides info
for some part of NLS support, hence the "MRI" in its name. Quick and easy.
AS/400 as a PC file server?
Question:
Is there a command, I can use that will to check to see if a library has any locks on it and if it does release
them?
Answer:
Use WRKOBJLCK on the library. To automate the process, you can do this to print, copy to file and process
the results sending a message and/or cancelling each user found. If you have tools installed on your
system (remember those?) the CVTOBJLCK makes this a bit easier. Who knows, there's probably an API
you could use as well.

- 204 -

Tips n Facts
Saving Spool Files / Copying to database
Question:
I have some print I would like to save, and I was wondering if it is it possible to move the spool files (print
files) to a tape/floppy disk ?. If so, how is this done, and how do I get them back on the system if I should
need to print them once more?
Answer:
You can copy the spool file to a physical file and then save it to tape or disk. However, getting it back
would be difficult at best. The best recommendation is to get the Save Output Queue (SOQ) product from
Generic Software. This is the best little, very inexpensive utility I've ever seen. Very helpful in archiving
spool files each month, cataloging them, and then retrieving them when needed.
Answer:
This will copy spool1 to Qtemp/Temp
CPYSPLF FILE(&SPLFNAME) TOFILE(QTEMP/Temp) + JOB(&SPLFJNBR1/&SPLFUSER/&SPLFJOB) +
SPLNBR(&SPLFNBR) CTLCHAR(*FCFC) mbropt(*replace)
You will be able to save the file This will create a spool file QSYSPRT from saved data
OVRPRTF FILE(QSYSPRT) CTLCHAR(*FCFC) OUTQ(&OUTQ) +
FORMTYPE(COPYPACK) HOLD(*NO) SAVE(*NO) +
USRDTA(DUPLICATE) SPLFNAME(&SPLFNAME)
CPYF FROMFILE(QTEMP/Temp) TOFILE(QSYSPRT)
Then you can pump QSYSPRT to your Fax ! Hope this will help
Question:
Anyone know of an easy way to have the cursor move top to bottom through input capable fields instead
of left to right within a display file, NOT a subfile.
Answer:
You can use the field level keyword FLDCSRPRG to specify the next field to go to when exiting that field.
You can go to any other field on the screen which makes for some real interesting possibilities.
Answer:
Use CSRLOC. This allows you to set the value of the row and column of the cursor before each write to the
screen. You could set up a loop to increment the value of the row before each WRITE or EXFMT. The
column value would remain constant. The CSRLOC does NOT work with subfiles. Your DDS manual should
have the syntax and format of the keyword.
MSGLINE in windows
Color coding records in a subfile
Question:
Can anyone instruct me on how to color condition fields in a subfile. For example, I would like to conition a
balance field to be displayed in red if it is debit figure. Only the subfile record with debit balances should
be red all other records on the subfile display should not be red.
Answer:
Greetings A neat way to do this is to make the SFL field one character longer than normal and move a hex
attribute for the required color into the furst position of the field Now this is obviously not feasible with
numeric fields but works very well for character fields and removes the need to track the color on the field
(indicators are always reset when reading 'C' to a subfile) If you really need to use this technique with a
numeric field, make the SFL field character and then use the API to edit the field into a 'numeric' format
Let me know if you want to receive a table of hex attributes and the color/attribute that they represent
Question:
Does anyone know if it is possible to retrieve the subfile size or subfile page size in an RPG program
without filling the subfile with blank records and using a counter?
Answer:
I believe that the INFDS data structure holds that sort of information. You will need to look at the IBM
infoseeker for the breakdown on the data structure.
SFLMODE keyword in an ILE program
Question:
I am trying to use the SFLMODE keyword in an ILE program to keep my subfile in Fold/Truncate mode
while I page down through my subfile. Does anyone have any examples of how to use this in RPG ?
Answer:
Here is a short example:
DSPF:
SFLMODE(&FIELD1)
N59 SFLDROP(CF14)
59 SFLFOLD(CF14)
RPG:

- 205 -

Tips n Facts
In your *INZSR (or where else you want) set the FIELD1 to *ON.
In your dspf-routine:
EVAL *IN59 = (FIELD1=*OFF)
EXFMT xxx
...
...
...
Note: CF14 is the key for fold/trunc. The field FIELD1 (or any other name) must be 1 alpha. You can
replace the indicator 59 with any other ind.
Field masking for passwords
Multiple subfiles
Question:
Hi, I need to write an RPG program that will display and allow input for more than one subfile at the same
time. Has anyone done this? If so would you please enlighten me on the technique?
Answer:
Hi, you can display more than one subfiles in two ways: Either ------------------------------------- + + +
subfile1 + + + ------------------------------------- + + + subfile2 + + + ------------------------------------ or
side by side (or anything else) with subfile-windows. Note: When you read a record from one subfile (f.e.
READC) and then you read a record from the next subfile, the system "forgets" the rcdnbr of the first
read. If you need it for an update of the subfilke you must save the rcdnbr and then read the record (with
CHAIN) for the update again.
Question:
We are primarily RPG 400 site. We are contemplating on moving to RPG IV (ILE RPG) Advice from those
who have done this will be appreciated Thanks
Answer:
Just take a look at all the limitations that have disappeared, think about the easier coding for string and
arithmetic expressions and the choice should be clear. Wether or not you'll be using the ILE capabilities
(service programs, modules, ...) is another question, but I would at least start with RPG IV (or whatever it
might be called) and use the CRTBNDRPG option. So far I haven't encountered any disadvantage except
that compilation times (including the CRTPGM) are a bit longer compared to before.
Answer:
There is another "problem", the compiled objects are about double size than RPG400 programs.
Answer:
Take your migration in two steps. 1) Focus on the Language (i.e. RPG-IV). The features such as date/time
arithmetic and many more are more than worth the effort which is relatively minor. As Paul indicated, the
freedom from limits is worth the move all by itself. 2) Learn the ILE piece (they are separate - one does
not require the other) separately. ILE tends to be difficult for many AS/400 people. If you have any old
mainframe folks in your shop, they'll tell you that IBM finally brought the linkage editor to the 400.
Approcah ILE with caution using modular programming only where necessary and major benefit can be
gained. In most cases we've found that the complexity of modular programming isn't worth the gain, but
RPG-IV is. We converted all of our old RPG/400 (actually RPG-III and some RPG-II code) to RPG-IV via the
converter that IBM provided without incident one weekend. All of our 5,000 plus programs compiled and
ran without incident. They did a real good job on the converter, just create new source files with the
proper record lenght, set up a CL and let her rip. You may want to check Midrange Computing's list of
books and buy some of Bob Cozzi's books on RPG-IV I can't remember the title, but there is on book
(small green book) that explains the differences and introduces the new op codes to an experienced RPGIII programmer. That was all we needed to get the migration done. We did conduct a seminar where we
used overhead foils to present the new features to the programmers and spend 1/2 day talking about
them (including ILE). We did no other training.
Question:
I'm not sure if this is possible with Logical files? I've never seen logicals used for this, and can't find any
reference to doing this. Say I have two physical files(sales history and ancient sales history). Both physical
files have the same record layout (say Cust#[5A],Date, Sales[3N2]). I'd like to normally access just the
"sales history" and not "ancient sales history". On occasion though, I'd like to join the two files. Sure, I
could just copy one, and append the other to it. But, that would eat up some space. Example... Sales
History File; Cust# Date Sales Bubba's 1998/01/05 632.23 Fido's 1998/01/01 32.44 Ancient Sales History
File; Cust# Date Sales Waldo 1996/12/30 335.23 Bubba's 1993/12/15 201.15 Joined Files View???;;
Cust# Date Sales Bubba's 1998/01/05 632.23 Fido's 1998/01/01 32.44 Waldo 1996/12/30 335.23
Bubba's 1993/12/15 201.15 Can DB2/400 do This??
Answer:
Not only can DB2/400 do this, it has been doing this since long before it was called DB2/400. What you
are describing can be accomplished with a multi-format logical file.It is not even, striclty speaking, a join

- 206 -

Tips n Facts
file. It is more similar in concept to the UNION ALL sql operation. In your DDS for the logical file specify
the following
A R CURREC PFILE(CURFILE)
A CUSTNUM
A CUSTDATE
A CUSTSALES
A K CUSTNUM
A K CUSTDATE DESCEND
A*
A R OLDREC PFILE(OLDFILE)
A CUSTNUM
A CUSTDATE
A CUSTSALES
A K CUSTNUM
A K CUSTDATE DESCEND
In your HLL when you want to reference current sales history you read/chain/setll using the record format
name (CURREC). When you want to reference ancient sales history you read/chain/setll using the record
format name (OLDREC). When you want to reference all the sales history you read/chain/setll using the
File Name. You can also perform updates, deletes, and writes to this file. (not possible with a join lf)
OS/400 provides another feature called a format selector program where you specify an exit program to
call if someone writes to the multi-format logical but doesn't specify which record format to write to.
Remember, SQL hates multi-format logicals so you may have trouble using it with ODBC and certain
queries.
Answer:
You definitely can't use multiple format logicals with SQL or Query, so ODBC seems out of the question
too. The format selector is especially useful when using program described files in RPG.
Answer:
yes you can, but it is not a join file, just a logical file. if pysical files P1 and P2 have the same format name
you can do : R format PFILE( P1 P2) K key1 You can make a 2 format logical file. R format1 PFILE(P1) K
key1 R format2 PFILE(P2) K key1 In your program use this second file by file name, not format name.
Regards
Message subfile problem
Question:
a message subfile(first time I tried this) using API's to write and clear the message subfile. The messages
are being properly retrieved - they are written to the joblog - but they dont display when the screen with
the input capable subfile reappears for correction. I was pondering this over the weekend and one
possibility is that I could try the OVERLAY keyword on the control record of the message subfile. Any
suggestions appreciated.
Answer:
Check OVERLAY first. If this brings you no success: maybe your message subfile is empty because you
sent the messages to another program message queue. Check the joblog, press F9 for message details,
you'll see which program sends the message and in which program's message queue it was placed. If this
is correct then check if you fill the name of the message queue correct. I prefer the following:
A R SMSFL SFL
A SFLMSGRCD(24)
A SMMSGK SFLMSGKEY
A SMPGMQ SFLPGMQ
A R SMSFLC SFLCTL(SMSFL)
A SFLSIZ(2) SFLPAG(1)
A OVERLAY
A SFLDSP
A SFLDSPCTL
A SFLINZ
A N01 SFLEND
A SMPGMQ SFLPGMQ
In my RPG-programs, i use the follwing line to set the program name:
C MOVEL '*' SMPGMQ
Hope this information is the one you needed.
Answer:
Thanks for the response. The OVERLAY on the message subfile didn't work(I already had one on the main
subfile). Your message subfile control record looks the same except that I did not use the last 3 keywords.
The set of '*' for initializing the program message Q also looks the same. I will check on the joblog F9 tip
tomorrow. This is for a file maintenance program that the IS dept will be using so the message subfile is
not critical but It will really bug me until I get it to work.
Answer:

- 207 -

Tips n Facts
The OVERLAY on the message subfile is not requried but the OVERLAY on your main display IS required so
that it does not erase your messages.
Answer:
If you have OVERLAY on the main screen already, how are you displaying the message subfile? Are you
writing it before the exfmt? for example
C WRITEMSGCTL
C EXFMTSCREEN
Record lock wait time
Question:
Does anyone know how to change the default time that an RPG update program will wait on a record lock?
Answer:
CHGPF or CHGLF?
Answer:
I'm not at a AS/400 now, so I can't provide exact details. The process default wait time is used, and I
believe that is a job attribute. Check out the CHGJOB command, or the JOB command for a batch job. It
might even be a job CLASS attribute.
Answer:
From OS/400 CL Reference, V3R2, with respect to CHGJOB DFTWAIT(): "The wait time specified for this
parameter is ignored for read operations to database files; to specify that attribute, use the WAITRCD
parameter of the appropriate database command (create, change, or override) for a physical, logical, or
database file command."
Answer:
Do an OVRDBF cmd in a CL pgm before calling the RPG or do the OVRDBF cmd in the PRG using
QCMDEXC. The parameter is I believe is WAITRCD.
Answer:
use the setting on the CRTPF, or override on the OVRDBF
Answer:
Set the WAITRCD parameter on the file whith CRTPF or CHGPF commands. This is an atribute of the file
object, rather than the programmer's choice.
Updating in CL
Question:
Is there ANY way to update a file in CL? Looked for an API and didn't find one. Any Help would be greatly
apreciated.
Answer:
If you have TAATOOLS, there is a cmd called something like UPDFLD that allows this.
How to use ERRSFL
Question:
Help, I am writing messages to a display file by using the API QMHSNDPM. The messages appear in the
message subfile on the display file if the message subfile is defined. I am trying to avoid using the
message subfile and use the standard error message subfile created by the file level ERRSFL keyword. Has
anybody managed to load this error message subfile via the QMHSNDPM API?
Answer:
The ERRSFL can only be used ERRMSG, ERRMSGID, SFLMSG, SFLMSGID, and the display file validity
checking keywords. If I were you, I would continue to use the Message subfile and QMHSNDPM. It gives
your program far better control over error handling. It is a very telling example that message subfiles are
what IBM uses for all its displays.
Answer:
We switched to using this API to send error messages successfully. We decided not to try and fill the
subfile, because most users only look at the one being displayed. So, whenever we encounter an error, we
loop back to display the screen (and any errors). One thing we had to do was use the overlay keyword on
the control record (for a subfile) and the screen format (for just a plain screen) otherwise the error would
flash and then dissappear. A simple example of how we use it is this...
C dow (W$KEY <> f3)
C CALL 'SNDPM' WPMSG
C EXFMT SCR01
C eval WPMSID = 'INV0001'
* other code
C enddo
the program call to SNDPM displays any error message shown. The WPMSG parameter list includes
message id, message data, message file name, and message file library. We created message ID INV0001
as a blank record to clear any messages after they are displayed. Hope this helps.
Library lists and performance
Question:
Is there any performance difference in the following scenario? 1. One library with 1000 objects. 2. 10
libraries with 100 objects. I understand that in (2) if the object were found in a library near the top of the
library list the access would be very quick. My question is this, with one big library is there a pointer to the

- 208 -

Tips n Facts
object required or does the OS have to scan all the objects in the library until it finds the one required. If
there is a pointer then would it not be faster to access any object in one huge library than to access an
object in the second library. The OS would be checking the existence of the object in the first library then
the second...until the library list has been scanned. I hope some of you system gurus can help as I am
just a lowly application guy
Answer:
This is an interesting question, and I'd love to hear what people say. But, I really don't think it's a big
performance worry. My guess is this. It searches each library for the object, but uses a good search
technique. Kind of like the way we would search through a dictionary for a word. We wouldn't start with
the A's and scan until we reach our desired word (in this case let's say "STEAK"). We would go to the Ss
and then the STs and so forth. I can't for the life rember the name of the search method. But it's the one
where you go to the middle of the list. If the value is equal, your done. If it is greater than the desired
value, you go to middle of the top half, and do the same until a value is or is not found. If the value is less
than the desired value, you use the bottom half of the list and do the same until a match is or isn't
found... Darn mental blocks! Binary search? Someone help me out
Answer:
The is absolutley no difference between the two. I runs on a pointer system and does not need to search
libraries. Once the program is compiled , os400 knows exactly where it is.
Answer:
I'm afraid that your statement is true if you have qualified the objects ( I mean if you have stated the
library/object of the call/open ) if not there is a search. As was stated in a later message that penalty is
nowadays not that significant ( I recall having read somewhere in the old S/38 to put the data libraries
before the pgms libraries to diminish the search )
Answer:
In each library there is an independent index (similar to the index of a logical file) which the system can
use to find 'normal' objects. That means it will take approximately 5 times as long (averagely) to find one
object with 10 libraries than with one library, given that they are evenly distributed in the 10 libraries. But
a lookup in an index is fast, so you really don't need to bother.
Answer:
Also, in a related performance impact: If you seperate the objects into 10 libraries, the as/400 can place
them on seperate disk packs, reducing the risk of (entire) loss, and spreading the disk head activity
among several physical devices. (right?) :)
Answer:
Wrong. All data is spread over all disks evenly, to make optimal use of all disk-arms.
Answer:
Not (right). If not told otherwise (specifying an explicit storage pool for every object), OS/400 itself
chooses physicall space for any objetct, usually trying to keep sotrage usage at a level for all disks.
AS/400 'machine language' - MI Programming
Question:
Hi as i am often at AS/400 shops that only have an RPG compiler, i'd like to start learning MI to be able to
do things i'd otherwise only could do in C/C++. Now i am not afraid of MI, but i need some information to
get started. I (nor any of the shops i've ssen so far) dont have the "Machine Interface Functional
Reference" which is referred to extensively in the API books. This book is NOT on the Online Reference
Library CD's , nor is it on the IBM rochester FTP site (as far as i know). Can anyone tell me where i can
obtain the book (in electronic or paper form, any version) or advice other reading? Or does anyone
perhaps have a list of operation codes that can help me get started?? tnx very much in advance
Answer:
contact IBM, I think you can order this book. and as far as I know MI is release-dependent, opcodes may
change without notice.!
Answer:
There are other problems too, for instance objects previously available via MI, can no longer be accessed
as they're now in the 'System Domain' (I think it's called) and you get object violations if you go near
them.
Answer:
For kicks-n-giggles, I wrote an RPG that used most (all the standard) of the OPCODEs to get work done in
RPG, then compiled the program with MI output it's on of the options on the compile. I then took a look at
the code. And decided to skip it... Too much like JCL for me... 8-)
Answer:
If you can do it in C then do it in C. You can order the Machine Interface Functional Reference book from
your local IBM literature service. I had this book at my previous work place and found it more than
lacking. It only describes a few select system mmemonics such as MATMATR (materialize machine
attributes) but certainly doesn't give you any information on how to change any settings on your /400 or
even something "simple" as to create an object. (Even though they use the CRTS (create space) OP in
their sample programs!) There is as certain *DTAARA in the QSYS library which contains the names of all
MI mmemonics known to the system MI compiler (It starts with Q ;-) I don't remember the rest though).
Just a fraction of these are documented in above mentioned publication. BTW I heard of a 3rd party MI

- 209 -

Tips n Facts
compiler that has aside from the OPS I just mentioned lots of IBM undocumented MI OPS in it. You might
want to check for that.
Answer:
He *doesn't* have a C compiler at his shops. ;D. That was his question. Anyway, I don't understand why
someone wants to write legacy soft *on the AS* in C. Particulary on the AS, whose C compiler is really
indecent and whose C++ environment requires aprox 50x (sum soft, CPU & workstations needed)
investment as on any other machine. And if it isnt legacy soft, well, why have you to recompile it for
every customer? I don't know what you're doing, JimBob19, but I'm sure you have a better solution
behind you as rewriting in MI code, which is machine & release dependent. Tell us some more.
Answer:
Right, but still, there are things you can do with MI at such a speed you can't do with anything else. We
have been doing heavy MI development for years, and the difference is huge. However, we do system
tools here, so the investment in manuals, training, and testing pays for itself. Outside the tool
development, MI can help you to speed up certain critical functions of your applications... but try other
languages first. There is more myth on the "release dependant" issue of MI than reality. Our software run
untouched from V1R2 (yeah, I mean Version One Release Two) with the sole exception of two instructions
(out of hundreds of thousands lines) that we use for speeding up system internal things, that you are not
(definitely) going to use in a business application program (hey, not a surprise here: all the compilers
generate MI code - if they changed MI a lot, they would need to change all the compilers - and the beauty
of the AS/400 is MI - its machine independant interface). And we achieved subsecond response times in
complex Client/Server transactions, for instance, thanks to the MI compiler. But MI *is* complex. You can
buy the book (MI Functional Reference) from IBM, but it is not a tutorial. IBM will not help you either.
There was a company (Monahon I think) that sold a MI compiler with a handbook, but I don't know if they
still are on business (look for them on the NEWS/400 Sourcebook). Good MI examples appeared from time
to time on AS/400 magazines as NEWS/400 and MC. You can learn a lot from inspecting the the RPG
compiler output in MI. You are going to need a good interactive source debugger as well (the IBM provided
debugger will not work). If you need a good one, send me a message, I know a great one. If you, in the
end, start a MI programming career, welcome to the club!
Answer:
Well, that struck me. :-) Not that I'm going to dive into MI after that, but it was a nice reading. As some
say here : oooole tus huevos!
Answer:
Do you know of any 3rd Party publications that might be useful aside from the IBM book I know of and
looking at NEWS/400 articles? Like I said in my previous post, the IBM book (Machine Interface Functional
Reference) really gets you nowhere.
Answer:
> ...... all the compilers generate MI code if they changed MI > a lot, they would need to change all the
compilers Just a couple of points. First only the _old_ compilers generate MI. All of current compilers (C,
C++, CL, COBOL/400, RPG IV) generate W-code, not MI. Second, the compiler writers are protected from
potential changes to MI (or more often to the control blocks etc.) by macros. Even when changes occur, by
changing the macro we avoid changes in code. I agree though that MI is not likely to go away any time
soon. Jon Paris - Toronto Lab
Answer:
QPROCT ("Program Operation Code Table" ??) in QSYS (type x'19DA') contains all valid MI op-codes.
There's a lot of the op-codes from the S/38 days that can only be used by system domain programs, and
the Create Program API won't recognize them. Database access, create program, etc. is probably
considered too "dangerous" (or simply makes it too easy to violate system security or database integrity).
Even IBM's compilers doesn't access the DB opcodes directly, but rather through programs QDB*. It's
safer to use a HLL like RPG to access files, and use MI for the utlity/system related stuff.
Answer:
In the System API Programming guide chapter 5 contains a very brief introduction to MI programming.
Here you also have all the information for a 'do it yourself' MI compiler. However for real programming you
need the Functional Reference. The Functional Reference is NOT complete, in the sense that OPCODES
reserved for use by IBM (system state programs) are not listed. However the opcodes that are listed are
not likely to be changed in the curent millenium. I found that I can sometimes achieve an incredable
performance gain by putting SELECTED parts of an application in MI. Especially manipulating Independent
Indexes is much faster than using workfiles, of using Indexes with help of the appropriate API, which is
incredibly slow. Also MI can be used to retrieve lots of information from a job, or from the system. For
instance it can easily be seen how many pagefaults your jobs caused, or how many CPU milliseconds it
used. I have used this for performance testing applications that themselves were written in RPG. A very
simple MI program can even retrieve information from the system operator panel, like how your key is
turned in your machine (if you still have one of those models).
Answer:
Can you tell us more about W-code? W-code is a platform independent intermediate language that is
output by most of IBM's more recent compilers on multiple platforms. It is then processed by a platform
specific back-end (the bit we refer to as the translator on the AS/400). There are back-ends for Win 95,

- 210 -

Tips n Facts
OS/2, Win 3.1, etc. etc. It is much more of a 'nuts and bolts' assembler type language than the old MI. MI
instructions are of the "Move Universe from A to B" type. W-code instructions are more itsy-bitsy. W-code
is not a published interface, but it can be obtained by folks who want to write compilers etc. for the
platform.
Logical Files and DDS
Question:
Hi ! I have some trouble creating logical files on my system, hope you can point me in the right direction.
I have a database table TEST_TABLE for which I need to create a logical file. When I enter the command
CRTLF it prompts for a DDS ( Data Description Specification ). I have seen a few examples of the DDS files
for various C programs in the ILE C/400 Programmers Manual. But I dont know How to create one or what
format it should be for my file. Suppose the table format is as follows : TEST_TABLE
----------------------------- Field_1 Integer Field_2 Character (10) Field_3 Integer What will be the format
or the simplest DDS file ? How do i create the DDS file ? Do I just edit the file in my Editor or is there a
special command CRT* somthing ? Thanks
Answer:
the most common way to create a logical is to create the DDS source, which pseudocodes something like
pfile() a keyfield1 a keyfield2 a otherfield k keyfield1 k keyfield2 this describes a logical file over file
myPhysicalFile, selecting fieds keyfield1, keyfield2, and otherfield, and ordering by keyfield1 and keyfield2.
you can also do select and omit logic. you would create this using SEU (STRSEU) or within PDM
(WRKMBRPDM). traditionally it will reside in a file QDDSSRC in your library. if you are creating it in PDM,
give it file type LF. you can then either use option 14 in PDM to compile, or CRTLF specifying this text as
your DDS source. for more specifics, look it up: http://as400bks.rochester.ibm.com/bookmgr/home.htm
Passing parms to Query
Question:
Does anybody know how I can pass a parameter to a query?
Answer:
You can't pass parameters to Query directly, unless you use the Query Manager, I believe. I don't use the
Query Manager, so I'm not that sure about this, but I have seen it discussed. Other ways to get
parameters to Query are with another file. Create a file that contains that data parameters you want and
use this as the primary file on a join.
Answer:
Not direct to query, but you could use Query-Manager instead. Put your query in a source-member
(record-length 91 (79+6+6)) e.g. QQMQRYSRC : Select * from &n Then create an executable object form
the source : CRTQMQRY (F4) Then "execute" the Query-object : STRQMQRY ... (F4 + F10 shows the
screen, where you can fill the first parameter with the File-Name) Now you have a Query which gets all
fields and all records from the specified file (with an parameter). Hope it helps,
Answer:
As far as I know, you can't. The only way to do it is to keep your parameters in a file and have the query
join to this file, selecting based on the field values....I would suggest using Query manger..you can pass
parameters for record selection..
Answer:
Rather than getting fancy, I just would write a prompt program in RPG that passes your parameters to a
single record file. Simply add that file to the query definition. Your fronted CL calls the prompt program,
then does a SBMJOB to do the RUNQRY command. No parameters needed. Not fancy, but it works. I have
always felt that passing parameters to Query the way you're supposed to do it is a waste of time.
Answer:
RUNQRY may not be the command you are thinking of. It does not appear that it works as described
above. But... whatever the proper command is, (SQL or QryMgr or whatever) note the result when the
procedure is run over and over again without waiting for completion of a given invocation.
Answer:
RUNQRY certainly is the command I'm thinking of. I've used it many times in this manner. The
"parameters" are passed to a regular query by the use of an additional file defined in the query, which is a
single record file. This allows a user to run a query without having to change the query definition.
Answer:
I have some sample source for passing dates to query. Check out the following: www.as400.com/programm.htm
Answer:
I think I stand corrected. Haven't had a chance to try this out yet, but it goes to show there's always a
way to do something. BTW, Multiple invocations would still be a problem.
Help - Windowed Subfiles
Question:
I am attempting to create a display that when opened is a subfile in a window. That much in itself is
working fine. My problem is that when this program is called (currently from a command line, but
eventually will be assigned to the Attention key.) The entire contents of the screen is erased before the
initial window is displayed. I want the popup window to overlay anything already on the screen. In the
DDS, I'm using the WINDOW, OVERLAY, and PROTECT keywords. I wish I had the DDS in front of me to

- 211 -

Tips n Facts
explain what I already have in place better... Can anyone assist me that has done this type of thing
before?
Answer:
If memory serves me correctly, you need to specify OVRDTA or OVRATR on all fields.
Answer:
Sorry, but memory can play tricks on you. A "dummy" format is defined in the display file with the
ASSUME keyword. One field is defined in this format with the PUTOVR attribute. This works!
Answer:
I have an example, below, I can share that is using a windowed- subfile. Strip-out the DDS, and create a
*DSPF, and strip-out the RPGIV code, and create a *RPGLE. Remember to compile the *DSPF with
RSTDSP(*YES). Let me know what you think?
The DDS Code...
A DSPSIZ(24 80 *DS3 A 27 132 *DS4)
A PRINT
A R SUBF01 SFL
A #FLDNAM 10A O 3 1
A #FLDTYP 1A O 3 14
A #DIGITS 4Y 0O 3 37EDTCDE(Z)
A #DECIMALS 2S 0O 3 45
A #STRPOS 5Y 0O 3 25EDTCDE(Z)
A R CNTR01 SFLCTL(SUBF01)
A *DS3 SFLSIZ(0016)
A *DS4 SFLSIZ(0016)
A *DS3 SFLPAG(0015)
A *DS4 SFLPAG(0015)
A *DS3 WINDOW(SCRN01)
A *DS4 WINDOW(SCRN01)
A N75 ROLLUP(25)
A CA03(03 'exit')
A KEEP
A BLINK
A CSRLOC(SETROW SETCOL)
A OVERLAY
A SFLCSRRRN(&GETRRN)
A 50 51 SFLDSP
A 50 SFLDSPCTL
A 52 SFLCLR
A 75 SFLEND
A @PAGE 4S 0H SFLRCDNBR
A SETROW 3S 0H
A SETCOL 3S 0H
A GETRRN 5S 0H
A 1 1'Record Format Layout...'
A DSPATR(HI)
A SCRFLDDBFL 10A O 1 38DSPATR(HI)
A DSPATR(UL)
A SCRFLDDBLB 10A O 1 25DSPATR(HI)
A DSPATR(UL)
A 1 36'/'
A DSPATR(HI)
A 1 49'('
A DSPATR(HI)
A SCRFLDDBRF 10A O 1 51DSPATR(HI)
A DSPATR(UL)
A 1 62')'
A DSPATR(HI)
A 2 1' Field '
A DSPATR(UL)
A COLOR(PNK)
A 2 12'Type'
A DSPATR(UL)
A COLOR(PNK)
A 2 17'Starting Position'
A DSPATR(UL)
A COLOR(PNK)

- 212 -

Tips n Facts
A 2 35'Length'
A DSPATR(UL)
A COLOR(PNK)
A 2 42'Decimals'
A DSPATR(UL)
A COLOR(PNK)
A R SCRN01
A *DS3 WINDOW(2 2 21 72)
A *DS4 WINDOW(2 2 21 72)
A OVERLAY
A WDWBORDER((*COLOR BLU) (*DSPATR RI)A (*CHAR ' '))
A USRRSTDSP
A 18 1' AA'
A DSPATR(UL)
A DSPATR(HI)
A 19 1'To select a field, position yourcA ursor and press ENTER... A'
A COLOR(PNK)
A 20 1'F3-Exit AA'
A DSPATR(HI)
A R ASSUME ASSUME
A 24 79' '
-----------------------------------------------------------------------The RPGIV Code...
*
**********************************************
* This application allows the user to display the
* Record Format Layout of a File(Passed Parm),
* and Returns the FIELD-NAME, and LENGTH...
*
* ...sgroi
**********************************************
*
/EJECT
*
FRCDL600D CF E WORKSTN
F SFILE(SUBF01:@RRN)
F INFDS(@LOCATE)
*
D@LOCATE DS
D@CURSOR 388 389B 0
D@FIRST 378 379B 0
*
D RETURNNAME S 10A
D RETURNLEN S 2A
D @RRN S 4S 0 INZ(*ZEROS)
D @REBLD S 1A INZ(*OFF)
D @BAD S 1A INZ(*OFF)
D @DONE S 1A INZ(*OFF)
D @ERR S 1A INZ(*OFF)
D @SKIP S 1A INZ(*OFF)
D @MODE S 1A INZ(*BLANKS)
D MESSAGEQUE S 10A INZ('*')
D MSGDTALEN S 8B 0 INZ(60)
D MSGQUENBR S 8B 0 INZ(0)
D MESSAGEKEY S 4A
D MESSAGEFIL S 20A
D MESSAGETYP S 10A INZ('*DIAG')
D @RRN# S LIKE(@RRN) INZ(*ZEROS)
D @PASS S LIKE(@RRN) INZ(*ZEROS)

- 213 -

Tips n Facts
*
D X S 4S 0 INZ(*ZEROS)
D @FIELDS S 4S 0 INZ(*ZEROS)
D F S 4S 0 INZ(*ZEROS)
*
D @FLDNAM S 10A DIM(150) INZ(*BLANKS)
D @FLDTYP S 1A DIM(150) INZ(*BLANKS)
D @FLDLST S 14S 0 DIM(150) INZ(*ZEROS)
*
D ErrorDs DS INZ
D BytesProvd 1 4B 0
D BytesAvail 5 8B 0
D MessageId 9 15
D Reserved 16 16
D MessageDta 17 116 INZ(*BLANKS)
*
D GENDS DS
D OffsetHdr 117 120B 0
D SizeHdr 121 124B 0
D OffsetLst 125 128B 0
D NbrInLst 133 136B 0
D SizeEntry 137 140B 0
*
D Input DS
D UserSpace 1 20
D SpaceName 1 10
D SpaceLib 11 20
D InpFFilLib 29 48
D InpFilNme 29 38
D InpFilLib 39 48
D InpRcdFmt 49 58
*
D HeaderDS DS
D OutFilNme 1 10
D OutLibNme 11 20
D OutType 21 25
D OutFormat 31 40
D RecordLen 41 44B 0
*
D LISTDS DS
D SfFld 1 10
D SfType 11 11
D BufferOut 13 16B 0
D FieldLen 21 24B 0
D Digits 25 28B 0
D Decimals 29 32B 0
D FieldDesc 33 82
*
D DS
D StartPos 1 4B 0
D StartLen 5 8B 0
D SpaceLen 9 12B 0
*
D DS
D @FLDLST1 1 14S 0
D @STRPOS 1 4S 0
D @FLDLEN 5 8S 0
D @DIGITS 9 12S 0
D @DECIMALS 13 14S 0
*
/EJECT
*
***********************************************
*MAINLINE...
***********************************************
*

- 214 -

Tips n Facts
C EVAL *INLR = *ON
*
C EXSR $GETDBFLDS
*
C EXSR $POSITION
C EXSR $PROCESS
*
C EXSR $SHUT_DOWN
*
/EJECT
*
************************************************
C $POSITION BEGSR
* POSITION SUBFILE RECORDS...
************************************************
*
C Z-ADD 1 @PAGE
*
C CLEAR @RRN
*
C Z-ADD X @FIELDS
*
C EVAL *IN50 = *OFF
C EVAL *IN51 = *OFF
C EVAL *IN52 = *ON
*
* CLEAR SUBFILE...
*
C WRITE CNTR01
*
C ENDSR
*
/EJECT
*
*********************************************
C $PROCESS BEGSR
* PROCESS SUBFILE, AND USER FUNCTIONS...
*********************************************
*
* F3-EXIT...
*
C DOU *IN03=*ON
*
C EXSR $FILLSFL
*
C IF @RRN > *ZEROS
C EVAL *IN50 = *ON
C EVAL *IN51 = *ON
C EVAL *IN52 = *OFF
C ELSE
C EVAL *IN50 = *ON
C EVAL *IN51 = *OFF
C EVAL *IN52 = *OFF
C ENDIF
*
C EVAL @RRN# = @RRN
*
C DOU *IN03=*ON OR *IN25=*ON
*
C WRITE SCRN01
C EXFMT CNTR01
*
C EVAL @REBLD = *OFF
*
C IF *IN03=*ON
C LEAVE

- 215 -

Tips n Facts
C ENDIF
*
C SELECT
*
* ROLLUP KEY PRESSED...
*
C WHEN *IN25 = *ON
C EVAL @RRN = @RRN#
C EVAL @PAGE = (@PAGE +15)
C CLEAR @PASS
*
* ENTER-PRESSED...
*
C OTHER
*
C EXSR $CURSOR
*
C ENDSL
*
* REPOSITION/REBUILD SUBFILE WHEN THIS FIELD * IS ON...
*
C IF @REBLD = *ON
C EXSR $POSITION
C LEAVE
C ENDIF
*
C ENDDO
C ENDDO
*
C ENDSR
*
/EJECT
*
***********************************************
C $CURSOR BEGSR
* CURSOR POSITIONING...
***********************************************
*
C EVAL @PAGE = @FIRST
*
C @CURSOR DIV 256 SETROW
C MVR SETCOL
*
C IF GETRRN > *ZEROS
C GETRRN CHAIN SUBF01 99
C IF *IN99 = *OFF
C MOVE #FLDNAM RETURNNAME
C MOVE #DIGITS RETURNLEN
C EXSR $SHUT_DOWN
C EVAL *INLR = *ON
C RETURN
C ENDIF
C ENDIF
*
C ENDSR
*
/EJECT
*
*********************************************
C $FILLSFL BEGSR
* FILL SUBFILE...
*********************************************
*
C EVAL *IN75 = *OFF
C CLEAR F
*

- 216 -

Tips n Facts
C 1 DO @FIELDS F
*
C CLEAR @FLDLST1
C MOVEA @FLDNAM(F) #FLDNAM
C MOVEA @FLDTYP(F) #FLDTYP
C MOVEA @FLDLST(F) @FLDLST1
C Z-ADD @STRPOS #STRPOS
C Z-ADD @DIGITS #DIGITS
C Z-ADD @DECIMALS #DECIMALS
*
C ADD 1 @RRN
C ADD 1 @PASS
*
C WRITE SUBF01
C CLEAR #FLDNAM
C CLEAR #FLDTYP
C CLEAR #STRPOS
C CLEAR #DIGITS
C CLEAR #DECIMALS
*
C IF F = @FIELDS
C EVAL *IN75 = *ON
C ENDIF
*
C ENDDO
*
C ENDSR
*
/EJECT
*
******************************************
C $GETDBFLDS BEGSR
******************************************
*
* This is neat!!!
* We're using the "QUSFLD" *API to get
* the RECORD-FORMAT-LAYOUT for the FILE
* that's defined for this app...
* ------------------------------------------------------*
* First, we're gonna create a USER-SPACE in QTEMP
* to store all of the stuff we need...
*
* Now, we can create it...
*
C EVAL SpaceName = 'DSUSFD00'
C EVAL SpaceLib = 'QTEMP'
C MOVE SCRFLDDBFL InpFilNme
C MOVE SCRFLDDBLB InpFilLib
C EVAL BytesProvd = 116
C CALL 'QUSCRTUS'
C PARM UserSpace
C PARM *BLANKS SpaceAttr 10
C PARM 4096 SpaceLen
C PARM *BLANKS SpaceVal 1
C PARM '*ALL' SpaceAuth 10
C PARM *BLANKS SpaceText 50
C PARM '*YES' SpaceRepl 10
C PARM ErrorDs
*
C IF BYTESAVAIL <> 0
C EXSR $APIERRORS
C ENDIF
*
* Get the LIST FIELDs data for the FILE name passed...
*

- 217 -

Tips n Facts
C CALL 'QUSLFLD'
C PARM UserSpace
C PARM 'FLDL0100' ListFormat 8
C PARM InpFFilLib
C PARM SCRFLDDBRF InpRcdFmt
C PARM '1' OverRide 1
*
* Now, pull it in from the USER SPACE, with
* a RETRIEVE command...
* -----------------------------------------* Have to do this a couple of times, since,
* everything we need is sittin' in different
* parts of the USER-SPACE...
* -----------------------------------------* First, let's grab the GENERAL HEADER info from the *SPACE,
* and plop-it into the GENDS structure...
*
C EVAL StartPos = 1
C EVAL StartLen = 140
C CALL 'QUSRTVUS'
C PARM UserSpace
C PARM StartPos
C PARM StartLen
C PARM GenDs
*
* Then, grab some more, and put it into the HEADER
* structure...
*
C EVAL StartPos = OffsetHdr + 1
C EVAL StartLen = SizeHdr
C CALL 'QUSRTVUS'
C PARM UserSpace
C PARM StartPos
C PARM StartLen
C PARM HeaderDs
*
C EVAL SpaceName = 'DSUSFD00'
C EVAL SpaceLib = 'QTEMP'
*
C EVAL StartPos = OffsetLst + 1
C EVAL StartLen = SizeEntry
*
C CLEAR X
C CLEAR @FLDTYP
C CLEAR @FLDNAM
C CLEAR @FLDLST
*
* Now that we have some general information about the
* fields in the file, we can LOOP thru the next
* RETRIEVE, based on the number-of-fields counter,
* and grab what we need...
*
C DO NbrInLst
*
* Pull field-info and plop-it into the LIST structure...
*
C CALL 'QUSRTVUS'
C PARM UserSpace
C PARM StartPos
C PARM StartLen
C PARM ListDs
*
* We're gonna dump these values into arrays, because,
* we don't want too much I/O processing on FILES...
*
C EVAL X = (X + 1)

- 218 -

Tips n Facts
C MOVE SFFLD @FLDNAM(X)
C MOVE SFTYPE @FLDTYP(X)
C CLEAR @FLDLST1
C MOVE BUFFerout @STRPOS
C MOVE FIELDLEN @FLDLEN
C MOVE DIGITS @DIGITS
C MOVE DECIMALS @DECIMALS
C IF @DIGITS = *ZEROS
C MOVE FIELDLEN @DIGITS
C ENDIF
C MOVE @FLDLST1 @FLDLST(X)
*
C EVAL StartPos = StartPos + SizeEntry
C ENDDO
*
C ENDSR
*
/EJECT
*
**********************************************
C $SHUT_DOWN BEGSR
**********************************************
*
C EVAL SpaceName = 'DSUSFD00'
C EVAL SpaceLib = 'QTEMP'
C EVAL BytesProvd = 116
C CALL 'QUSDLTUS'
C PARM UserSpace
C PARM ErrorDs
*
C IF BYTESAVAIL <> 0
C EXSR $APIERRORS
C ENDIF
*
*
C ENDSR
*
/EJECT
*
*********************************************
C $APIERRORS BEGSR
**********************************************
*
* Standard API ERROR MESSAGE handling...
*
* --------------------------------------------------------*
C EVAL MESSAGEDTA = (MESSAGEDTA +
MESSAGEID)
C EVAL MESSAGEFIL = ('QCPFMSG ' +
'QSYS')
C EVAL MESSAGEID = 'CPF9898'
*
C CALL 'QMHSNDPM' PQHSNDPM
*
C ENDSR
*
/EJECT
*
****************************************
C *INZSR BEGSR
****************************************
*
C *ENTRY PLIST
C PARM SCRFLDDBFL
C PARM SCRFLDDBLB

- 219 -

Tips n Facts
C PARM SCRFLDDBRF
C PARM RETURNNAME
C PARM RETURNLEN
*
C PQHSNDPM PLIST
C PARM MESSAGEID
C PARM MESSAGEFIL
C PARM MESSAGEDTA
C PARM MSGDTALEN
C PARM MESSAGETYP
C PARM MESSAGEQUE
C PARM MSGQUENBR
C PARM MESSAGEKEY
C PARM ERRORDS
*
*
C ENDSR
*
/EJECT
*
Answer:
All you have to do is create a new record format: R DUMMY ASSUME 23 1 ' ' and the existing panel will not
be erased. This is a must for all windows. Strange is it not?
Answer:
To accomplish what you are asking is relatively easy: create DDS record format DUMMY and specifiy the
ASSUME keyword. You do not need to reference this format in your program. It's mere presence in the
display file will prevent the screen from being cleared. Another thing: if this program is being called by
other programs, make sure you do an explicit open/close of the display file, or exit with LR on
Answer:
The easiest way is to add another format to the display file that is never used but contains the ASSUME
keyword. The reason that your screen is being cleared is that when a display file is first used it always
clears the current screen. By using the ASSUME keyword you are telling the program that the display file
has already been opened. I hope this answers your question
Answer:
One more thing if you intend to use your window program as an attention key handler, you must specify
RSTDSP(*YES) on each and every display file that your attention key program may overlay, or as IBM is
wont to say "unpredictable results may occur." We changed the command default for CRTDSPF for this
very reason. Remember too, that you must explicitly close your window display file or exit your program
with LR on. If you don't do this the background screens from the first invocation of the program will be
retained behind your window not matter what is on the display when the program is subsequently called.
Answer:
If I remember correctly, you need to define a dummy record format with certain keywords. I'm not sure
what they are but can get an example id you still need help
Answer:
Try ASSUME for the keyword.
Answer:
You may insert the following dummy record instead:
*
* DER DUMMY SATZ MUSS VORHANDEN SEIN,
* AUCH WENN KEIN ZUGRIFF AUF IHN ERFOLGT !!
*
*----------------------------------------------------*
RADD A R DUMMY ASSUME
RADD A 11 1' '
Is there an easy way to change edit codes?
Question:
I am working with RPG/400 on a V3R1M0 and have following problem: Usually our edit format for numeric
fields is comma for decimal seperator (111.111,00) now we have a new customer who wants a point
(111,111.00). Do I have to define every output-field twice (al lot of maintenance) or does anybody know
something better. Maybe there is a way to control the edit format in the program? Please let me know.
Thanks
Answer:
This is a system value that can be found by using WRKSYSVAL. It allows you to change these settings. So,
if they are on a different machine, no problem.
Retrieve List of Files Used by QUERY/400
Question:

- 220 -

Tips n Facts
How do I do that?
Answer:
Recently there have been many folks wondering how to get a list of files used by Query/400 objects. This
can be particularly valuable information for Year 2000 issues. While RTVQMQRY will somewhat work for
the task, it has a few shortcomings. It's slow, chews up DASD storing the resulting source, you have to
scan and parse the resulting SQL source to get the file names, and it only shows input files -- if the output
of the query is to an outfile you're out of luck -- RTVQMQRY will not retrieve that information. There might
be a better alternative for you if you need to retrieve this information -- AND IT'S FREE!!! Some time ago
I wrote a RTVQRYF (Retrieve Query Files) utility. It is a MI program and it accesses the *QRYDFN objects
directly. Because of this, you must be at security level 30 or below to use the utility. It is located on the
NEWS/400 website, in the shareware section. You'll also need to download a MI compiler (if you don't
have one) to compile the source. You can also find this at the NEWS/400 website. I hope this utility helps
you out -- let us know what you think.
1. Download RTVQRYF utility now from http://www.news400.com/sharewarefiles/rtvqryf.zip
2. Download MI compiler now from http://www.news400.com/sharewarefiles/qir.zip
3. Check out the NEWS/400 website now at http://www.news400.com Auf wiedersehen, Gary Guthrie
NEWS/400 Technical Editor
Reusing deleted records - OK?
Question:
Anyone have experience with reuse deleted records ? I understand the concept and how to setup, but I've
heard horror stories about databases with it turned on ? We have multiple(4-5) databases with over 90
million records with 8-10 logicals over each one. We are also using a product called MIMIX that provides
database mirroring at an application level between to 530's soon to be 640's. What does this do to my
performance over time ??? Any thoughts ???? Is reuse deleted records a stable option for databases that
large ?
Answer:
So long as you have some non-user time available you should be able to REORG the files periodically. I
think this reclaims deleted records.
Answer:
We have used the REUSEDLT(*YES) parameters ever since it was introduced in V2R2. The Database Guide
lists the warnings, but I will reiterate some of the more important ones. You cannot specify re-use delete if
the physical file has any access path that specifies anything other than default ordering for duplicate keys.
All LF38 files have an implicit default ordering of FIFO. So these would have to be created. You should not
use EOFDLY on physical files unless you are reading sequentially by key. Any program that relies on new
records being added to the end of the file will not work as expected. When we started REUSEDLT we
dedicated a weekend for the access path rebuilds. We have had absolutely no problems with it for 6 years.
Not even a performance degradation that anyone has noticed. Make sure with Mimx that they support reuse delete before you start it. In 1992, they did not.
Answer:
We have used reusedlt since it was introduced on the System/38 with no problems. One of our clients
though some times uses relative record number to remove blocks of records added in error. Reusedlt will
not work for that.
Answer:
When I used it at a client site I didn't think through the ramifications and had problems for a few days
until it came to light. The program reads an unkeyed physical file from start to end (by RRN), then deletes
all records for the next cycle. Problem turned out to be that records that were loaded in a certain
sequence fell out of sequence since the indexes (RRN) went all over the place, so think it out first. BTW,
performance did improve for those couple of days. Ever try to do a DSPPFM on a physical whose first
record (because of deletes) was in the hundreds of thousands? If not, you have to wait sometimes
minutes for the screen to come up.
Answer:
I have seen a case were reuse caused problems. A batch program received records from a bisysc line and
wrote records to several data files. It would periodically submit other batch jobs to process it's output
files. These programs would then process the records and delete them. This created large numbers of
deleted records so we changed these files to reuese deleted records. Duplicate records started appearing.
We never determined whether duplicates were being wrtten or deletes were failing. We never saw any
triplicates or more and duplicates were very rare (one an hour with several thousand an hour being
processed.) Changed the files back and the problem dissapeared. This was 4 years ago on a B60 V2
somthing. I have see reuse used extensively on other machines with no problems.
Answer:
if you are using any logicals with LIFO sequencing then you cant use reuse as the LIFO depends upon the
Relative record number to work...probably a good idea to check this first.
Can you highlight code in SEU?
Question:
Does anybody know how I can high light a line of code or comment in my RPG source we I am editing it
with SEU?

- 221 -

Tips n Facts
Answer:
The attribute byte that does highlighting can't be entered on the keyboard, so you'll need another way.
One option is to use a program that does it for you (for example on all comment lines), or copy a line with
the attribute byte from another source (that way you can use Copy-Overlay in SEU).
Answer:
You cannot do it from within SEU, you have to write a program that reads a source file and inserts hex
code 22 before the text that you wish to highlight. Use the BITON/BITOFF command to setup the hex field
and insert it at the begining of the text that you want to highlight. Once you have got one highlighted line
you can copy it on from within SEU. Looks quite pretty for comment lines (but it's not to everyones taste)
Answer:
You must write hexadecimal value '22' on 5th position of the command RPG line.
Answer:
I remember an artical in News/400 (issue was in late 1993 to early 1994) that gave code to color your
source in SEU. It involved putting a display attribute in position 9. If you can find this artical it may be
what you are looking for.
Answer:
Are you interested in causing specific lines of source to appear highlighted when you view the member in
SEU? or do you want the current line to be automatically highlighted whenever you edit it? For the first,
you can imbed the hex value for the display attribute (highlight, blink, underline, color, etc.) directly in the
source statement. I do that by copying it in from another member. I have a source member named
COLORS that has one line for each attribute that I want. I copy the line that I want into the member I'm
editting and type over it. (I originally created this member by doing STRCPYSCN to an outfile while
viewing various panels that had different display attributes on different fields -- STRCPYSCN includes
attribute bytes in the output. You can then get that file into a source member and edit it to arrange things
as you like. Not very high-tech, but it was simple.) For the second, you'll either need to install something
other than SEU to do your editting or rely on the facility that SEU provides. SEU will highlight the line
number if you place the cursor on a line and press . Essentially, SEU shows you the line that you just
changed, not the one that you're changing 'now' (which I thought was what you asked for). As far as I
know, highlighting the line number is as far as it goes for SEU.
Problems with ZADD *ZEROS
Question:
It seems to me that there is a wrong value in a unsigned integer field after executing a Z-ADD *ZEROS
into that field! After the Z-ADD *ZEROS there is a value of 15 in the field. Z-ADD 0 is working fine!!!
Please have a look at the following test program:
*
D Unsigned S 10U 0 INZ(*ZEROS)
*
D Msg1 DS
D Text1 15A INZ('Old unsigned = ')
D Value1 10S 0 INZ(*ZEROS)
*
D Msg2 DS
D Text2 15A INZ('New unsigned = ')
D Value2 10S 0 INZ(*ZEROS)
*
C Z-ADD Unsigned Value1
C Msg1 DSPLY
*
C Z-ADD *ZEROS Unsigned
C Z-ADD Unsigned Value2
C Msg2 DSPLY
*
C MOVEL (P) '1' *INLR
Answer:
After I had reported the problem to IBM they told me that there are some PTFs available for V3R7 that fix
the problem. The PTFs are no available in a cumulative PTF yet. The numbers of the PTFs are: SF45417
and SF46327.
Answer:
Nice for the V3R7 users, but this is still happening in V4R1
A C function that returns a string to an RPG pgm
Question:
I'm writing a C function that to retuns a string to an RPG program. The format looks like this. char
*Func(parm) When the data gets back to my RPG program the string is all NULLs. I can pass the string in
the arguments like this int Func(*Stringparm, parm) But I need the string returned not passed as an
argument. Any suggestions? I'm stumped. Doesn't take much to stump me though since I am C novice
Answer:

- 222 -

Tips n Facts
The way that is typically done in C is to pass the string pointer as an argument and as the return value:
char* foo(char* bar) { strcpy(bar, "a string"); return bar; } C isn't like PASCAL in which the run-time will
allocate a specified as a return value -- you have to do the work yourself. This, by the way, was also
confusing to me when I first began learning C after writing a lot of Pascal programs. Hope this helps
What is the longest parameter usable in RPG?
Question:
Does anybody know of any limitation to the length of a character parm to an RPG program, for example...
*ENTRY PLIST PARM PARM1 70 PARM PARM2 6 PARM1 is 70 character string, PARM2 is 6 character string.
Can I do this? Or is there any limitation to the length of a parm? Like.... 33 characters?
Answer:
PARM1 at 70 is more than acceptable. I constantly use 100 byte parms. The limitation is the max length of
RPG, of course it depends on your version that you are using. RPG/400 max length is 256 for character
fields. We are running V3R2
Answer:
The main thing to watch out for with long character fields is that right-padding with spaces is not done
consistently if the field is over 32 in length. If your content does not fill the field, garbage characters may
end up padding the field on the right. In your example, the contents of PARM2 will probably end up in
PARM1 following the last non-blank character. If you need a field with a length greater than 32, you must
ensure that all characters are filled in. I usually handle this by making the field one character longer than
needed, and place some character such as "." in the final character.
Answer:
This is not entirely accurate, the 32 character limitation, only applies when you use the CALL command on
a command line to pass parameters to a program. When a HLL program calls another program, a pointer
to the string is passed to the sub-program. If the string declared in the main program is declared shorter
than the string in the sub-program, then the extra characters in the sub-program may actually overrun
some other storage from the main program. Any modifcation to the string by the sub-program could yield
"unpredicatable results". On the other hand, the sub-program declares the string as shorter than what is
passed, the subprogram will not have any problems but it won't be able to address all the positions in the
string. While strings may be limited to 256 in RPG/400, Data structures are not and can be passed as a
parameter.
Answer:
This is not entirely accurate, either. Calling a program with a character parameter (in a CL lets say)
greater that 32 character could very likely end up with garbage in the trailing character, even in the
parameter on the receiving program is declared the same size, type, etc. It's happened to me, and other,
many times before.
Answer:
I used to work on a project were every I/O was handled by a specific program. So in order to read/write
something, a program needed to call this routine with the record buffer (was always bigger than 32
bytes). In case it would give garbage as you stated, this project shouldn't have worked... however it did !
Answer:
Do you have a specific example of what you are describing? What you are describing has never happened
to me or to anyone else I know. And also runs contrary to any discussion of parameter passing I have
seen in any of the HLL manuals.
Answer:
Depends on how the program is called. There is no problem if it is called from another program using
variables for the parameters (using the correct definitions, of course). The padding happens when it is
called using literals, mostly when used from the command line.
Answer:
If you need more you can use arrays (up to 9999 times 256 bytes) or data structures (up to 32K ?)
Answer:
Your final statement "Like 33?" is telling. Can you supply an exact example of how the parameter is
created and used on the CALL statement? If the CALL happens at a command line or the parameter is a CL
literal value or any of a number of possibilities, you'll run into possible problems. By default, every *CHAR
parameter passed from CL has a minimum 32 character length. Up to 32 is always padded with blanks
even if you only pass a single character. Over 32, the parameter has a default declared length of whatever
the
length
of
the
literal
is.
If
you
issue
the
following:
===>
call
pgm(ABC)
parm('12345678901234567890') and receive it into a character variable declared as longer than 32
positions, there will be no padding at the rightmost end. Whatever was in memory after position 32
becomes part of the value of the received argument. Positions 21 through 32 should be blank, but the
rest? Who knows? (Actually, you CAN make some predictions, but that's irrelevant.) If you supply some
precise examples of the CALL, corrections can be given.
Getting the relative record number (RRN)
Question:
Does anyone know how to get the relative record number?
Answer:
Look for "IO feedback" subject in whatever you are trying to work with... I's all there.

- 223 -

Tips n Facts
Answer:
Here is a part of the I/O-feedback area for RPG-IV. There should be no problems to translate it to RPG-III.
FFILE00 UF F 4096 DISK USROPN
F INFSR(*PSSR)
F INFDS(File#00)
F COMMIT(CommitLVL)
*
DFile#00 DS
D F0Status 11 15S 0
D F0File 83 92A
D F0Library 93 102A
D F0Member 129 138A
D F0NbrOfKey 387 388B 0
D F0RcdNbr 397 400B 0
Answer:
IFDS. An answer as short and indescriptive as the question.
Answer:
Which RRN, the First on the Display?
FDISPLAY CF E WORKSTN
F RRN KSFILE SFLRCD
F KINFDS ###DSP
I###DSP DS
I *STATUS DSPSTS
I B 378 3790@SFLRN
@SFLRN will have the RRN for the first record on the subfile that is displayed, that is the number of the
record that is first on the current subfile 'Page'. If you want the RRN of the last record read with a READC,
that's RRN.
RPG Differences: V2R3 to V3R2 upgrade
Question:
Can anyone tell me the best place to find out about the differences in RPG that we will find when OS400 is
upgraded from V2r3 to V2r3? We developers will have little involvement in the upgrade process but will
need to know how it is going to affect us. I understand that we should be able to use RPG as we do
currently but that there could be better ways to use it when we upgrade. Also, will we automatically get
RPG IV and ILE? (Not that I really know what these are yet) Also, is there anything in particular we should
test for after the upgrade to confirm that our applications will still work and that we can continue to
develop those applications? I believe that the upgrades will go ahead on both our development and
production machines at the same time - ie there will be no lengthy testing. Does anybody think this is
risky?
Answer:
For each release of OS/400, there is a 'Memo to Users' document which contains useful information about
significant changes. I would advise you read the programming section of this document for V3R1 and
V3R2.
You
can
find
these
documents
online
at
http://as400service.rochester.ibm.com/as4sde/sline003.nsf/sline003home.
Answer:
We developers will have little involvement in the upgrade process but will need to know how it is going to
affect us. I understand that we should be able to use RPG as we do currently but that there could be
better ways to use it when we upgrade. Yes - there is a better way. Use RPG/IV. To use ILE means to learn
more about static linkage and so on, but to use RPG/IV you will only have to learn abut the OP-codes, new
built-in functions and the new source format. We have mae it in about 3 month without any additional
help. The next step is to use procedures instead of sub-routines. This is easy to. In procs you have the
advantage of local variables. In the third step, you will have to learn about static linkage, service
programs and so on. But I think that the speed advantage that static linkage will give you isn't worth it.
Also, will we automatically get RPG IV and ILE? (Not that I really know what these are yet) You will get
ILE-RPG as a licensed program from IBM. If you have licensed RPG/400, you will now get ILE-RPG and
RPG/400 automatically. > Also, is there anything in particular we should test for after the upgrade to
confirm that our applications will still work and that we can continue to develop those applications? We
have made the upgrade a time ago and everything went OK. I believe that the upgrades will go ahead on
both our development and production machines at the same time - ie there will be no lengthy testing.
Does anybody think this is risky? If you have two machines, make the upgrade on you developent
machine first and then give it a week to prove it. The upgrade isn't risky, but if you have the chance to
test it, use this chance.
Answer:
We developers will have little involvement in the upgrade process but will need to know how it is going to
affect us. Not, if you don't want it to, but you will have more possibilities. I understand that we should be
able to use RPG as we do currently but that >there could be better ways to use it when we upgrade. True.
Also, will we automatically get RPG IV and ILE? (Not that I really know what these are yet) ILE: You

- 224 -

Tips n Facts
already have it, but can't use it with RPG. You will be able to use it with RPG IV (or ILE RPG as IBM likes to
call it). There are lots of advantages and lots of disadvantages and it will take time to get accustomed to
it. RPG IV: You get it. Lots of improvements over RPG III. >Also, is there anything in particular we should
test for after the upgrade >to confirm that our applications will still work and that we can continue >to
develop those applications? Nope, everything will work. >I believe that the upgrades will go ahead on both
our development and >production machines at the same time - ie there will be no lengthy testing. >Does
anybody think this is risky?
RPG record locking
Question:
Hi everyone. We have a problem with several users trying to acces the same record , at the same time.
The timeout parm on the logical is set to 60 sec. and may not be changed, because of another problem,
but that another story. :-) Is there anyway to tell there is a lock on a record without having to wait until
the request times out.?? I use rpg/400. Please help..
Answer:
If you can't *change* the WAITRCD parameter, then why don't you try using the OVRDBF with
WAITRCD(0) in those programs that you don't want to have wait.
Answer:
When you chain to the file, also use a low indicator. If it comes on, the record is unavailable-so give your
user a message to try later. Also, you might want to explore techniques that limit record locking.
Answer:
If you are not doing updates, then use SETLL then READ to retrieve the record. If you are using CHAIN,
then use the 'N' to not lock the record. Hope this helps.
Answer:
How is a SETLL and a READ different from a CHAIN on an input only file? This is was you're saying, right?
Answer:
You might try using the error indicator on the CHAIN or READ operation you are using. I believe it's the LO
column, but not sure. On the other hand, why is everyone locking a record for such a long time? Is this a
file update program that someone likes to sit on for a while, and not realize the problem they are causing?
Or, could it be solved by using a nolock on the input operation and then reinputting (ie. CHAIN, READ)
when actual update occurs? Then again, you could use a dataq attached to the display file to kick
someone off if they sit on the same record for more than say 45 seconds or so. This could be a design
problem. I would look into using the nolock option on your input operation until right before you do the
update as a first solution.
Answer:
Since the original poster is new to the technique, it should be pointed out that the record contents should
be rechecked before the update occurs.
1. UserA reads record 1 (nolock) and sits on it.
2. UserB reads record 1 (nolock) also.
3. UserB quickly re-reads the record (with lock) and updates it.
4. UserA finally re-reads the record (with lock) and updates it also. If the program doesn't verify that the
record contents have changed between steps 1 and 4. UserA will overwrite UserB's changes.
Answer:
Another scenario: 1. UserA reads record 1 (nolock) and sits on it. 2. Another (batch) process changes
information in the record that is not on UserA's screen. 3. UserA wants to update the record, but is
informed that the record has changed. How annoying! We generally take the risk that 2 users might
interfere and don't worry about it. In the more than 10 years that my company is in business we never
had a complaint from any of our about 200 customers (which doesn't mean that it did not happen, of
course). We once developed a program template where only the fields that were modified on the screen
were output to the file, but it was a lot of coding, so we dropped it.
Answer:
That's right... UserB can be batch just as easily as interactive. In one application, with five users updating
a database of 25,000 applicants and 40,000 certificate records, the record-lock condition happened
around twice a year over a period of six years. No batch was involved, so take care on taking the ris
Answer:
I have this problem and the solution i came up with is: 1. use the error indicator on your chain command
2. immediately after your chain check the error indicator 3. at this point you can send the user a message
telling them that the record is in use or as i did call a cl to send the operator/mis person a message to the
effect that ???? has a record lock. 4. they can then find the person who probably went on break with the
record left on their screen and have them get out of it. 5. you can then let the user enter a "r" to retry
and have the program loop back to the chain command or have the mis person handle the retry and the
program automatically loop back to the chain.
Answer:
You can overwrite the recordwait time in a CLpgm before calling the RPG pgm or in a QCMDEXC call before
opening the file in the RPGpgm itself
Answer:

- 225 -

Tips n Facts
Great. OSITim has mentioned OVRDBF in the first answer to the question. If you prolong the time, the
user doesn't know why she/he cannot proceed. Most users will think that the AS/400-program is looping
or crashed, just like their PC-programs do from time to time. Or they think that the AS/400 is extremely
slow and they ask whether to buy a Pentium-processor for the AS/400. They might even use Attn-2 to
cancel or turn off the terminal (don't laugh! This shit happens!) to get rid of the Input Inhibited syndrom.
This is the worst case scenario, as the application program is most likely in a dangerous situation, from
the point of view of the data. --- So if the techniques described so far aren't good enough, combine them
with the old-fashioned way: some fields in the database that say "This record is locked by interactive
jobnbr/user/job since timestamp". The applications are not allowed to lock records when they wait for
user's input. They fill the fields mentioned above instead. They have to use error indicators on every
update/write, however. If something goes wrong, the program should do what the MIS personnel would
do. (An AS/400 is said to be operator-less. Programmers should pay attention to this point, especially
when they have an OS that enables them to!) Batch programs do not change the locked-fields, except
they change the same fields that the user is enabled to change. But this should be avoided by means of
mutexes or a self-written mechanism. If this is not possible, the batch-program has to exclude soft-locked
records. (10 of 11 records processed - 1 not processed. Does this sound familiar?) Applications are not
allowed to crash, they have to monitor everything (as mentioned above). Otherwise the soft-locker-fields
still soft-lock the record, although the application isn't active any more. (Extremely uncomfortable with
TCP/IP and changing device names!) That's why i suppose to store the job number, user and job name. If
the application runs into a "soft-lock", it might check whether the other job is still running. So, put as
many thought-pieces together as you want and build a solution. OS/400 offers enough power to do it.
Answer:
Maybe you can create another logical file with the same key, using the same DDS but giving the object a
different name. That way you don't have to use OVRDBF if at creation time you set the waiting time to just
a few seconds. In the other hand you have to determine if that is a good option; maybe you have already
a lot of LF's and adding a new one would slow down you system's performance. I hope you find what you
need between all the answers. :-)
OVRDBF and SECURE() keyword in an ILE environment
Question:
Does anyone know what the SECURE() keyword is supposed to do on the OVRDBF? It seems to have no
effect at all. Also, is it true that OVR's are not scoped to the call level in a native ILE application but rather
they are scoped to an activation group name? IOW, if I have programs A, B, and C all compiled to run in
activation group FUNNY, and program A calls, B calls C, and C does an override to file PF, and then returns
to B which in turn returns to A which performs an OPEN on file PF -- will program A use this OVR? Did you
get that?
Answer:
If you do the following: PGMA issues OVRDBF FILE(FUNNY) TOFILE(*LIBL/FUNNY) SECURE(*YES) This
then calls PGMB which calls PGMC PGMC issues OVRDBF FILE(FUNNY) TOFILE(QGPL/FUNNY)
SECURE(*NO) <--the default value PGMC then tries to OPEN file FUNNY. The original override will be the
one in effect. If the second OVRDBF also specified SECURE(*YES) then the second override would be in
effect. If an ILE program issues an OVRDBF command and the OVRSCOPE parameter is left at
*ACTGRPDFN, then the scenario you describe will be true. If you specify OVRSCOPE(*CALLLVL), then it
will work the "old" way. We were severely burned by this when we converted everything to ILE. I had a
tech tip published in News/400 about this a year ago or so. We just went through all of our CL and
specified the OVRSCOPE(*CALLLVL) to make the application work as before. Back to the SECURE issue,
one interesting situtation I bet that comes up, is that after PGMC goes out of scope, the OVRDBF
command that it issued would still be in effect, negating the original OVRDBF. If *CALLLVL were used, then
the original OVRDBF would come back into the picture.
Answer:
Thanks for the tip! I'll go back and re-read your News/400 article, and perhaps we will change our OVR
commands to use *CALLLVL. Actually, I'm not even sure this will work. You see, we are creating a
proecdure called CRTHUBDDM() that the user will call from their programs. This procedure will create a
DMM to the "hub" machine Db, and override the "F" spec to use this DDM file. The problem is, trying to
determine if there are any outstanding overrides in effect already against this file that the tool will OVR()
unbeknownst to the programmer.
Answer:
The ILE program must be running in an ILE activation group for activation group level scoping to take
effect. If it is running in the default activation group, call level scoping will be in effect.
Sorting a user space
Question:
Currently I get a list of jobs, by user, and place that into a user space. Unfortunately, when I push that list
into a UIM interface for a user to scroll and select from the list is not sorted. I would like to sort the data
in the user space. Does anyone know of a resource that I can use? I did not find a sort api anywhere......
My other choices are to sort the list in the uim (can this be done?) or put the list into a phyical file and do
the sort there. I don't want to do either of those :-(
Answer:

- 226 -

Tips n Facts
I would suggest reading the user space into an overlaying array. Then you can sort by any field in the
array very easily... something like this...
D USpaceArr DS 100 DIM(9999)
D UserName 10 overlay(USpaceArr:1)
D JobName 10 overlay(USpaceArr:10)
etc.... (hope this is right... not at work....)
The size of USpaceArr should be the total of bytes from all the fields defined using overlay. This way, you
can sort by any subfield using SORTA keeping the data intact and sequenced. Refer to subfileds as
UserName(i) or JobName(i) as you would any other array element. Hope this helps!
Answer:
You can use the QLGSORT API, or a user index.
Sockets in RPG?
Question:
Can anybody help me or say that it is posible to call a socket API from ILE RPG please I worked out most
of it but i always get a return value -1 calling socket() = unsuccesfull a little working example would be
nice i know i should use C400 but whe don't have it :( please help me out i'm really getting down here
Answer:
The necessary information (function prototypes) can be found in the manual "OS/400 Sockets
programming". Recently I programmed several Sockets applications from and to AS/400 and PC's using
Delphi without any problem. All this is done from ILE-RPG, and there's really no need to use C.
Answer:
Please, Please don't pull our legs...Please say its so ....I want to know too... I've read the same manuals
and they say we need C/400. If you could give us a short source sample.
Answer:
Since V3R2, ILE-RPG supports function prototyping and the use of pointers which made it possible to
use/call almost any function written in any language. Since to these set of functions, which required
languages like C in the past, also belong the Sockets functions no C/400 is required anymore. The
following examples should make it clear how to use the prototyping, and how to call the socket functions;
DOpenSock PR 10I 0 ExtProc('socket')
D prSockFam 10I 0 Value
D prAddrTyp 10I 0 Value
D prProtocol 10I 0 Value
DSock_Descr S 10I 0
DAddr_Fam S 10I 0
DAddr_Type S 10I 0
DProtocol S 10I 0
C Eval Sock_Descr = OpenSock(Addr_Fam:
C Addr_Type:
C Protocol)
The other prototypes (which are in C, but can be translated to ILE-RPG) can be found in the Sockets
Programming manual. Remember to use 5U, 5I, 10U, 10I as replacement for unsigned/signed, short/long
integers, or an * for pointers. I hope this gets you started... and BTW, translation from ASCII/EBCDIC can
be done with QDCXLATE (however iconv() works as well, but is a bit more complex to use).
Determining the calling program
Question:
Hello out there I have in my programming on the AS/400 reached a point of deadlock.... I have at
programme in which I have to know the name of the calling progamme (the progam that called the
current progam)... This sounds like a very easy task, but I can't use LDA or parameters... If any of you
out there can help me PLEASE do!!!!
Answer:
The following program returns in the &CALLER parameter, the program that invoked the program named
in the &PGM parameter. Example of use in your own program:
/* &MYNAME will contain the name of the program currently running */
CALL CALLER (&MYNAME '*')
/* &MYCALLER contains the name of the caller of the current program */
CALL CALLER (&MYCALLER &MYNAME)
PGM PARM(&CALLER &PGM)
DCL VAR(&CALLER) TYPE(*CHAR) LEN(10)
DCL VAR(&PGM) TYPE(*CHAR) LEN(10)
DCL VAR(&MSGKEY) TYPE(*CHAR) LEN(4)
DCL VAR(&SENDER) TYPE(*CHAR) LEN(80)
MONMSG MSGID(CPF0000) EXEC(GOTO CMDLBL(ERROR))
CHGVAR VAR(&CALLER) VALUE(' ')
SNDPGMMSG MSG('Who called me?') TOPGMQ(*PRV (&PGM)) +
KEYVAR(&MSGKEY)
RCVMSG PGMQ(*PRV (&PGM)) MSGTYPE(*INFO) +

- 227 -

Tips n Facts
MSGKEY(&MSGKEY) RMV(*YES) SENDER(&SENDER)
CHGVAR VAR(&CALLER) VALUE(%SST(&SENDER 56 10))
GOTO CMDLBL(ENDPGM)
ERROR: CHGVAR VAR(&CALLER) VALUE(' ')
ENDPGM: ENDPGM
Answer:
You can examine the Invocation stack of your job by using one of the Retrieve job API's or the DSPJOB
command.
What does the "optimize" parm do?
Question:
really would like to know what exactly does the 'Optimize' parameter of the Generation Options on the
crtpgm or chgpgm command does optimize. I remember that 4 or 5 years ago I once experimented with
it, putting the pgm parameters of our most used programs in production on Optimize, and as a result our
machines went crazy and lazy... Not much of an optimisation was done. Probably there are many
'optimisations' performed on the parameter, so , wath would it do now, either on a OPM or on a ILE pgm .
Our machines are on V3R7 and V3R6 (will be upgraded to 7).
Answer:
"Optimize" does a lot, but it can only speed up program execution, not disk I/O, etc, so there may or may
not be a significant improvement if you use it. While it is theoretically possible for "optimization" to make
performance worse, in practice this doesn't happen to any extent. (There are some programs that are
"hard to optimize", and these may end up being 1-2% worse, but they are rare.) When optimization works
well (best on large programs without a lot of calls), the improvement can be 4:1 or better (though this is
also rare). Typical results would be 30% to 50% reduction in CPU time.
QRYDFN to source and back
Question:
I know I can convert a qrydfn object into a source file but how do I take that source file and recreate the
qrydfn.
Answer:
The conversion I assume you refer to is RTVQMQRY . From a retrieved source for QM query, you can only
create a *QMQRY object ; there is no CRTQRYDFN command to create a query definition from source.
Answer:
Remember that RTVQRYSRC is a S/38 command with a corresponding CRT. But I can't recall what the CRT
command was. Maybe Jack's using RTVQRYSRC or running on a S/38.
Answer:
Sure, but then it would not be a QRYDFN object ;-) The command for that would be CRTQRYAPP which
creates a *PGM object; the interactive design method being DSNQRYAPP .
Answer:
Ah, yes. It starts coming fully back to me now. How quickly we forget the good ol' days after something
better comes along.
Packed or unpacked fields?
Question:
Packed or unpacked ? We are in the process of deciding whether we should pack or not our fields in our
files, and we are wondering the following :
1. what are the advantages of unpacked vs packed
2. it is deemed that unpacked is more performant, but "how more" (if true) ?
3. are there any limitations with unpacked fields as far as coding (RPG) is concerned ? Any answer ?
Thank you
Answer:
fields in our files, and we are wondering the following :
a. what are the advantages of unpacked vs packed Packed decimal fields take about half the space to
store as zoned decimal. (unpacked) Unsigned Zoned fields are more easily transferred with FTP.
(Although you lose the decimal)
b. it is deemed that unpacked is more performant, but "how more" (if >true) ? I doubt there is a
performance difference between the two representations. If there is, it is not likely to be significant.
c. are there any limitations with unpacked fields as far as coding (RPG) >is concerned ? RPG handles
either type easily and does conversions as needed.
Answer:
Packed is supposed to be much more efficient that signed (probably because of doing BCD arithmetic).
One disadvantage I can think of is exemplified by what passed through this news group some weeks ago:
FTP-ing data cannot translate packed into something readable by other systems (eg, ASCII). Within RPG
programs there is no difference between packed variables and signed. One other thing to look out for is to
try to make all your packed field lengths an odd number, like 9,2 or 11,4 etc. The extra MI instructions to
pad evenly sized fields is supposed to be substantial.
Answer:
Packed: Less space (but what's a few bytes on todays disks) Unpacked: Better legibility with DSPPFM (but
SQL and Query have no problems with packed) >b) it is deemed that unpacked is more performant, but

- 228 -

Tips n Facts
"how more" (if >true) ? As I understand it arithmetic is done with packed fields, so unpacked fields will
have to be converted. But the difference will probably only be notable when you do lots of arithmetic and
hardly any screen or disk IO. >c) are there any limitations with unpacked fields as far as coding (RPG) >is
concerned ? None that I know of. >Any answer ? >Thank you So you picks your choice and pays your
money. Not too much difference, really.
Answer:
In general, packed is faster than unpacked. But the difference would be marginal in most cases.
Using IFS APIs w/ ILE RPG
Question:
Sometime back, someone posted the correct way to write data to an IFS file using ILE RPG and the IFS
write() API. I didn't bother looking at it because I use the QDCXLATE program to transalate from EBCDIC
to ASCII before writing. Now, I want to read from an IFS file (using read()) and then write a different file
back out. Most IFS files that I read work fine but I've run into one from an outside vendor that doesn't
work. The file is in ASCII, but when I write it back out, it's get translated back to EBCDIC. I verified this
by converting the data using QDCXLATE before writing back out. Does anyone have the correct way of
doing this? It had something to do with the codepage parameter.
Answer:
Here is some code for writing and reading files to the IFS system. My understanding was you had to open
the file with create first so that the conversion with the code page will work properly. I know the following
code works good.
D RC S 10I 0
D FileNam S 50A INZ('/qualcomm/test1'
D FileNamP S * INZ(%ADDR(FileNam))
D FileDescr S 10I 0
D O_CREAT S 10I 0 INZ(8)
D O_RDWR S 10I 0 INZ(4)
D O_TEXTDATA S 10I 0 INZ(16777216)
D O_CODEPAGE S 10I 0 INZ(8388608)
D Oflag S 10I 0 INZ(0)
D Omode S 10U 0 INZ(511)
D cp S 10U 0 INZ(819)
D ZeroBin S 1A INZ(*ALLX'00')
D NLZero S 2A INZ(X'1500')
D SI_Fmt S 50A INZ('\n')
D SI_FmtP S * INZ(%ADDR(SI_Fmt))
D SI_Msg S 50A
D SI_MsgP S * INZ(%ADDR(SI_Msg))
D Num_DS DS
D Num_Hex 4A INZ(X'00000000')
D Num 10I 0 OVERLAY(Num_Hex)
D Buf S 100A
D BufP S * INZ(%ADDR(Buf))
D BufLen S 10U 0
D/copy IFSHEAD
C EVAL FileNam = %TRIM(FileNam) + ZeroBin
C Z-add O_CREAT Oflag
C Add O_RDWR Oflag
C Add O_CODEPAGE Oflag
C EVAL FileDescr=open(FileNamP:Oflag:Omode:cp)
C IF FileDescr = -1
C EVAL RC = perror(FileNamP)
C Return
C ENDIF
C EVAL RC = close(FileDescr)
C IF RC = -1
C EVAL RC = perror(FileNamP)
C Return
C ENDIF
C Z-Add O_RDWR Oflag
C Add O_TEXTDATA Oflag
C EVAL FileDescr=open(FileNamP:Oflag)
C IF FileDescr = -1
C EVAL RC = perror(FileNamP)
C Return
C ENDIF
C EVAL Buf='This is a Test number 1' + X'25'

- 229 -

Tips n Facts
C X'25' SCAN Buf BufLen 30
C EVAL RC = write(FileDescr: BufP: BufLen)
C IF RC = -1
C EVAL RC = perror(FileNamP)
C Return
C ENDIF
* Close the File
C EVAL RC = close(FileDescr)
C IF FileDescr = -1
C EVAL RC = perror(FileNamP)
C Return
C ENDIF
The following is the IFSHEAD file that I copy in.. There are defined routines here that I use in other
programs .. I just keep them all together as I create new headers for C functions..
Dperror PR 10I 0 EXTPROC('perror')
Dconst * VALUE
Dsprintf PR 10I 0 EXTPROC('sprintf')
D * VALUE
D * VALUE
D 10I 0 VALUE OPTIONS(*NOPASS)
D * VALUE OPTIONS(*NOPASS)
* Open Operations
* value returned = file descriptor 0 (OK), -1 (Error)
Dopen PR 10I 0 EXTPROC('open')
D * VALUE
D 10I 0 VALUE
D 10U 0 VALUE OPTIONS(*NOPASS)
D 10U 0 VALUE OPTIONS(*NOPASS)
* Read Operations
* value returned = number of bytes read or , -1 (Error)
Dread PR 10I 0 EXTPROC('read')
D 10I 0 VALUE
D * Value
D 10U 0 VALUE
* Write Operations
* value returned = number of bytes Written or , -1 (Error)
Dwrite PR 10I 0 EXTPROC('write')
D 10I 0 VALUE
D * VALUE
D 10U 0 VALUE
* Close Operations
* value returned = 0 (OK) or , -1 (Error)
Dclose PR 10I 0 EXTPROC('close')
D 10I 0 VALUE
* Open Directory Operation
* value returned = file descriptor 0 (OK), -1 (Error)
Dopendir PR * EXTPROC('opendir')
D * VALUE
* Read Directory Operation
*
Dreaddir PR * EXTPROC('readdir')
D * VALUE
* Open Directory Operation
* value returned = 0 (OK) or , -1 (Error)
Dclosedir PR 10I 0 EXTPROC('closedir')
D * VALUE
* Unlink a File from system... Delete File
* value returned = 0 (OK) or , -1 (Error)
Dunlink PR 10I 0 EXTPROC('unlink')
D * VALUE
Subfile Window background problem
Question:
IBMers Please help ... window background I know it as been discussed more than often! But I still dont
know the right solution! Although Ive tried almost anything! Why do I get an OLD or totally EMPTY
background for my windows the second time I display them? I prefer to end my RPGLE program with
RETURN. There for Ive tried to open my displayfile USER CONTROLLED ... no solution when calling the

- 230 -

Tips n Facts
same window from more than one processed subfile record of the main program! Ive expirmented with
the USRRSTDSP keyword, no use ... Could somebody please help my out ... Thanks Ron
=================================== See here my window example: PS The dummy
record "WINDOW" is not really used within my program. PS The field *RTNUMM and *VTRVLG are numeric
6,0 and 3,0.
A*****************************************************************
A* Create DisplayFile Keywords:
A* CRTDSPF RSTDSP(*YES)
A*****************************************************************
A DSPSIZ(24 80 *DS3)
A REF(*LIBL/@FRF FRFR)
A PRINT(*LIBL/QSYSPRT)
A ALTHELP(CA01)
A HELP
A HLPSCHIDX(*LIBL/@IDX)
*****************************************************************
* DUMMY WINDOW RECORD TBV ASSUME
*****************************************************************
A R WINDOW
A ASSUME
A #PGMID 10 1 2
A*****************************************************************
A* SELECT Display X1
A*****************************************************************
A R SLCTX1
A WINDOW(MSGCTLX)
A CF04
A CF06
A CF12
A CF18
A CF23
A CF24
A VLDCMDKEY(55 'Valid command
key')
A CSRLOC(#ROW #COL)
A RTNCSRLOC(&#CSRRCD &#CSRFLD &#CSRPOA S)
A CHANGE(40 'SLCTX1 Changed')
A OVERLAY
A #ROW 3S 0H
A #COL 3S 0H
A #CSRRCD 10A H
A #CSRFLD 10A H
A #CSRPOS 4S 0H
A $1RTNUMM R O 5 32REFFLD(@@RTNUMM)
A $1VTRVLG R B 6 35REFFLD(@@VTRVLG)
A 80 DSPATR(PC)
A 80 DSPATR(RI)
A 69 DSPATR(ND) DSPATR(PR)
A $2VTRVLG R B 6 52REFFLD(@@VTRVLG)
A 81 DSPATR(PC)
A 81 DSPATR(RI)
A 69 DSPATR(ND) DSPATR(PR)
A $2RTNUMM R B 8 32REFFLD(@@RTNUMM)
A 82 DSPATR(PC)
A 82 DSPATR(RI)
A $3VTRVLG R B 9 35REFFLD(@@VTRVLG)
A 83 DSPATR(PC)
A 83 DSPATR(RI)
A*****************************************************************
A* MESSAGE Subfile Record X
A*****************************************************************
A R MSGSFLX SFL
A SFLMSGRCD(12)
A #MSGK SFLMSGKEY
A #PGMQ SFLPGMQ(10)

- 231 -

Tips n Facts
A*****************************************************************
A* MESSAGE Subfile Control X
A*****************************************************************
A R MSGCTLX SFLCTL(MSGSFLX)
A OVERLAY
A 44 SFLDSP
A 44 SFLDSPCTL
A 44 SFLINZ
A 44 SFLEND
A SFLSIZ(0002)
A SFLPAG(0001)
A USRRSTDSP
A WINDOW(*DFT 12 55 *NOMSGLIN)
A WDWBORDER((*COLOR BLU) (*CHAR'...:A ::.:'))
A #PGMQ SFLPGMQ(10)
A*****************************************************************
Answer:
It's in the RSTDSP(*YES) parameter. When the window is first displayed, the background over which it is
displayed is saved. The next time it is displayed, the saved background is restored. You can try it out with
CHGDSPF RSTDSP(*YES|*NO).
Answer:
There are other implications of changing RSTDSP to *NO that may present some problems to you. If you
have any attention key programs that open display files, or message break handling programs that open
display files, then you *MUST* use RSTDSP(*YES) otherwise your display files will not be properly
restored when the attention or break handling programs finish. The only solution I have found when
RSTDSP(*YES) is specified, is to have the window display file opened at program start and closed at
program end. Setting LR on when your program finishes, automatically closes any files for you. If you
simply want to RETRN then you must explicitly close the window display file. BTW, if your window display
file as the KEEP keyword specified, then this prevents the display file from being fully closed, so take it out
if it is there.
Answer:
There for Ive tried to open my displayfile USER CONTROLLED ... This work !! always remember, you have
to open the Display file as you entre the program and close it before the RETRN. I've done this several
time: works fine. Btw, if someone know a better way... or. if IBM is thinking about fixing this hole...
CPYSPLF Automation
Question:
I had the same question that is posted here many times, about converting a spooled file to a PC file. I can
do this manually thanks to the CPYSPLF command and FTP. However, now I want to automate the process,
but the piece I'm missing is how to obtain the spool file information in a CLP program to automatically run
the CPYSPLF command. There is a lot alluding to this process, but no examples of how to code it.
Particularly, I need to be able to get the SPOOL FILE NUMBER, because, for the most part, the JOB and
USER name are always constant. Thanks in advance.
Answer:
the more easy way if you can is to include CPYSPLF just after print program and use *last (or *only if it is)
as number.
Answer:
Two possible APIs, depending on exactly how much you know at the time the function runs and exactly
what you need to know. Both are in the Print APIs section of the API documentation. The first is the List
Spooled Files (QUSLSPL) API and the second is Retrieve Spooled File Attributes (QUSRSPLA). The first will
return a list of spooled files depending on what you ask for, e.g., all spooled files for current user, all
spooled files on a particular outq, etc. And the second returns the attributes for a specific spooled file. If
you know you want the *LAST splf named QSYSPRT for the current job, then all you need is the second
API. Lots of combinations possible.
Answer:
Yes, there are APIs to retrieve spooled file information, but maybe you'd like the use of a data queue
connected with the output queue(s). You then receive an entry in the dtaq every time a spooled file gets
the status READY. In the entry, you find all infos to access the spooled file, including spooled file number.
This is the best performing method; you do also use a minimum of system ressources, when you wait "for
ever" for a data queue entry.
Answer:
This can be pretty easy assuming a couple of things:
1. The copy take place withing the same job stream
2. There is only one spool file or the one you are coping is the last one. #2 can be worked around if
the statement is not true. Use the SPLNBR parameter of the CPYSPLF command. SPLNBR can be

- 232 -

Tips n Facts
*ONLY (the only spool file for the job), or *LAST (the last spool file for the job), or the actual
spool file number.
Answer:
The best way to retrieve spool file info is to use a data queue attached to the output queue. When a spool
entry goes to ready in the output queue, an entry is written to the data queue with all the spool file's info.
You can then receive the data queue entry and substring the field entry into info needed for CPYSPLF. The
layout of the data queue entry can be found in the "IBM Printer Device Programming Guide". I have done
this many times and works great.
Answer:
There are two problems with the *dtaq method that irritate me. First, the *dtaq entry is sent when a
spoolfile goes to *RDY status; *HOLD or any other status doesn't do it. And second, a *dtaq entry is sent
*every* time a spoolfile goes to *RDY status; place the spoolfile on *HOLD, then release it and you get
another *dtaq entry. That is, the *dtaq entry is not sent when a spoolfile arrives on the *outq; the entry is
sent "when a spoolfile goes to *RDY status". Do you have a way around either of those issues?
Answer:
I just wrote a program that does pretty much the same thing. It constantly monitors an outq. When a new
file pops up, it moves the file to a new outq. It is a never ending C/L program that sleeps once in awhile
then calls an RPG program to do the dirty work. The heart of it is in the RPG program. Using QCMDEXC it
runs WRKOUTQ OUTPUT(*PRINT), then copies that spool file to a data base file. Then it deletes the
WRKOUTQ spool file. The data base file now has more than enough information in it (including job
number) to make decisions and run further commands against the spool files on the outq being
monitored. I am running CHGSPLF but CPYSPLF will work just fine. If this meets your needs and you need
further information let me know. John P.S. I tried using API's to list the spool file into a user space and
read the user space but I was getting weird results. I was running out of time (and getting pissed) so I did
it the old fashioned way.
Answer:
I use both *dtaqs and the APIs, depending on what I need. No weird results with the APIs except when I
have more spoolfiles than they can handle. (We routinely have 100,000 or more spoolfiles in our biggest
system.) So, I'm now digging into the various 'Open List' APIs to see how they can help.
CVTDAT
Question:
I am trying to use the CVTDAT command on V3R2 to convert an *MDY to a *LONGJUL. I keep getting the
message that *LONGJUL is not supported. I've recently loaded PTF SF36257 but that doesn't fix it. Any
ideas?
Answer:
I ran the following little test on my V3R2 system sucessfully. Everything ran fine. Used the debugger and it
confirms the field &ToDate contains the value '1998/001' after the program invokes the CvtDat command.
*************** Beginning of data ***************************
Pgm
Dcl &FromDate *Char 06 '010198'
Dcl &ToDate *Char 08
CvtDat Date( &FromDate ) +
ToVar( &ToDate ) +
FromFmt( *MDY ) +
ToFmt( *LongJul )
EndPgm
*************************************************************
I never applied any special PTFs. I am at cume level 96317 (fairly old).
Answer:
Thanks for your help. Upon further inspection I found the Member Type was CLP38. When I changed it to
CLP it amazingly worked! It's always the simple things, isn't it? Thanks again.
Calling AS/400 APIs from ILE RPG
Question:
I am working on a project that requires the use of the Dynamic Screen Manager APIs, but try as I might
there seems to be no way of declaring the call to match the parameter requirements of the API. The
problem seems to be that all RPG calls, ILE or otherwise, whether you specify that the parameter is
passed by reference, value or as a constant, the parameter passed is always the address of the data. Now
in normal inter language calls this is OK. CL expects this and C is quite happy because all the parameters
are just declared as being passed as pointers. Then you try and use the AS/400 APIs. I don't know if you
have studied the APIs much, but the vast majority of parameter calls require that the parameter is passed
by value, not by address. Until now have had no choice but to write a noddy little wrapper routine in C so I
can cast the data types and call the API, but surely there must be a way of calling the API directory from
ILE RPG. What was wrong with the API designers when they wrote AS/400, didn't they think RPG would be
used for writing programs? If anyone has any idea at all how the hell you can call an API where the
parameters need to be passed by value, please let me know. NOTE: The value keyword on procedure

- 233 -

Tips n Facts
declarations does not actually pass the parameter by value, the procedure has code to copy the contents
of the passed variable into the local variable at run time.
Answer:
I guess I don't quiet understand your problem. I have used MANY system APIs with RPG with no problem
whatsoever. Do you have any examples?
Answer:
I will give you an example. The Dynamic Screen Manager APIs tend to have their parameter lists set up to
pass by value rather than by reference. Here (off the top of my head) is one specific example. The API
QsnCrtCmdBuf is passed 5 parameters as follows,
p1 Initial buffer size int or 10I in rpg
p2 increment size int ditto
p3 max size int ditto
p4 address of buffer handle long *
p5 error data structure char *
this differs say from the dataqueue send APIs which expect all of their parameters to be pointers. The
above API, because pointers are 16 bytes long on the AS/400, decides to pass the variable contents
instead, presumably for performance reasons. Now If you read the AS/400 ILE RPG manuals carefully you
spot a pattern. The PARM statement explicitly states that parameters are passed by reference. Hence you
can never receive a parameter into a data structure because it is already allocated in storage elsewhere.
Using procedure calls you may be forgiven for thinking that parameters are passed differently, but this is
not the case. Parameters can be passed by reference, value and as const. Pass by reference is exactly the
same as using parm, and the parameters must match exact size ad type for obvious reasons. Pass by
value allows you to use different field sizes and types. This is because the parameter is copied into the
storage of the procedure. Pass as const is an interesting one. It is supposed to represent a read only
variable, but if you read the manuals carefully you see that you have to make sure the procedure does not
change the variable. Why? well obviously because it is really being passed by reference, and changing it
would change the original storage, even if it is a constant !! So this leaves me believing that it is not
possible to call a lot of the system APIs, because as I said earlier some of them expect the variable
contents to be passed on the stack (if the AS/400 has a concept of a stack) instead of the reference to the
variable. Another give-away is the fact that functions like QsnCrtCmdBuf returns a result field as well, and
there is no support for this in RPG without procedures. Have you written much in C ? If you have then the
above can be explained more simply by showing that variables are always passed by address e.g..
callproc(&parm1, &parm2, &parm3);
.
.
.
callproc(int *parm1, char *parm2, packed(7,2) *parm3)
{
.
.
If you have any examples of code you have written to such APIs as these, I would love to see how you
coded them.
Answer:
I have created ILE RPG prototypes for the APIs that I use. When you create the prototype you can specify
that the parameter is passed by value, then just use the CALLP opcode. Works quite well.
Answer:
Unless a program (including an API) is expecting to receive a parameter passed by value, this will not
work. C library functions receive parameters by value. However, most other APIs receive parameters by
reference. Maybe you're referring to passing by read-only reference (i. e., specifying the Const keyword in
an RPG IV prototype). Mike Cravitz NEWS/400 Technical Editor
Answer:
You're clearly bringing up an interesting issue. Not being a C expert, I can't say much one way or another
except that I've used numerous APIs with no noticeable problem. I've yet to run into an API that I can't
call successfuly in ILE RPG in fact. (Unfortunately, I have yet to get into DSM.) The IFS APIs in 'OS/400
UNIX-Type APIs' are examples where prototyping for the VALUE keyword seems to work just fine. By just
looking at the documentation, I don't see any significant difference between the ways the DSM APIs and
the IFS APIs are defined. So, my first question is: How can you tell by looking at the documentation that
the DSM APIs will react to parameter definitions differently than the IFS APIs, for example? Are IFS APIs
*not* expecting parameters to be passed 'by value'?
Answer:
The following little program in ILE RPG uses a few of the DSM API's. Browsing quickly through the API
reference manual I couldn't see any DSM API's requiring value declarations.
D f3 c x'33'
D sa_norm c x'20'
D txt s 128 inz('Press Enter to Roll, F3 to quitD .')

- 234 -

Tips n Facts
D txtlen s 9b 0 inz(32)
D err s 8 inz(x'0000000000000000')
D aid s 1
D lines s 9b 0 inz(1)
D wf1 s 1
D wrtn s 9b 0
D clrscr pr 9b 0 extproc('QsnClrScr')
D mode 1 options(*nopass) const
D cmdbuf 9b 0 options(*nopass) const
D env 9b 0 options(*nopass) const
D error 8 options(*nopass)
D wrtdta pr 9b 0 extproc('QsnWrtDta')
D data 128
D datalen 9b 0
D fldid 9b 0 options(*nopass) const
D row 9b 0 options(*nopass) const
D col 9b 0 options(*nopass) const
D strmatr 1 options(*nopass) const
D endmatr 1 options(*nopass) const
D strcatr 1 options(*nopass) const
D endcatr 1 options(*nopass) const
D cmdbuf 9b 0 options(*nopass) const
D env 9b 0 options(*nopass) const
D error 8 options(*nopass)
D getaid pr 1 extproc('QsnGetAID')
D aid 1 options(*nopass)
D env 9b 0 options(*nopass) const
D error 8 options(*nopass)
D rollup pr 9b 0 extproc('QsnRollUp')
D lines 9b 0 const
D top 9b 0 const
D bottom 9b 0 const
D cmdbuf 9b 0 options(*nopass) const
D env 9b 0 options(*nopass) const
D error 8 options(*nopass)
C eval wrtn = clrscr('0' : 0 : 0 : err)
C dow wrtn = 0
C eval wrtn = wrtdta (txt : txtlen : 0 : 23 : 2 :
C sa_norm : sa_norm : sa_norm : sa_norm :
C 0 : 0 : err)
C eval wf1 = getaid (aid : 0 : err)
C if aid = f3
C leave
C endif
C eval wrtn = rollup (lines : 1 : 24 : 0 : 0 : err)
C enddo
C eval *inlr = *on
Remember to bind this to serviceprogram QSNAPI
SQL in a CL program
Question:
Is this posible and if so does someone have an example. I have no problem with SQL in RPG but I have
not found any example of its use in CL programs.
Answer:
SQL works in RPG because there's a pre-compiler that converts the SQL sections into "real" RPG code. IBM
has not supplied a similar pre-compiler for CL. I suppose there's nothing to stop a 3rd-party from doing it.
Or, you could examine the pre-compiled RPG and make similar CALLs and CHGVARs, etc., in your CL. It'd
be interesting to see how it turned out. However, CL can execute RUNSQLSTM and STRQMQRY. SQL
procedures and statements can be invoked that way; not in the same way as in RPG, but often usefully
enough. BTW, REXX can also include SQL.
Answer:
SQL in CL is also no problem. Add this line to your CL program: 0037.00 RUNSQLSTM
SRCFILE(WWLIB/QCLSRC) SRCMBR(MYSQL) COMMIT(*NONE) An SQL member looks like this: (the
member type in PDM is 'SQL' instead of 'CLP')
0002.00 INSERT INTO ELABACK/TAGESVORG
0003.00 SELECT DISTINCT(A7AENB) FROM ELABACK/ASA7SIC;
0004.00

- 235 -

Tips n Facts
0005.00 INSERT INTO ELABACK/ASALSIC SELECT B.ALAENB, B.ALACDA, B.ALABTM,
0006.00 B.ALAUCD FROM ELABACK/TAGESVORG A, ELADTA/ASALCPP B WHERE A.A7AENB 0007.00 =
B.ALAENB;
0011.00
0012.00 DELETE FROM WEISS/ASALCPP
0013.00 WHERE ALAENB IN (SELECT A7AENB FROM ELABACK/TAGESVORG);
0014.00 INSERT INTO WEISS/ASALCPP SELECT * FROM ELABACK/ASALSIC;
Note: *** RUNSQLSTM runs the whole SQL member, no way to select only one statement of it. So you
must create more SQL members for a CLP, if you need to run the statements from several places of your
CLP. Perhaps like this: CLP = MYCLPGM, SQL members: MYCLPGM1, MYCLPGM2, ... then you have them
right below the CL in PDM. *** Create and test the SQL statements with STRSQL and then use the save
option to store them into a source member. *** Seen the ';' at the end of each line? It's important.
Detecing IFS Files from RPG
Question:
I need a way to detect if an IFS file exists from an RPG program. Anyone familar with a way to do this? It
needs to be detected by file name.
Answer:
You do not specify what version of RPG. With ILE you can do the following:
* FileExists
* Nick Roux
* 1997/10/02
*
* NOTE: Compile with DFTACTGRP(*NO)
*
* IFS API prototypes
*
* Access
*
Daccess PR 10I 0 extproc('access')
Dpathptr1 * value
Dmode1 10I 0 value
*
* IFS API Constants
*
DF_OK S 10I 0 inz(0)
*
* Some working environment for us
*
DFile_exists S 10I 0
Dpathptr S *
Dpathname S 21
DExists C 'File Exists'
DNotExists C 'File does not exist'
*
* Main{}
*
C *entry plist
C parm filename 20
* Set a character pointer to the file name string
C eval pathname = %trim(filename)+x'00'
C eval pathptr = %addr(pathname)
* Call the IFS API
C eval File_Exists = access(pathptr:F_OK)
* Did we find it?
C File_exists ifeq 0
C Exists dsply
C else
C NotExists dsply
C endif
* Thats all folks
C move *on *inlr
The filename should be supplied as //dir/dir/file, i.e. CALL FILEEXISTS ('//etc/pmap') is a valid call.
Answer:
I created a command that functions similarly to the CHKOBJ command, except for an IFS object. The
"heart" of the command is the following C code, which could also be created in ILE RPG by correctly
protyping the "access" API being used by the C function.

- 236 -

Tips n Facts
/*
** CHKIFSOBJC
*
* PARAMETERS: Path to file
*
* DESCRIPTION: Check for IFS object
*
* RETURNS: Y if objects exists
* N if object does not exist
*
*/
char CHKIFSOBJC(const char* reffile) {
if( access(reffile, F_OK) != 0)
return 'N';
else
return 'Y';
}
The only problem with using any IFS API, is that adopted authority does not work, which means the user
executing the program must be authorized to the entire path, and to the file itself, or else the function will
look like the object does not exist. I have solved this problem by front-ending the above code with other
code that temporarily changes the job user to a profile with sufficient authority. This uses the QSYGETPH
and QSYSETP API's. Hope this helps,
Help with data area API
Question:
I need help with the QWCRDTAA api. I have copied the data structures from the system include source file
and added space for the variable data to be returned at the end. The length of both the receiver variable
and the error parameter DS is 32767. The ILE RPG compiles without error, but the call to the API errors
out with the message "Receiver value to small to hold output." That is VALUE and not variable. The error
returned in the Error DS is the ever-popular CPF9999. What I need to do is print the contents of every
data area in a given library. QUSLOBJ gives me the list of names (and that part of the program works
fine). Now I want to walk through that list and access each data area on the list. Can anybody share an
example of a call that works?
Answer:
Whenever you define a binary field in the D-specs in RPG IV, you need to make it 9 positions. The API
docs make you assume 4 positions, but that is the physical length. Remeber, most of the API
documentation was written before RPG 4 came out. Make sure that the receiver variable is as long as the
longest data area you'll be accessing, and the length parameter must match it. Code your DS in RPG III
with the binary values as B 4, run it through CVTRPGSRC, and you'll see what I mean. HTH,
Answer:
Here is an example of using QWCRDTAA from ILE RPG.
D* copy qsysinc/qrpglesrc,qwcrdtaa into source to change QWCVALUE
DQWCRDRTN DS
D* Qwc Rdtaa Data Return
D QWCBAVL 1 4B 0
D* Bytes Available
D QWCBRTN 5 8B 0
D* Bytes Returned
D QWCTVRTN 9 18
D* Type Value Returned
D QWCLIBN 19 28
D* Library Name
D QWCLVRTN 29 32B 0
D* Length Value Returned
D QWCNBRDP 33 36B 0
D* Number Decimal Positio
D QWCVALUE 37 512
D*
D* Varying length MODIFIED and uncommente
D*
D/copy qsysinc/qrpglesrc,qusec
D*
Drcvvarsiz s 10i 0 inz(512)
Ddataname s 20 inz('DTAARA DTALIB ')
Dstrpos s 10i 0 inz(-1)
Dstrlen s 10i 0 inz(475)
C*

- 237 -

Tips n Facts
C eval QUSBPRV = 0
C call 'QWCRDTAA'
C parm QWCRDRTN
C parm rcvvarsiz
C parm dataname
C parm strpos
C parm strlen
C parm QUSEC
C* The variable QWCVALUE now contains the *DTAARA value
C eval *inlr = '1'
C return
Answer:
Since RPG has built in support for data areas, we have found little need to use the API with RPG. However,
PL/I has no support for data areas, so we wrote a function using the QWCRDTAA API to retrieve data
areas for use in our PL/I programs. Perhaps you can gleen some information from this code. One
important thing to remember about this API is that the data area's value is returned in the same field,
regardless of the type and Packed fields are not converted to readable characters. I hope this helps. Sorry
I don't have an RPG example for you
RTVDTAARA: PROCEDURE (DTAARA,LIB) RETURNS(CHAR(1024) VARYING);
DCL DTAARA CHAR(10);
DCL LIB CHAR(10);
Dcl DecVal Char(31) Varying;
Dcl (Int,I) Bin(15);
Dcl Char1 Char(1);
%INCLUDE QPLIINCL(TRIM);
Dcl 1 ErrRtn Static,
5 ErrStrLen Bin(31) Unaligned Init(272),
5 ErrRtnLen Bin(31) Unaligned,
5 ErrMsgID Char(7),
5 Filler Char(1),
5 ErrMsgDta Char(256);
Dcl QWCRDTAA Ext Entry
(*, /* Return variable */
Bin(31), /* Length of return variable */
Char(20), /* Qualified data area name */
Bin(31), /* Start position */
Bin(31), /* Length to retrieve */
*)) /* Error code structure */
Options(Assembler);
Dcl 1 Value_St,
5 AvailBytes Bin(31) Unaligned,
5 RtnBytes Bin(31) Unaligned,
5 Type Char(10),
5 RtnLib Char(10),
5 RtnLen Bin(31) Unaligned,
5 DecPos Bin(31) Unaligned,
5 Value Char(1024);
ON ERROR GOTO EOJ;
IF (LIB=' ') THEN LIB = '*LIBL';
Call QWCRDTAA (Value_St,1060,DTAARALIB,-1,1024,ErrRtn);
Select(Value_St.Type);
When ('*LGL','*CHAR')
Return(Substr(Value,1,RtnLen));
When ('*DEC')
Do;
DecVal = '';
Do i = 1 to RtnLen/2 + 1;
Char1 = substr(value,i,1);
/* moves the first four bits to an interger field */
int = substr(unspec(char1),1,4);
/* convert integer to character and append */
DecVal = DecVal||Trim(Char(int));
/* moves the first four bits to an interger field */
int = substr(unspec(char1),5,4);
Select(int);
When(0,1,2,3,4,5,6,7,8,9)

- 238 -

Tips n Facts
DecVal = DecVal|| Trim(Char(int));
When(13) /* x'D' found make value negative */
DecVal = '-'|| DecVal;
When(15); /* x'F' found value is positive, ignore it */
End;
End;
If DecPos > 0 Then
DecVal = Substr(DecVal,1,Length(DecVal)-DecPos) ||'.'||
Substr(DecVal,Length(DecVal)-DecPos+1);
Return(DecVal);
End;
End; /* Select */
EOJ: Return('NOT FOUND');
END RTVDTAARA;
RPG IV help using APIs
Question:
Some background: New to AS/400 and RPG Have spent a few months looking at RPG III now want to start
working in RPG IV, specifically with API calls and pointers. previous expirence with COBOL (on Honeywell
DPS 6), C and Pascal (on PCs) Now then, I've been looking at the following APIs: List Database File
Members (QUSLMBR) List Database Relations (QDBLDBR) both of which use a user space to return a list. I
would like to use pointers to access this user spaces, as opposed to the Retrieve User Space (QUSRTVUS)
API since pointer access is supposed to be faster. First off I was supprised that the source members in
QSYSINC/QRPGLESRC for these APIs did not have prototypes for the API calls. Is there a reason for this?
Second, it seems to me that the members in QSYSINC/QRPGLESRC can't really be included in your
module. By that I mean that for the most part you would not use a /COPY
QSYSINC/QRPGLESRC,mbrname in your source code. I base this on the fact that there are no prototypes
in those members, and the fact that to use the data structures with a pointer to a user space you have to
actually define the DS in your module with a BASED(ptrname) as shown in the example in "System API
Programming" appendix B topic 3.2. I can find no way to use the pointer while leaving the DS in the
include file. However, I did see this in the RPG manual(p 177):
*
* Define a basing pointer field and initialize to the address of the
* data structure My_Struct.
*
D My_Struct DS
D My_array 10 DIM(50)
D
D Ptr1 S 16* INZ(%ADDR(My_Struct))
But I don't think that this really has the same effect as
D My_Struct DS BASED(Ptr1)
D My_array 10 DIM(50)
D
D Ptr1 S 16*
Am I correct in this assumption? Help me out here folks, am I not understanding something here? Thanks
in advance,
Answer:
you are completely right. Accessing user spaces with pointers is *much* faster than QUSRTVUS. The best
thing about it, as you surely discovered, is the possibility of shifting a data area over the user space
instead of retrieving them with a call. I saw programs that did then some MOVEing with the data. That has
to be slower and it is. What we really miss with the /COPY is the possibility to change the source of the
included /COPY member as we were able to with good old Auto Report. But there was only support for
field names and attributes, and this can be done with ILE RPG, so i think that there's a little gap in
programmer's support. At least is that my state of knowledge, i couldn't find anything about this feature
on the handbook CD. Perhaps this is read by a IBMer/ress who solves the riddle or maybe this becomes a
requirement? Back to the topic: When you code a DS that is "based", you have to get your pointer field
filled. Before that, your DS is somewhere in nirvana. After that, you use a piece of storage that is
accessable for you; that is a user space or variable storage of your program. A DS without "based"
occupies the same place in the storage all the (run)time and cannot be shifted around. From V3R1 to
V3R6, you cannot calculate with pointers. You can have them set with QUSRPTRUS and %ADDR and that's
it. With V3R7, you can calculate with them like
EVAL Pointer = Pointer + %size(structure).
Before, you have to use some kind of workaround. You might be able to use this:
D Structure DS BASED(PtrStruct)
D Struct_F1 10
D Struct_F2 10
D Struct_Next 1

- 239 -

Tips n Facts
to move the structure, you use
EVAL PtrStruct = %ADDR(Struct_Next)
If you have to deal with offsets, what you have to when you use APIs, you might want to use an array.
D UserSpace DS BASED(PtrUsp)
D Offset 9B 0
D Array 1 32767 DIM(32767)
and use
EVAL PtrUsp = %ADDR(Array(Offset+1))
Has the disadvantage that you can only jump in 32K-steps in storage. But that can easily be solved by a
subroutine that does these jumps in a loop.
Answer:
Thanks for your reply. Have a couple of things... > From V3R1 to V3R6, you cannot calculate with
pointers. You can have them set > with QUSRPTRUS and %ADDR and that's it. With V3R7, you can
calculate with > them like > EVAL Pointer = Pointer + %size(structure). > > Before, you have to use
some kind of workaround. That explains this little code snippet in IBM's example correct? C* and then
incrementing LSTPTR to the Input Parameter Header C* C EVAL LSTPTR = %ADDR(ARR(QUSOIP + 1)) I
wondered why they needed that array defined. In v3r7 can you say add the offset to a pointer with the
following: C EVAL LSTPRT = LSTPRT + SizeOfEntry Thanks for you help.
Answer:
Charles, you're right that the members in that file are not as useful as they could be. They were written in
V3R1 before prototypes were supported in RPG IV. The problem with the data structures not being based
is a holdover from the RPG III versions which couldn't declare based data structures. The RPG IV headers
were supposed to be "the same" as the RPG III ones so customers could convert their programs to RPG IV
without difficulty. But I agree that it's time to do something about them (note that I'm not speaking
officially for IBM here). My guess is that we'd have to create a whole new source file to avoid disrupting
current users of QRPGLESRC. For now, you can copy (not /COPY) in the data structure subfields into your
own source, and unfortunately write the prototypes yourself. Sometimes it's helpful to look at the C
prototypes in QSYSINC/H (although sometimes they're just confusing e.g. "void *"). P.S. not sure if
anyone answered your question about pointer arithmetic, but yes, starting in V3R7 you can EVAL ptr = ptr
+ offset (zowie!). Thanks for reminding us about QSYSINC
Answer:
I thought you could already do this in V3R2. I'm sure we're using it for APIs that access a user space. Or
is it because we're actually advancing in an array....
Answer:
Yup, you must be using p = %addr(arr(offset+1)) to do pointer advancing. This is ok, although handling
an offset greater than 32766 leads to additional ugly coding usually involving a based multiple occurrence
DS with the char(1) array in it. Brrr. What you can't do with an array but you can with pointer arithmetic is
EVAL p = p - offset and even better, EVAL offset = ptr1 - ptr2.
Convert UPPERCASE to lowercase
Question:
Hi there! I need to convert names entered in the database in the format "JOHN SMITH" to "John Smith",
and I've tried to find an utility, a program, a RPG statement or anything to help me do that, but so far I
have not found anything! I have searched in "Deja News" and in the IBM Softcopy Library and the
TAATOOL library without any success. Is there such an utility, or do you have any suggestions how to build
such a program?
Answer:
look at the XLATE opcode. That's what it does. If you wanna see a program using it, go to my web site,
pick "RPG Sample Code" and choose the one about translating from UPPER to lower case.
http://www.spy.net/~booth Hell, never mind, here's the code. (set your reader to fixed font)
An RPG program to demonstrate a technique to translate
upper/lower case text
The RPG code:
*
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
* : PROGRAM PROPERTY OF:
:
* : DATE PROGRAMMER ACTION
:
* : 4/98 Booth Martin Create program
:
*
:............................................................:
* : TO TRANSLATE LOWER TO UPPER CASE.
:
*
:............................................................:

- 240 -

Tips n Facts
FXLATEFM CF E WORKSTN
I*
I 'ABCDEFGHIJKLMNOPQRST-C UP
I 'UVWXYZ '
I 'abcdefghijklmnopqrst-C LO
I 'uvwxyz,'
* .. .. .. .. .. .. .. .. ..
* raise lower case names to UPPER CASE.
C *INKC DOWEQ*OFF
C EXFMTFMT01
C LO:UP XLATEFIELD1 FIELD2
C END
C* .. .. .. .. .. .. .. .. ..
C SETON LR
Answer:
Not to mention the qdcxlate API if you want to externalize them apping instead of hard coding it. Or even
to create an ILE C/400 mod using a for-to loop with the "tolower" macro included. Can be linked into the
RPG app. Then we have of course the qtvtbnam function, which is unsupported and undocumented and
which I have not tried in a couple of years. Might have been removed..
Answer:
I wrote a routine like that in RPG/IV recently; what it does is: a) break name into seperate parts and store
leftadjusted in array b) xlate from position 2 upper to lower for each array element loaded c) cat together
each part with one blank in between
Answer:
Try something as follows;
DLo C Const('abcdefg...
DUp C Const('ABCDEF....
C Up:Lo Xlate Str Str
C Eval Len = %Len(Str)
C Eval Char = %SubSt(Str:1:1)
C Lo:Up Xlate Char Char
C Eval %SubSt(Str:1:1) = Char
C 2 Do Len n
C If %SubSt(Str:n-1:1) = ' '
C Eval Char = %SubSt(Str:n:1)
C Lo:Up Xlate Char Char
C Eval %SubSt(Str:n:1) = Char
C EndIf
I haven't tested this, but it should more or less do the job.
Answer:
Simply capitalizing the first letter of every word is not sophisticated enough. Since you are converting case
on an individual's name, you also run the risk of mangling it. For example: "JOHN MACDONALD" will
becom "John Macdonald" when it should be "John MacDonald" and O'Reilly becomes O'reilly. I work for a
mai-order company, and when an advertising piece mis-prints a prospect's name, that prospect is way
more likely to toss the offer in the trash. From personal experience, I know that my name is one that is
constantly mangled on junk mail. As a matter of fact I use that fact to screen my mail... if they can't get
my name right, then I don't read their stuff. Restoring mixed case to a name is a complex topic, and you
must weigh the cost of a sophisticated algorithm to avoid mangling names. Our experience as a company
has shown that customers don't mind all CAPS in their printed name, they do mind mis-spellings and
goofy capitalization.
Answer:
If I recollect correctly, you take the date in question, make sure it is a date data type (D), subtract the
date of any known Sunday in the past expressing the result in days (SUBDUR opcode), divide by 7 and the
remainder is the day of the week. Jon Paris uses this, or something like this, in his Common
presentations.
Answer:
Mike, just jump in the water and copy the function DayofWeek in the ILE RPG manual to a SRC-PF. You
then just code EVAL Weekday = DayofWeek(Datefield)
Get day of the week in RPG
Question:
Hi Is there an easy way to get the day of the week in ILERPG, or do I need to use the CEEDAYS/CEEDYWK
APIs. If so an example would be appreciated. Thanks
Answer:
Well as a last resort, if you are calling it from a controlling CL program, use RTVSYSVAL to just pass the
system value QDAYOFWEEK to your program. It's 4byte char. values *MON *TUE *WED....etc.
Answer:

- 241 -

Tips n Facts
This piece of code tells you the day of the week today is that I made for another purpose, but you can
modify it easily enough.
*********************************************************************
* Compile-time array: AL = days to first of a month, not leap year:
* Compile-time array: AR = days to first of a month, leap year:
* Compile-time array: ARD = DAYS of the week(The field we want).
DAL S 3S 0 DIM(12) PERRCD(12) CTDATA
DAR S 3S 0 DIM(12) PERRCD(12) CTDATA
DARD S 9A DIM(7) PERRCD(7) CTDATA
* .................................................................
* Step 1: find the # of days through the end of last year:
C *YEAR SUB 1 LASTY 4 0
C LASTY MULT 365.25 DAYS 7 0
* .............
* Step 2: add the days so far this year:
* Is it Leap year? (TESTLY if = 0, then its leap year.)
C *YEAR MULT 25 TESTLY 2 0
* Days so far this year, to the first of this month:
C Z-ADD UMONTH I 2 0
C TESTLY IFNE *ZEROS
C ADD AR(I) DAYS
C ELSE
C ADD AL(I) DAYS
C END
* Then, add in the days so far this month:
C ADD UDAY DAYS
* .............
* Step 3: Now we have the total number of days since 01/01/0001.
* By removing all full weeks since 01/01/0001 we will have
* established today's "offset" from 01/01/0001. That
* "offset" is the remainder, and is useful as an array index.
C DAYS DIV 7 DAYS
C MVR I
* .............
* Step 4: Logically the remainder can only be 0 - 6.
* But 0 is a lousy index so by adding 1 we assure
* that the index will be 1-7, and therefore useful.
C ADD 1 I
* .............
* Step 5: Now, with the index, look up the day of the week.
C MOVE ARD(I) TODAY 9
* A frequently asked question is "Hey, how did you know what day
* to start with in the ARD array?" Simple. The first time I
* did this I started it with Sunday. It was off by one day so I
* started the array with Monday instead; then I was off by two
* days. But Saturday worked fine.
* .................................................................
*
** FebMarAprMayJunJulAugSepOctNovDec (AR days, not leap year)
000031059090120151181212243273304334
** (AL days, leap year.
000031060091121152182213244274305335
** DAYS of the week: (becomes "TODAY") (ARD Day-of-week)
Saturday Sunday Monday Tuesday WednesdayThursday Friday
>>Is there an easy way to get the day of the week in ILERPG, or do I need to >>use the
CEEDAYS/CEEDYWK APIs. If so an example would be appreciated. >> >>Thanks >>Mike -Answer:
Mike, just jump in the water and copy the function DayofWeek in the ILE RPG manual to a SRC-PF. You
then just code EVAL Weekday = DayofWeek(Datefield)
Answer:
Hi Rocky. Here is the day of week module which I lifted from Bryan Meyer's book RPG IV Jump Start.
H NoMain
H DatFmt( *ISO )
D GetDow PR 1P 0
D InpDate D Value
P GetDow B Export

- 242 -

Tips n Facts
D PI 1P 0
D InpDate D Value
D DayOfWk S 11P 0
C InpDate SubDur D'1998-08-01' DayOfWk:*D
C Div 7 DayOfWk
C MvR DayOfWk
C If DayOfWk > 0
C Return DayOfWk
C Else
C Return DayOfWk + 7
C EndIf
P GetDow E
This procedure returns 1=Sunday, 2=Monday, etc. Here is a quick module I wrote to test this module.
D GetDow PR 1P 0
D InpDate D Value
D PrmDate S D DatFmt( *MDY )
D Dow S 1P 0
C *Entry Plist
C Parm PrmDate
C Eval Dow = GetDow( PrmDate )
C Dow Dsply
C Eval *INLR = *On
Compile these two modules with PDM option 15. Then bind them together with the CrtPgm command.
From the command line you invoke by call the program... Call WhatEverYouNamedTheProgram
'DateInMM/DD/YY-Format' Mike Cravitz NEWS/400 Technical Editor
Answer:
Here's some water to jump in: I swear that i copied this originally out of a RPG manual, but i cannot
remember which version/release. I wasn't able to find it in V4R2, there is another example for functions,
CvtToHex, and i have no access to the other manuals at this time.
H DEBUG
*
D DayOfWeek PR 1P 0
D DateIn D
*
D Week_Date S D INZ
D WeekDay S 1P 0
*
D Date S 6S 0 INZ(120997)
*
C *DMY MOVE Date Week_Date
C EVAL WeekDay = DayOfWeek(Week_Date)
* 1=MON,2=TUE,3=WED,4=THU,5=FRI,6=SAT,7=SUN
C DUMP
C MOVE *ON *INLR
P DayOfWeek B
D PI 1P 0
D DateIn D
*
D Weeks S 7 0
D DayNbr S 1P 0
D AnySunday S D INZ(d'1997-04-27')
*
C DateIn SUBDUR AnySunday Weeks:*D
C DIV 7 Weeks
C MVR DayNbr
C IF DayNbr <1 C EVAL DayNbr="DayNbr" + 7 C ENDIF C RETURN DayNbr P DayOfWeek E
Hope this helps.
Determining Even/Odd Values in queries
Question:
I'm trying to create an open query file that sorts on a location field in my item file. Here's the problem, my
location is a six digit number: aisle (XX) - rack (XX) - shelf (X) - position (X). I need to sort the file such
that all the even racks within an aisle are together as are all of the odd racks within that aisle. IE. I need
01-01-1-1 01-03-1-1 01-05-1-1 ... 01-02-1-1 01-04-1-1 01-06-1-1 .... Now here is the OPNQRYF I'm
working with.
OPNQRYF FILE((IORINVMS)) FORMAT(IORINVCT)
KEYFLD((IDIVSN) (IWHALS) (IWHREO) (IWHRAK) (IWHSHF) (IWHPOS)

- 243 -

Tips n Facts
(IITNIM))
MAPFLD((IWHALS '%SST(IWHLOC 1 2)')
(IWHRAK '%SST(IWHLOC 3 2)')
(IWHSHF '%SST(IWHLOC 5 1)')
(IWHPOS '%SST(IWHLOC 6 1)')
(IWHREO '*MAPFLD/IWHRAK - (2 * ( *MAPFLD/IWHRAK / 2))'
what I'm trying to do here is create a field (IWHREO) that is 1 when the rack field (IWHRAK) is odd and 0
when it is even. For this to work I need IWHRAK / 2 to round down so that for example rack 5 / 2 = 2.5
needs to be 2. Lastly, IWHLOC is the six character location field that is in the file. IWHASL, IWHRAK, are
defined in the format IORINVCT as zoned 2 digit no decimal. IWHSHF, IWHPOS, IWHREO are defined as
zoned 1 digit no decimal. I'm thinking that I may have to have some sort of work field with a couple of
decimal places, or perhaps I need to subtract .25 after the division so that the results will round down
when the rack is odd ( 5 / 2 -.25 = 2.25) but up when the rack is even ( 6 / 2 - .25 = 2.75). Any
thoughts??? Or can someone tell me or point me to a manual that explains the precision being used here?
Answer:
All you need to do is have the *MAPFLD become the modulus, or remainder, after diving by two. In
OPNQRYF, you can get the remainder by using // instead of / for divide: (IWHREO *MAPFLD/IWHRAK // 2)
Note that this will cause even numbers to return 0, and odd numbers to return 1 as you requested.
However this sorts the even numbers ahead of the odd numbers, and your message also made it sound
like you wanted racks 1,3,5,... prior to 2,4,6,... If this is the case, you can reverse the order by something
like: (IWHREO %ABSVAL((*MAPFLD/IWHRAK // 2) - 1)) This is untested, but should get the remainder (0
or 1), subtract 1 (giving -1 or 0), then take the absolute value (giving 1 or 0). I think this will give you
odd racks, then even racks.
Answer:
Thank you, how in the *!%$ did you know about this operator?? I did not see it in any of the manuals that
I looked at. Thanks again, this worked perfectly.
Answer:
Ok, this seems to work but I'm open to suggestions on how to improve it.
OPNQRYF FILE((IORINVMS)) FORMAT(IORINVCT) +
KEYFLD((IDIVSN) (IWHALS) (IWHREO) (IWHRAK) +
(IWHSHF) (IWHPOS) (IITNIM)) +
MAPFLD((IWHALS '%SST(IWHLOC 1 2)') +
(IWHRAK '%SST(IWHLOC 3 2)') +
(IWHSHF '%SST(IWHLOC 5 1)') +
(IWHPOS '%SST(IWHLOC 6 1)') +
(XRAKD2 '*MAPFLD/IWHRAK / 2' *ZONED 4 2) +
(XRKD2R '*MAPFLD/XRAKD2' *ZONED 2 0) +
(IWHREO '*MAPFLD/IWHRAK - +
(2 * *MAPFLD/XRKD2R)') + )
How do you change the signon screen?
Question:
Can anyone tell me how to edit / change the signon screen on the as400. All I need to do is to add a
sentence to the bottom, company warnings about mis-use etc. Cheers
Answer:
go to http://as400bks.rochester.ibm.com/bookmgr/home.htm and look up the the book OS/400 Work
management there you wil find some information on changing QDSIGNON. The source of QDSIGNON is
shipped in QGPL/QDDSSRC. I copied the source and added the following lines:
A MSG001 79 O 11 2MSGID(S000001 SIGNON)
A MSG002 79 O 12 2MSGID(S000002 SIGNON)
A MSG003 79 O 13 2MSGID(S000003 SIGNON)
A MSG004 79 O 14 2MSGID(S000004 SIGNON)
A MSG005 79 O 15 2MSGID(S000005 SIGNON)
A MSG006 79 O 16 2MSGID(S000006 SIGNON)
A MSG007 79 O 17 2MSGID(S000007 SIGNON)
A MSG008 79 O 18 2MSGID(S000008 SIGNON)
create a MSGF SIGNON and add the MSGID's with your text. When creating the sign-on display file with
the Create Display File (CRTDSPF) command, secify 256 on the MAXDEV parameter. I created QDSIGNON
in QGPL, and changed the SBSD QINTER to look at QGPL/QDSIGNON. I would recommmend not to change
the controling subsystem. HTH
Answer:
The source file member is QDSIGNON in QGPL/QDDSSRC. Do not change the order of input capable fields
or remove them. If you only want users to be able to enter User ID and Password, you can protect and
hide the other fields in the changed DDS. Compile the source into one of your libraries and then change
the sub system description for the subsystem such as QINTER by using WRKSBSD. I would advise that
you do not change your controlling subsystem just in case! You can add many lines of output text and you
can move the positions of input capable fields providing you do not alter their sequence in the DDS.

- 244 -

Tips n Facts
Answer:
I just did this for our AS/400 and added a "security" message and the company logo on it. What you need
to do is get the QDSIGNON source and edit it to show/say what you want. then for any subsystem you
want this to show up on (don't use QCTL so you can at least get into your console) you will have to do a
ENDSBS on the subsystem. Then compile the DDS source into a library other than QSYS I put mine in
QGPL. Then STRSBS on the subsystems you want the QDSIGNON used in. Then do a CHGSBSD
SBSD(QINTER) SGNDSPF(QGPL/QDSIGNON). (Change SGNDSPF to whatever Subsystem(s) you want to
use the new signon screen. If you have any problems let me know.
Answer:
usually, you can find member QDSIGNON in file QDDSSRC in library QGPL. Copy this member to new one
and edit by SEU or SDA. After creating new object you have to change subsystem description (usually
QINTER) - CHGSBSD - keyword SGNDSPF.
Help: AS/400 subfiles
Question:
Writing file maintenance program for open purchase order file. Typically provide a view screen in addchange-delete maintenance programs. However this program involves header and detail physical files with
a logical file required for the detail record handling. Also the view portion will look at all detail records of a
PO at the same time. Can I use the same subfile definition for the add and change transaction? Typically
the PO generation program would add POs, but I want to include it here also. Can you also reccommend a
good book with examples for subfile processing.
Answer:
I think I know what you're asking for. We have many screens like this, including PO entery and Order
Entry. Let me see if I have this straight.. here's an example of what I think you want. Purchase Order
Entry
Vender: _________ PO#:____________
any other header data
(leave this area blank to update selected detail lines one at a time)
Select options,
press Enter. 2=Change 4=Delete
Opt PO Line Purchase# Qty Cost Ext. Cost _ 1
Item1 1 2.45 2.45 _ 2
Item2 3 4.23 12.69 _ 3
Item3 2 1.00 2.00 .... ... ...
F3=Exit F6=Add F12=Cancel
message line -----------------------------------------------So, this will not only display what is on the PO, but will also allow update of the PO lines. Use the option
field to select lines to update, and display the PO line data in the area noted above (This is because there
will most likely be more info that can be updated on the subfile line itself, also makes it a little easier).
When enter is hit, update the PO detail file. When all lines that were selected have been updated, reload
the subfile do display new changes in the subfile. I made this display with IBM standards to make it easier
to understand. F6 will display blank data in the detail line screen area with an incremented detail line
number. Simple enuff.... Did this help at all?
Answer:
yes, i would think so. When ready, chain to the file with an indicator in 54-55. If the indicator is on, write
the record. if the indicator is off, update it.
Answer:
Get the book, "Subfile Technique for RPG/400 PRogrammers 2nd Edition" By Jonathan Yergin and Wayne
Madden. From DUKE Press (www.news400.com). It has source examples of order entry subfiles. It's a
good book, I used it to learn more of the other subfile techniques.
Answer:
Michael Catalani's "Subfiles for RPG Programmers" from Midrange Computing is decent. He takes you from
basic to complex subfile design in a nice, progressive manner. Lots of detailed RPG III code and display file
examples. A glaring omission is a lack of information about coding subfiles to allow option selection on a
subfile line item, except by using cursor position. He promises he will cover doing this by option number
'later', but never does unless I've missed something. And sometimes new keywords and concepts appear
in the examples without any explanation in the text. But overall, it is a useful book. Also, Pence &
Hawkins' "Power RPG III" and "IV" books (also MC) have brief, but informative sections on subfiles, again
with examples. They do explain one technique for performing option selection on a subfile by option
number.
Sharing DB files between two AS/400s
Question:
Hello! I've got such a problem here. We have 2 AS/400. One is V3R7, another V4R1. The second has SQL
support (I mean the one that I get when I type STRSQL), another does not. Is it possible to access PFs
that reside on the first AS from the second one. The problem is that all sort of SELECT type commands
can be more or less easily implemented by query, but not the REPLACE. Any advice will be highly
appreciated.

- 245 -

Tips n Facts
Answer:
DDM is the answer... If you use a lot of interactive inquiry, it can be slow but with casual use... works
fine..
Answer:
DDM is one way, But a better solution for those who use SQL or Query management is to use the remote
database support... If you have APPC communications configured between the two machines (ie. if you
can use STRPASTHR either system to the other), then you have all you need to execute remote database
queries. (And, no, your remote V3R7 does not need the SQL licensed program installed, SQL runtime
support is included in the base OS) Use the WRKRDBDIRE command to define the local database and the
remote database locations on both your systems. You will need to define an entry for your local system
and one for each remote database your system will connect to. You then use the CONNECT TO in your SQL
or Query Management queries to access the remote system. If you move to V4R2, you will want to apply
the ptf SF48822 to forego any problems with update/delete operations.
Answer:
The nice thing about AS/400 is that SQL is always on the system, as it is part of the database. The only
thing missing on your V3R7 is the user interface ! A workaround for this is to create a SRC-PF with a
length of 79, code the SQL statement in it and use the CRTQMQRY/STRQMQRY commands to execute it. I
have written a CL-program and command for this to do some checking on the source member and things
like that, created an option for it in PDM and now it looks like I have SQL (great for customers who don't).
Answer:
You can use the SQL CONNECT command to connect to the other AS/400 and then run standard SELECT,
etc commands. Although the other AS/400 does not have SQL it does have the SQL engine (as do all
AS/400s for file transfer, query, OPNQRYF, etc). The select command will be transmitted to the other
AS/400 and executed there, the results will be transmitted back to the first AS/400.
PCL ESC codes in CL/RPG
Question:
Hi, All I've got a situation where I'd need to embed some PCL printer codes in either CL or RPG code to be
sent to the printer. Pardon that I'm no AS400 person, and can't give much details, but would appreciate
some help, especially how to enter the ESC character on the terminal (or however else it's represented
as). Any help appreciated. TIA.
Answer:
if you're creating a SCS spooled file, what i assume, you can use the SCS command ASCII Transparent,
which is hex 03. Then you have to code the length of the ASCII transparent bytes in one byte (including
the length byte), and then code the ASCII representation of the escape sequence you want to send. You
might however face some problems. E.g. when you have some interface between your AS/400 and the
printer, some interfaces go berserk when they do receive a x'03'. Cause: partial implementation of the
SCS command set.
Answer:
You
can
find
a
description
of
how
to
do
it
on
my
site
at:
http://www.angelfire.com/oh/nickroux/tipprtpcl.html and download most of the common PCL codes in RPG
and RPGLE format from http://www.angelfire.com/oh/nickroux/download.html Including the constants
from the download the following RPGLE will initialize the printer, put it in landscape mode and select A4
from the upper tray.
0100.00 O REPORT E 01 HEAD
0110.00 O @INIT 10
0120.00 O @LAND +0000
0130.00 O @A4 +0000
0140.00 O @TUP +0000
The following will send $1B $45 ascii codes to the printer.
0100.00 O REPORT E 01 HEAD
0110.00 O +000 X'03021B45'
DSPDTAARA to an outfile - possible?
Question:
Hi, I would like to make a dspdtaara for every dtaara named dsp* to an outfile. Is that possible?
(DSPDTAARA doesnt do it) (My problem is that we have a dtaara for every Session (Terminal or PC) and
in that dtaaras is saved, which printer is to be used from the Session - and I would like to check this Data)
Answer:
Hi, I would like to make a dspdtaara for every dtaara named dsp* to an outfile. Is that possible?
(DSPDTAARA doesnt do it) (My problem is that we have a dtaara for every Session (Terminal or PC) and
in that dtaaras is saved, which printer is to be used from the Session - and I would like to check this Data)
Answer:
With some quick and dirty programming this can't be a problem. I would suggest to use following steps;
1. DSPOBJD the necessary *DTAARA to an outfile
2. Write a CL that reads this outfile and does a RTVDTAARA for each of them
3. Call an RPG program for each of them with name and contents to write to a file. This can be done
in 10 minutes.

- 246 -

Tips n Facts
STRQMQRY parm problem
Question:
I have a problem with the parameter SETVAR of the command STRQMQRY. The command looks like this
STRQMQRY QMQRY... SETVAR(VAR 'XXX') ... The comparison value is character. Everytime I start the
command I get the error message that the comparision operator '=' isn't correct.
Answer:
Suppose you have a query management query that looks like the following. Select * From Customer
Where CuName = &var There are two ways you can be tripped up here. First, query manager is case
sensitive with respect to variable names. So if you invoke this query as follows... RunQmQry whatever
SetVar( var 'A&P Grocery' ) It will not run 2 reasons. 1) Since the variable was defined as lower case in the
query and since the AS/400 command line monitor converts all names to upper case, the variable var will
be converted to VAR which doesn't match the name of any variable in the query. The solution to this
problem would be the following query. RunQmQry whatever SetVar( 'var' 'A&P Grocery' ) But we still have
one more problem to solve. 2) The above query will attempt to run the following SQL command Select *
From Customer Where CuName = A&P Grocery The problem here is there are no apostrophes surrounding
the string A&P Grocery as SQL syntax demands. In order to solve this problem, you must use two
apostrophes wherever you want the command line monitor to pass a single apostrophe to the query. So
the final solution to the problem would look like this. RunQmQry whatever SetVar( 'var' '''A&P Grocery''' )
Notice it takes 3 opening and closing apostrophes to solve the problem. The first apostrophe is simply the
one the command line monitor needs in order to pass embedded special characters. The second and third
apostrophe tell the command line monitor to pass an apostrophe. Similarly for the closing 3 apostrophes.
Mike Cravitz NEWS/400 Technical Editor
Named indicators
Question:
Hello all, Has anyone used the named indicators feature in V4R2 ? Specifically I'm trying to find out how to
use them to name a general indicator. Say 50, suppose I have it conditioning an Ouput spec. I'd like to be
able to say for example EVAL PrtSeq# = Yes instead of EVAL *IN50 = *ON. I've used them with display
files indicator area and they are great !! Using named indicators to signify a keying error for example,
EVAL CusNumErr = Yes is WAY better then EVAL *IN50 = *ON. Any help is greatly appreciated TIA
Answer:
Oscar, Gary Guthrie outlined a technique for this about a year ago (maybe more) in the magazine. Here is
how to accommplish what you want.
D IndPtr S * Inz( %Addr( *IN ) )
D IndAra S 1 Dim( 99 ) Based( IndPtr )
D PrtSeq# 50 50
Answer:
Thanks, I went to news400.com and looked up the named indicators, It told me it was Feb 97 so I went
and got the magazine from our library. That's exactly what I wanted.
Mapping Fields To Arrays in ILE RPG
Question:
I'm stumped. I'm trying to map a 10 numeric variables (7,6) into an array for clearer coding, but the
exact syntax is defeating me. I can do it with alpha vars via the overlay keyword within a D spec, but not
numeric. Help!
Answer:
Assumming none of the 10 variables are already defined in a data structure....
D MyDs DS
D Var01 7P 6
D Var02 7P 6
D Var03 7P 6
D Var04 7P 6
D Var05 7P 6
D Var06 7P 6
D Var07 7P 6
D Var08 7P 6
D Var09 7P 6
D Var10 7P 6
D MyArr 7P 6 Overlay(Var01)
D Dim( 10 )
Answer:
Try this. Its a little bit strange but it works.
D pbtw s based(pbtwpntr) dim(10)
D pbtwpntr s * inz(%addr(ipbtw00))
The field pbtw is your array (10 elements), based on a pointerfield. The field pbtwpntr is a pointer to the
FIRST field of a range of 10 fields (ipbtw00, ipbtw01......ipbtw09).
Topic: Print file overflow in ILE RPG
Question:

- 247 -

Tips n Facts
Can anyone tell me how to handle overflow with an externally described print file ( created with RLU )? I
was going to add the OFLIND(*INOF) to the keyword section of the file specs, but the manual says thats
only for program described printer files and SEU won't let me do it. HELP!
Answer:
here we typically place an error indicator on the write statements. when overflow occurs, the error is
trapped, and you can perform your overflow logic.
Answer:
I usually check overflow by getting the information from a printer informational DS. As it contains the
current line, and overflow line, you can make the necessary calculations in your program to see if the
format you're planning to write still fits on the page ... and if not, you can write a new header.
Answer:
Chris, OA-OG, and OV are for program described print only. Use a numeric indicator. So you may code
your keyword...OflInd( *IN60 ). Also, this indicator comes on when there's overflow, but you must
programatically turn it off. Your code will look something like this.
If *IN60 = *On
Write Hdg
Eval IN60 = *Off
EndIf
Mike Cravitz NEWS/400 Technical Editor
First time Data queue application in RPG
Question:
Can someone suggest a quick way to get up to speed on using data queues in an RPG program. Any
manual references or code snippets would be much appreciated.
Answer:
DDAT C 'hello world'
C PSNDDQ PLIST
C PARM DataQ 10
C PARM DataQLib 10
C PARM DataLength 5 0
C PARM Data 50
C
C PRCVDQ PLIST
C PARM DataQ 10
C PARM DataQLib 10
C PARM DataLength 5 0
C PARM Data 50
C PARM Wait 5 0
C
......
*
* Place an entry in a dataq
*
C MOVEL 'MyDataQ' DataQ
C MOVEL 'MyLib' DataQLib
C Z-ADD 11 DataLength
C MOVEL DAT Data
C CALL 'QSNDDTAQ' PSNDDQ
.......
*
* Read from dataq until the data read is 'QUIT'
*
C dqdata doueq 'QUIT'
C movel 'MyDataQ' DataQ
C movel 'AGCTI' DataQLib
C move *BLANKS Data
C z-add *ZERO DataLength
C z-add -1 Wait //Wait forever
C call 'QRCVDTAQ' PRCVDQ
* Add code to process the data received
C enddo
How to send parameters to a query
Question:
Can you tell me how to send parameters, like date or any key for selection, to a query on AS/400 V4R1 ?
Answer:
You need to define a query management query
Answer:

- 248 -

Tips n Facts
Instead of using Query/400, use Query Manager (access via "STRQM"). Queries created this way (you can
use standard SQL syntax) can be saved and called with parameters easily.
Answer:
Use variables with a ':' as prefix to variable name. When prompted for a filename, just type DUMMY. Run
query with StrQmQry and ALWQRYDFN(*YES).
What's the fastest way to do a simple RPG lookup?
Question:
I sure you have all been here. I want to make sure that the two character Unit of Measure code that my
user has entered is valid. At the same time, for each code I want to have a corresponding description and
equivalent X12 code. My first thought would be to have a 'Unit of Measure Code Master File' with the
following fields. UUNMSR, UNDESC, UUOMCD With records like EA Each EA CS Case CA BX Box CA SP
Shelf Pack PK But my concern is the performance hit I would take chaining to this file so often, for
example when creating a PO to be sent via X12 EDI I would have to chain to it for every detail record. I
definately do not want to hard code this information into the programs that I want to use it on. I suppose
I could load a multiple occurance data structure with this info. But how do I perform the lookup? Are there
other, better?, ways to do this?
Answer:
Instead of loading the file into a multiple occurrence data structure, use an array. Then you could use a
lookup function on the array to find the particular element you need.
Answer:
Thanks for the reply. Maybe I am misunderstanding something here, but I thought that an array was
made up of single elements. ie. an array of 10 two character codes. This would be fine for validation, but
would not allow me to store the other two fields. Am I missing something here?
Answer:
yes, you missed the possibility to have other arrays containing the infos you need! For instance, you have
the array with your unit of measure and find your user's input e.g. in element 2. Then, you can access
another array with your descriptions with index 2, and so on. You can load the arrays at program
initialization time from a file to avoid hardcoding (manually or by means of a prerun-time array [you'll find
this in the RPG reference]), or, which is slightly more complicated, but also a common method, first lookup
your array, and if you do not find it there, chain a file. If you find it there, you can put it into the array(s).
But i do not think that there is much performance won. The AS/400 doesn't really access the hard disks
every time to get records, OS/400 will move the stuff to the main storage, but you do not have to care
about that. A more difficult method, but performing very good, is the use of an user index, but that's not
quite a point to start for a beginner. Hope this helps!
Answer:
Thanks for the reply, I hadn't thought of breaking the data up like that...I was thinking about working with
the entire record as a whole from the file.
Answer:
Yes. Alternate arrays are supported. This lets you define 2 arrays that are related. The first array would be
your unit of measure. The second array would be a composite field of the description and X12 unit of
measure. Use a data structure to split the second array into its subfields. Normally I would just load the
arrays in ordered sequence at initialization time and do a lookup for each record when the new lookup is
differant from the prior lookup. This approach saves 1 disk I/O request per output record and minimizes
the number of times lookup is actually executed. I/O is much slower than lookup. Lookup is slower than
reusing the prior values.
Answer:
You don't need to us MO Arrays. You can define arrays in data structures, and even sort with them. For
example:
D DS
D UOMArray 34 DIM(100)
D UOMKey 2 OVERLAY(UOMArray)
D UOMDesc 30 OVERLAY(UOMArray:3)
D UOMCode 2 OVERLAY(UOMArray:33)
Now, you load the fields by saying UOMKey(index) = xxx, UOMDesc(index) = xxx, and UOMCode(index) =
xxx This way you have all your fields together. If you wish to sort the arrays and keep the indecies intact,
simply sort by the subfield of your choice. For example
* sort by Description
C SORTA UOMDesc
* sort by Code
C SORTA UOMCode
Alternating arrays, who needs em! This is the best array technique I have learned in years.
Answer:
Wow, looks great!
Answer:
Database I/O is what the AS/400 is designed for. I can't imagine that a simple read to a code table can
impact performance in a perceptible manner. Certainly, the coding simplicity of a simple chain is much

- 249 -

Tips n Facts
more desirable than the complexity of other approaches (arrays or data-structures). In many cases
simplicity of code is much more desirable than the marginal improvement in response time a cacheing
algorithm would give. However, one thing you should do in whatever design you choose: don't do the
lookup if the last lookup was for the same code. this technique alone can save a good percentage of
necessary I/O.
Answer:
Thanks for the reply. You make some very valid points, especially about not doing the lookup if the last
one is for the same code. Since 95% of my items are coded with the same code this should eliminate any
performance problems. I had already thought of this after my original post, but in the back of my mind I
thought I remembered reading about something that was ideal to this scenario.
Answer:
For a table of this size/complexity (not!), maybe you could just use SETOBJACC to load it into a small
memory pool. Then, ignore thoughts of performance degradation. Other than that, if loading into an array
doesn't suit your taste, I wouldn't even think twice about the performance aspect unless you're already
hitting a performance curve -- in which case you've got other bigger problems.
Answer:
If you only need to see if the entry made exists in your file you can do a setll using an indicator in the =
position. This technique uses less overhead because no data is brought into the buffer at any time. Also if
you are using a chain and the key value does not change from the previous chain the values still remain in
the buffer. This is also less overhead than if the value changes and a read( disk)/write( buffer) actually
occurs. It may be the same overhead or less than checking for a changed value in your program before
chaining.
Answer:
Just to test the performance hit, I wrote a small program to read the entire article file (88000 records)
sequentially. On our model 620, this took 1.5 CPU secs. After adding a chain to our Unit of Measure file
the program took 7.1 CPU secs. This shows that a chain takes a significant amount of time (relatively). If
you have a large AS/400 and/or a small article file, you probably won't bother if the job takes 5-10 secs.
longer to execute. If you do, the methods suggested by others (array lookup or chain with array caching),
will work fine. If you're using ILE you may write a function that checks the UOM code using SETLL (which
requires less CPU than a chain), and functions to retrieve each of the corresponding UOM attributes. These
routines may well use arrays, caching, or simply hardcoded data (since they're only specified in one
source member, you can move them to a file later if you want to).
Answer:
You make a wrong assumption here. If we talk I/O operations, CPU time is not a concern. The question is
runtime. For each sync I/O, the cpu timeslice is ended and the job (after completing the I/o) will have to
compete for a new timeslice again.
Answer:
Have you performed a Chi-Squared analysis and other statistical methods to test the randomness of the
numbers generated by your function? Besides which the calculations would be tediously slow unless you
use the date API's and if you're going to use the API's why not just use the IBM supplied one for random
numbers?
Randomize function for the AS/400
Question:
I am looking for any randomize function in AS/400, has anyone done that before? Please advice.
Answer:
5.7.1 Basic Random Number Generation (CEERAN0) API The Basic Random Number Generation
(CEERAN0) API generates a sequence of uniform pseudorandom numbers between 0 and 1 using the
multiplicative congruential method with a user-specified seed. as described in System API Reference
OS/400 Integrated Language Environment (ILE) CEE APIs Document Number SC41-4861-01
Answer:
Just hook up your AS/400 to an NT server, ping it regularly, and record the time it crashes, that should
give you a nice random number.
Answer:
Shouldn't the result of the random function be between 0 and 1 ? You'll only get overflows by your
method.
Being
serious
again,
take
a
look
at
http://AS400BKS.rochester.ibm.com:80/cgibin/bookmgr/bookmgr.cmd/BOOKS/QB3AM M01/5.7.1 for information on the CEERAN0 API.
Answer:
An Idea but i don't how far it is going to help you out. You can use the API which martin has specified. If
you feel like how to go about in creating a random number by your own here is method. You can generate
a random number given a range . I have written a program to do so. The logic is like this. Input = range is
200 to 230 Solution: 1. Get the difference i.e.230-200 = 30 now get a random number between 0 to 30 2.
Calculate how much seconds we are from a fixed date take a date which is around 1980. 3. Now add the
seconds by any constant and multiply by another constant. This is to boost the random number for a small
change in seconds. 4. Convert both the seconds and the difference to binary and then do an AND
operation. 5. Convert the result binary to decimal. It will be in the range you desire. 6. Add the result to
base i.e. 200. You will get the random number. It may look hectic, but very iteresting to do. This i did

- 250 -

Tips n Facts
when i was new to AS/400 as well as Software field so did the binary conversion and AND by using Array
by division and addition. This really works good and we are using it to select a random part number for
inspection. Or I think so you can call up a c program in AS/400 and get the random number which looks
easier . I have not tried till now. Sorry if i have confused you through my poor english.

http://publib.boulder.ibm.com/html/as400/infocenter.html
Q.1) I'd like to save spool files, and then restore them as spool files?
A.1)

CPYSPLF FILE (&SPLFNAME) TOFILE (QTEMP/Temp) +


JOB (&SPLFJNBR1/&SPLFUSER/&SPLFJOB) +
SPLNBR (&SPLFNBR) CTLCHAR (*FCFC) mbropt (*replace)
You

will

be

able

to

save

the

file

this will create a spool file QSYSPRT from saved data


OVRPRTF FILE (QSYSPRT) CTLCHAR (*FCFC) OUTQ (&OUTQ) +
FORMTYPE (COPYPACK) HOLD (*NO) SAVE (*NO) +
USRDTA (DUPLICATE) SPLFNAME (&SPLFNAME)
CPYF

FROMFILE (QTEMP/Temp) TOFILE (QSYSPRT)

Q.2) How to change PF field color, it default showing white?


A.2) U cannot set COLOR attribute to a PF or LF.
(* You can view SQL query result in different colors using hexadecimal values)

Q.3) I have an interesting question for all of u,


I have a requirement in which i need to create 3 logical on one Physical, the key fields in logical will be like
that:
1st logical--->K1, K2, K3
IInd Logical-->K1, K3
IIIrd Logical-->K2, K3
I need to create all the 3 logical and going to use that in my program,
THE QUESTION IS WHICH LOGICAL I WILL CREATE FIRST AND WHY??????
Plz explain in Detail.
A.3) Order: 1st 2nd then Third.
Generating in this sequence will result in creation of ONLY ONE "Active Index". Whereas if you generate in
the reverse order three active indices will be generated.
OS/400 implements logical files by automatically creating "Active Index". There is a seperate active index
for each set of key and static selection maintenance.
It is always good to minimize the number of active indices because an active index causes
extra system overhead.
Compiling in the order mentioned above will lead to sharing of one active index by all the three logical
files. Obviously the number of active indices created depends upon the sequence in which the logical are
created.
Q.4) How to check who is allowed to do FTP in an AS400 machine? Where is the setting?
A.4) you can use Client Access Operations Navigator.
choose: (machine) ----- Users and groups - All users choose profile------ right click and choose------Properties---------- Capabilities button------------- Applications tab------------ Host Applications (from
drop-down menu)------------ Tcp/ip utilities for iSeries FTP--------- FTP Server and here is: Logon Server
or Specific Operations.
Q.5) I am writing a RPG progarm .In query ,where i need to write WHERE
condition as follows: WHERE date between 20050301(first day of curr.month) and 200050430 (lastday fo
next month). Can anyone plz tell me how to find last date of current month? and also last date of next
month?
A.5) To find the last date of the current month:

- 251 -

Tips n Facts
(1)Get the first day of the current month
Extract YY and MM from CurDate, then CurFstD=YY-MM-01
(2)Get the first day of the next month :
NxtFstD = AddDur of 1 Month to CurFstD
(3)The last day of the current month is:
CurLstD = SubDur 1 Day from NxtFstD
the same way to get the Last day of the Next Month
Q.6) How to convert a left aligned string to a right aligned string in RPG/400 or RPG-IV?
A.6) Use EVALR opcode.
Example: *stringL: left aligned
*stringR: right aligned
C
EVALR
stringR=%trim (stringL)
Q.7) Can anybody help me how to go about debugging RPG400 pgm using STRDBG?
A.7) Here are two points should be noted:
a.) 1. ) When you compile the program use CRTRPGPGM command, use *SRCDBG/*LSTDBG in
the 'Source list options parameter
2.) STRDBG PGM(yourpgmname) OPMSRC(*YES)
But if you use STRISDB command to debug RPG400 programs, you don't have to specify any parameters
intended.
8.) Does anybody knows the way to get the size of a member of a pf.
----DSPFD FILE(library/pfile) TYPE(*MBRLIST)
9.) consider CL pgm
pgm
call A
call B
call C
call D
endpgm
A & B run successfully & error occured while executing pgm C now I have corrected the error in pgm C
when i run main pgm control should directly goto pgm C skipping pgm A & B How to do it?
i think we can trasfer pgm A & B to data area but how to do it i dont know. can anybody explain?

- 252 -

Tips n Facts

1. How long will breakup messages last? (Is it dependant on any of the parameters in JOBD,
USRPF, SUBSYSTEM?)

In my target scenario, I want to send a message to all signed-on interactive 5250 users, asking them to
perform a specific function (i.e., get off the system, exit a program, etc). The requirement to only send to
signed on users occurs because some i5/OS functions, such as the Send Break Message command
(SNDBRKMSG), will deliver the message to every system workstation message queue even if there is no
signed on user accessing that device. Delivering messages to all terminal message queues can cause
confusion when users sign on to an unused terminal at a later time and find an old message that is no longer
relevant to the system. The goal is to avoid confusion by only sending break messages to currently signedon users.
The message must also be delivered as an immediate message which each user will receive in break mode
(where the message will automatically display on the user's screen, regardless of what the user is doing).
This is required so that the user will see the message as soon as it is received. IBM offers the following two
ways to accomplish this task in i5/OS.

By Menu: The OS/400 Operational Assistance Menu (GO ASSIST) provides a Send Message
option to send messages to individual users, to all users enrolled in the system, or to all active
users.

By API: i5/OS includes the Send Message (QEZSNDMSG) API, which allows you to embed a
program call within another program or a command, so that the message can automatically be sent
without manual input.

2. Command attention key VS Command Function key

3. How can we create RPG PGM for previous releases of AS/400?


Using TGTRLS option in CRTRPGPGM command
4. Can you compare Character and numerical values. If so how the HI indicator value will get
changed (Depending on EBCIDC or ASCII ?)
COMP cannot be used for values of different data types.
5. Can we sort certain elements in an array? (Not full array, but a selected number only say ,
eg. 20-43 elements)

6. What do RETURN will do when it is executed from a program?


The return operation causes are a return to the caller as follows.

- 253 -

Tips n Facts
1. The halt indicators are checked. If a halt indicator is on, the program ends abnormally.(All files are
closed, an
error return code is set to indicate the calling routine that the program has ended
abnormally, the control returns
to the calling routine.
2. If no halt indicators are ON, the LR indicator is checked. If LR is ON, the program ends normally.
(Locked Data area, Data structures , arrays, and tables are written and external indicators are set home.)
3. If no halt indicator is ON and LR in not on, the program returns to the calling routine. Data is
preserved for the next time the program is run. Files and data areas are not written out.
7. When is Indicator 1P gets turned on (if there is a valid indicator like that)?
This is the first page indicator. And it will be on if the first page of the report is getting

printed.

8. How can we make a subfile inactive?


9. What do SFLLIN parameter

refer to?

Causes the subfile to occupy multiple columns with the same data. Typically this keyword
and
style of subfile is used when only a few (1 to 4) fields are displayed. Those fields are repeated horizontally
across the display until the display is filled. the spaces parameter controls the spacing between the
columns of inforamtion.
SFLLIN
spaces.
10. Which is the type of variable that cannot be used in as a parameter?
( choices - DS, Array, Array element......)
11. Can we use MOVEL for a numeric value?

12. Which are the various compiler directive statements available in RPG?
Generally, Directive statements in RPG are of two types.
1. Compiler Directives
2. Preprocessor Directive.
1.Compiler Directives
Controls the various functions of the compiler process such as page printing and
inclusion of external source etc.
eg: /COPY [[lib/file],]member
/COPY [file[.lib],member]
/EJECT
/TITLE text : This will print the text as title in each page.
/SPACE [n] - Causes the compiler to print 'n' blank lines.
2. Preprocessor Directive
These are processed by preprocessor. A preprocessor is a program that reads the RPG
source code and performs some work possibly altering the RPG source code before calling
the RPG compiler. The RPG compiler and SQL preprocessor directive provide functions to alter
the RPG program listing and to include SAA SQL database manager.
eg :
/EXEC SQL [SQL statements]
+ continued SQL statements.
/END - EXEC.
13. Is there any limit for the size of a parameter.
14. Compile time arrays. How can U enter values into it.
15. Difference between Runtime array and Pre-run time array.
The compile data is placed in a named data structure and the array overlays the data. This method has
the enormous benefit of having the array data alongside the definition of the array as opposed to having
to page to the end of the program to view the data. There are two interesting points to note: you can
define storage in a data structure without providing a DS sub-field name, and you can specify the name of
the data structure on the Overlay keyword.

- 254 -

Tips n Facts
D CompileData
D
D
D
D

DS
27a
27a
27a
27a

Inz('January February March ')


Inz('April May
June
')
Inz('July
August September')
Inz('October November December ')

D MonthNames
9a Overlay(CompileData) Dim(12)
Figure 1: An alternative to compile time arrays
Figure two shows another feature of defining arrays in a data structure. The Address array is defined as
having 100 elements, each element being 87 characters in length. The rest of the data structure appears
to define subfields that overlay the first element of the array (i.e. the combined length of the subfields is
87 characters). But such is not the case; since the subfields overlay an array they are themselves arrays.
That means operations (such as SortA) executed on a sub field actually affects the overlaid array. In the
example shown in Figure 2, the SortA of City results in the Address array being sorted based on the 61 to
80 character of each element. Or the SortA of State results in the Address array being sorted based on the
81 and 82 character of each element. The %SubArr BIF is used to ensure that only the elements that have
been loaded are sorted (you do not want blank elements being sorted to the start of the array).
D
D
D
D
D
D
D

Address
Street1
Street2
City
State
Zip

D noLoaded
/Free

DS

87a Dim(100) Ascend


30a Overlay(Address)
30a Overlay(Address:*Next)
20a Overlay(Address:*Next)
2a Overlay(Address:*Next)
5a Overlay(Address:*Next)
S

10i 0

SortA %SubArr(City:1:NoLoaded);
SortA %SubArr(State:1:NoLoaded);

// Sort into City sequence


// Sort in State sequence

16. Details of command XLATE


the %DEC function converts a string expression to a packed decimal number, with a specified precision:
%DEC(expression:digits:decimals)
Previous releases allowed you to use only numeric expressions with %DEC. When you use the %DEC
function
to
convert
a
string,
the
second
and
third
parameters
are
required.
If the character field Amount has a value of '00123.45' you could convert it to a packed decimal number
by coding
%DEC(Amount:7:2)
If the string value includes non-numeric characters (other than a decimal character), you can include the
%XLATE function to translate those characters to blanks. For example, if Amount has a value of
'$***12,345.67 ' you could code
%DEC( %XLATE('$*,':' ':Amount) : 7 : 2 )
to first convert the currency symbol, asterisks, and commas to blanks. The %DEC function doesn't mind
the embedded blanks, so your program would get a seven digit packed return value of 12345.67.
If the %DEC function encounters an invalid numeric value, it will return a status code of 105, which you
can easily capture:
MONITOR;
Result = %DEC(%XLATE('$*,':' ':Amount):7:2);
ON-ERROR 105;
Result
= 0;
ENDMON;
To round the numeric result, use %DECH. The %INT and %INTH functions also accept string arguments,
returning integer values.

- 255 -

Tips n Facts
17. Syntax of DO - END (Factor 1 entries etc.)

18. DCLF
OVRDBF
RCVF
..........
Here when will the file be open? ( It won't get opened. you have to give an OPNDBF)
19. Which are the types of subfiles that can be used from a CL program?
20. COMP - details of Indicators after the operation..
21. Usage of L1, L2 indicators.
23. Why Do we use OVRDBF command before OPNQRYF command
Share open data path (SHARE) - Help
Specifies whether the open data path (ODP) is shared with other programs in the same routing step.
When an ODP is shared, the programs accessing the file share facilities such as the file status and the
buffer.
The possible values are:
*NO
The ODP is not shared with other programs in the routing step. A new ODP for the file is created and
used every time a program opens the file. *YES
If the member is opened more than once, the same ODP is shared with each program in the job that
also specifies *YES on the Share open data path prompt (SHARE parameter) when it opens the member.
This includes several open operations in the same program.
24. What will happen if you specify SFLPAG greater that SFLSIZ ?
Ans : It will give error at the time of compilation saying
"Message . . . . : Value on SFLPAG keyword too large for display size."
25. What will opcode CHECK do?
This verifies that each character of factor 2 is one of the list of characters in factor 1. This is
accomplished by comparing the characters of factor 2 , character by character, to the list of characters in
factor one until a difference is detected or until the end of factor 2 is reached. If a difference is detected,
it's position is returned to the result field.
Factor 1
opcde
factor2
result
Length Dec Ext resulting Ind.
Check list
CHECK
base value: start
position
size
Dec
-- [Error] [Found]
This can be used for
1. To find the first character position of factor 2 that is not in factor 1.
2. To verify that factor 2 contains valid character. Ie only numbers or only lower case alphabet.
3. this can be used to left adjust a field. Ie Check with blank as factor 1 , it will return the first location
where non blank character is available. then do a substring operation
26. Multiple Occurrence Data Structure
A multiple-occurrence data structure is a data structure whose definition is repeated in a program to
form a series of data structures with identical formats. You specify the number of occurrences of a data
structure in positions 44 through 47 of the data structure statement. When positions 44 through 47 do
not contain an entry, the data structure is not a multiple-occurrence data structure. All occurrences of a
data structure have the same attributes and can be referred to individually. The OCCUR operation code,
which can only be used with a multiple-occurrence data structure, allows you to specify which occurrence
of a data structure is used for subsequent operations within the program. Note: Multiple occurrences are
not allowed for a data area, file information, or program-status data structure.
27.
/COPY is a compiler directive command which will include another RPG piece of source in to the
program at compile time. This is similar to the #include command in C.
format :
/COPY [[library/[file,]member
: Causes the compiler to include source
code contained in a separate
source member. Any RPG source code can be included using the /COPY
directive.

- 256 -

Tips n Facts
/COPY[file[.library],]member]
Causes the compiler to include source code contained
in a separate source member. Any RPG source code can be included using the /COPY directive. This syntax
is valid for RPG on the system/38 and in the system/38 environment on the AS/400
28.
Same name can be used for an array declaration and a data structure. In this case, it can be
used as both array as well as Data structure.
Eg.
E
MW1
7 20
E
MW2
14 1 0
E
M10
7 10
E
WKE
5 1
I
DS
I
1 7 M10
I
1 70TMPBGD
I
1 7 TMPBGB
I
1 7 TMPBGZ
I
2 60 TMPBG
I
DS
I
1 14 MW1
I
1 14 MW2
29 . EXCPT command :
This operation performs an immediate write to either a program defined output file or an externally
described file's record format. EXCPT [ Except label] Factor 2 can contain the name of an EXCPT label.
Except labels are used to control the output to the output record. when an EXCPT label is present, only
those output specifications that contain the EXCPT label are written. (more details -- Robert Cozzi page :
197)
30. Parameter Passing in RPG.
In RPG the parameter is passed by reference. ie the address is passed to the called program. and
it access the same location.
31 .I would like to know more about MI in AS/400. I came across some sources with source type as MI .I
came to know that it stands for Machine Instructions.Is that correct???Is it something like writing
programs in the machine language???Please let me know where I could get more information about this.
(a) MI stands for Machine Interface. In the context of programming languages, MI is a set of
assembler-like instructions you can pass to the QPRCRTPG API to create a program. You'll need the
Machine Interface Functional Reference SC41-5810-01, available only in hardcopy. In the context of
architecture, MI is an abstract layer between the OS/400 and the SLIC.

SUBFILES
SFLDSP : When its enables it causes the SFLRCD to be displayed whenever the SFLCTL record is
WRITTEN in to the screen. This can be controlled using indicators. This is a mandatory entry. The default
value Y appears because a subfile control record requires the SFLDSP keyword. This keyword tells the
system when to begin displaying records from the subfile. If you do not specify condition indicators,
records appear on every output operation to the subfile control record.
SFLDSPCTL : Type Y (Yes) to specify when to display the subfile control record. If you do not
specify condition indicators, the subfile control record appears on every output operation to the subfile
control record. This is for the fields described for the control formats. if this is mentioned the fields on the
SFLCTL will be displayed wenever youperform a write operation of the SFLCTL.
SFLCLR :Specify condition indicators to instruct the system to clear all records from the subfile.
The system does not delete the subfile area, and the subfile contains no data. You must specify a
condition indicator to prevent the system from clearing the subfile on every output operation to the
subfile control record.
33) If RRN number exceeds the limit or if it's zero, the following error will occur at runtime,'Session or
device error occurred'
34) What will happen if you declare the subfile size less than the subfile page size?
It will give the following error at compile time of the display program
SFLSIZ value less than SFLPAG value for display size. severity 20
35)

Data Structure & data areas are character variables.

- 257 -

Tips n Facts
36. Subfile Page Control
I am loading a one shot subfile(loading all records at a time) i see that when i press enter the subfile rolls
back to the first page. I remember when i last wrote a page by page build subfile i had to to get that value
from the INFDS and move it to the SFLRCDNBR field. Do i have to do the same thing here i was suprised
as i did not realise this until lately. The subfile is a output subfile and i take function keys on one of the
records to access details of it.
Ans :
1 I do know that there is a DSPF DDS keyword that returns the RRN of the record at the top of the
currently displayed screen through a program-to-system variable. I think you should put this keyword
(whose name escapes me just now) into your SFLCTL record format, then after an EXFMT, move the value
returned into the SFLRRN variable. This would keep the current page on the screen until a roll key is
pressed. In the morning when I get back to work, I'll scan my DDS source archive and post the right
keyword, unless someone else beats me to it.
2.
The following lines of code are standard in most of my subfiles:
A
RTNCSRLOC(&RCD &FLD &POS)
A
SFLCSRRRN(&SRN)
A
DSRRN
4S 0H
SFLRCDNBR(CURSOR)
A
SRN
5S 0H
A
FLD
10A H
A
RCD
10A H
A
POS
4S 0H
I'm assuming from the text in your post that you already know what the SFLRCDNBR keyword does. The
SFLCSRRRN keyword, for all practical purposes, does the opposite. Here is what the DDS Reference
manual says: Use this record-level keyword on the subfile control record format to return the relative
record number of the record on which the cursor is located within a subfile.
After your program performs an EXFMT operation, the RRN of the record where the cursor was
placed is contained in the SRN field. Replace the value in the DSRRN field with this value, and the screen
will return to the same page every time you press Enter.
The RTNCSRLOC keyword returns the record format name, field name, and position within the
field where the cursor was located when control returned to the program (a function key or Enter was
pressed). This keyword is instrumental in performing cursor-sensitive prompting, sorting, and other
interactive program functions. Net
37.

What is the field reference Physical File. (brief)

38.

What are the different types of PF

39.

What are the different types of LF.

40.

Which are the Keywords used for creating a Join LF (as per sequence.)

41.

What is the use of JDFTVAL keyword while creating a Join LF

42.

What is the use of UNIQUE keyword at file file level (PF/LF)

43.

What is the use of 'S' and 'O' when used with the fields at position 25 of LF (Select/Omit records)

44.

What is the command to see the attributes of the file.

45.

What is the command to see the attributes of the fields.

46.

What is the command to see the logical files attached for a specified PF.

47.

Which spec. is compulsory in RPG/400.

48.

How to control the opening and closing of file in RPG/400.

49.

Which are the different control statements (like IF.., etc)

50.

Which are the Looping statemtents.

51.

How to rename a record format in a program (for the use of prog),

52.

How to rename a field in the program (for the use of prog)

- 258 -

Tips n Facts
53.

What is the difference between D0 WHILE and DO UNTIL.

54.

What is the difference between ITER and LEAVE.

55.

What is the difference between the READP and REDPE.

56.

What does the DEFN opcode do.

57.

What is the difference between the MOVE and MOVEL.

58.

What does the SETLL command do.

59.

How is the SETGT command different from SETLL.

60.

How is CHAIN different from SETLL.

61.
How to define composite key in the RPG prog. (what are the keywords) What are the conditions
are to be considered.
62.

What do read a record without locking the record if the file is in UPDATE mode.

63.

What are the different ways of passing PARAMETER from one program to another.

64.

How to return the value to the calling program.

65.

What are the different ways of loading a SUBFILE.

66.

What are the necessary keywords for SUBFILE.

67.

What is the difference between the SFL and SFLCTL.

68.

What does the SFLRCLR keyword do? Is it ALWAYS compulsory to clear a subfile

69.

What is the difference between the Initializing and Clearing a subfile.

70.

Which keyword indicator is to be used for not displaying blank subfile.

71.

Name and Explain at least five keywords related to SUBFILE

72.

What is the use of SFLRCDNBR .

73.

What is the use of SFLMSGRCD keyword.

74.

What are the different types of ARRAYS

75.

Which opcode has to be used to search to find a element in array.

76.

What is the basic difference between ARRAY and TABLE

77.

What is DATA STRUCTURE.

78.

What the OCCUR opcode do .

79.

How to initialize an ARRAY.

80.

What is the difference between record level data structure and subfield data structure

81.

What is DATA AREA.

82.

What are different types of DATA AREAS.

83.

What is the difference between the SETON LR and SETON RT(return).

84.

What is MOVEA used for.

85.

When MVR opcode can be used.

- 259 -

Tips n Facts
86.

How to unlock a record, with out updating or reading next record.

Here is the answers of some of your questions


6-Unique keyword is used to make the key of your PF,LF unique.
8-DSPFD is the command used for this purpose
9-DSPFFD
10-DSPDBR
11-In RPG all Specs are optional
12-You can handle files in RPG/400 by using RPG traditional cycle. You can also handle RPG files yourself.
For program cycle your one file would be primary and rest of the files would be secondary, then RPG
automatically open and close the files. Otherwise if you define the file as a Full procedural file then you
have the control fo the file and you will open and close your file yourself.
13-SELEC, WHEN, CAS (Conditionally invoke a subroutine), GOTO, CAB (compare and Branch), Else
15- For renaming of record select FC prompt in SEU editor, Enter External record name, in option enter
RENAME key word and in Entry write the new/changed name
16-For renaming of a field used JX column in I-Spec
18-DOUNTIL check the condition at the end of the pass while Do WHILE check the condition at the
beginning. If your condition doesn't meet then DO While doesn't execute but DOUNTIL will execute first
time and check the condition at the end.
20-Define the field in RESULT with same attributes in factor 2 if *LIKE is in factor 1 and also used to
define dataarea within the program if you have *NAMVAR in factor 1. you cannot use/access data area
without definning in this way
21-MOVE operation move data from right and MOVEL start moving data from left. IN RPG by default move
is from right
18-Whenever you get an ITER operation in your body of the loop again go to the top of the loop check
condition if meets then execute the new pass. If find Leave then Leave the loop though still the condition
exists for the loop
25-You can define composite key in RPG/400 by KLIST in Op Code and name of the Key list (Composite
key) in factor 1 and then definning KFLD for this Key list in Op code and KFLD name in the RESULT field of
the C-Specs
87. CLEAR opcode in RPG.
This opcode sets the factor2 to blanks, Zeros or 0 depending on its attribute. this can be used for
initialising Fiedl,Data Structure,Data Area,Data Structure subfield,record format
Program termination Indicator
Normally last record indicator and Return indicators are used as the program termination
indicators. LR is used as a signal that program should terminate upon reaching the end of calculation
specification. or when the RETRN operation is performed. RT , when used indepandantly, signals that the
program should end but remain active in memory at the completion of the calculation spec. Function Key
Attention Identification Byte
An alternative of assigning function key response indicator is being
used more frequently. This method avoids assigning indicators and uses the function indication byte(FIB)
in position #^( of the workstation info. Data structure. ie when a function key is pressed, the FIB will be
automatically fed with a value and by checking that value, we can understand which key was pressed.
RPG CYCLE Program class
File Type Entries in F- Spec.
I - I to indicate an input file.
O - O to indicate an output file.
U - U to indicate an update file.
C - C to indicate a combined (input/output) file.
File Designation :
Blank - Leave the field blank to indicate an output file.

- 260 -

Tips n Facts
PSRTF-

Type P to indicate a primary file.


Type S to indicate a secondary file.
Type R to indicate a Record address file.
Type T to indicate an array or table file.
Type F to indicate a full procedural file.

88. Trigger :
When a trigger associated with a file fails , Escape message CPF502B will be issued.
There can be max 6 types of triggers attached to a file
Pre/Post - Insert, Update,Delete.
A trigger program should have two parameters
89. Limitations in RPG
Max. Number of Subroutines in a program : 254
Max. No. of Arrays or tables in a program : 200
Max No. of Elements in an Array
: 9999
Max. No. of Record formats in a Diaplay file: 80
90 . Differenct between Array & table
In array , we can use subscript, In table , we can't.
91. The indicators in RPG program is an implicit array *IN maintained by the program. We can use this
just like and array to initialize and retrieve. But SORT operation cannot be specified on this. The only
possible value, which we can store in the element is 0 or 1.
92. Array Lookup.
LOKUP - The look up operation searches an arrya or table for a search argument.
Search Arg
LOKUP array, Start Element
If the lookup is successful and the starting element is a numeric variable, the variable is set to the
element where the search was successful.
Up to 2 indicators can be specified for a lookup operation.
93.Prerun time array is loaded from an array file when your program begins running before any input
calculation or output operations are processed.
94. Unlike an array name, the table name does not refer tothe entire set of table elements.So we cahhot
initialize a table using its name as in the case of an array.
95. Run-Time Array
If you make no further specifications beyond the essential array specifications, you have defined a runtime array. Note that positions 33 through 35 must be blank for a run-time array.
*...1....+....2....+....3....+....4....+....5....+....6....+....7...
E....FromfileTofile++Name++N/rN/tbLenPDSArrnamLenPDSComments
E
ARC
12 3
96. Compile-Time Array
For a compile-time array, you must specify in positions 33-35 of the extension specification how many
array entries are in an array input record. This is in addition to the required array specifications on the
extension specification.
*....+....1....+....2....+....3....+....4....+....5....+....6....+....*
E....FromfileTofile++Name++N/rN/tbLenPDSArrnamLenPDSComments
E
ARC 12 12 3
**
48K16343J64044H12648A47349K34650B125
?????????????????????????????????????????????????????????????????????????
? 48K ? 163 ? 43J ? 640 ? 44H ? 126 ? 48A ? 473 ? 49K ? 346 ? 50B ? 125 ?
?????????????????????????????????????????????????????????????????????????
This is the compile-time array, ARC.
97. Prerun-Time Array
On the extension specifications, in addition to the essential array specifications, specify the name of the
file with the array input data, in positions 11 through 18. In positions 19 through 26, you may optionally
specify the name of a file to which the array is written at the end of the program. E* Prerun-time array.

- 261 -

Tips n Facts
ARE, which is to be read from file DISKIN, E* has 250 character elements (12 elements per record).
Each element E* is five positions long. The elements are arranged in E* ascending sequence.
E DISKIN
ARE 12 250 5 A
Note: The file DISKN must be a sequential program described file.
98. Difference between arrauys and tables
Defining A table name must be a unique symbolic name that begins with the letters TAB. Loading Tables
can be loaded only at compilation time and prerun-time.
Multiformat Files
A multiple format logical file lets you use related records from two or more physical files by referring to
only one logical file. Each record format is always associated with one or more physical files. You can use
the same physical file in more than one record format.
In RPG program you can use the file and read whichever record format you want. You have the flexibility
to make the program IGNORE any of those record formats. This is done by specifying IGNORE in File
continuation spec.
FOPNPAY IF E
K
DISK
F
OPNPAYAH
KIGNORE
In this case, the program will ignore the record format OPNPAYAH completely while doing the file
processes.
USING A DIFFERENT FONT IN A REPORT
Q: Is there a way to use a different font in printing a report on an AS/400, particularly when the report
was generated with RLU (Report Layout Generator)?
Ans: The method for changing the font will vary by printer type. Impact Printers will use a combination
of font FGID's, 011 for Courier 10 cpi, 046 for Courier Bold 10 cpi, etc., or the highlight function to
double strike the field, making it bold. For most laser printers, the use of a font as a record or field-level
parameter is used to control the look of the output page.
The following was copied from the RLU manual, SC09-2635-00
(http://publib.boulder.ibm.com/cgi-bin/bookmgr/DOCNUM/SC09-2635-00 ), in the online library. You
should understand how the printer you are using is attached, what fonts it has resident, what font
substitution may occur based on the AS/400 printer device or remote outqueue used, and the keywords
in the DDS control for the font used.
Font:
Use this record-level or field-level keyword to specify the font ID for printing a named or constant field or
fields within a record. Option indicators are valid for this keyword. Certain fonts require a font identifier.
To specify a font identifier, type Y (Yes) for the Change defaults prompt on the Exit RLU display when you
are creating a printer file or prototyping a report. Specify a value in
the Font Identifier prompt.
Highlight (HIGHLIGHT):
Use this record-level and field-level keyword to indicate that a field should be printed in bold letters.
Option indicators are valid for this keyword.
Date, Time, and Timestamp Fields
Date, time and timestamp fields are brought into your RPG/400 program only if you specify the
*DATETIME value on the CVTOPT keyword of the CRTRPGPGM or CRTRPTPGM commands. If *DATETIME
is not specified, date, time, and timestamp fields are ignored and inaccessible in your RPG/400 program.
For a description and the syntax of CVTOPT, see the CVTOPT parameter on
page 3.2. Date, time or timestamp fields are brought into an RPG/400 program as fixed-length character
fields. Your RPG/400 program can perform any valid character operations on the fixed-length fields.
Since date, time, and timestamp data types each have their own format, if a field containing date, time or
timestamp information is output to your database file, the format and separators in the field must be
exactly as required by the declared format. If the same format or separators are not used, an
exception/error will occur. For more information on the formats of these database data types, see the
DDS Reference.
If you add a record to the database file and date, time, and timestamp fields are not specified for output,
the RPG/400 compiler will place default values in the fields for output. The default value of date for any
format is year 1, month 1, and day 1. The default value of time for any format is hour 0, minute 0, and
second 0. The proper separators will be placed into the field according to the declared format.
Keyed operations are not allowed when factor 1 of a keyed operation corresponds to an ignored date,
time, or timestamp key field.
Sequential-within-limits processing is not allowed if there is an ignored date, time or timestamp key field
in the file.
Giving Color to RPG Source
Did you ever have some particular comment or section of code that you would ike to have stand out so
that when the next person comes along he would be sure to see it? Maybe it's instructions to compile a
program or display file in a certain way or to note that someone should be notified if a certain piece of
logic changes. Maybe you have a specific way that a certain program needs to be implemented whenever

- 262 -

Tips n Facts
it's changed. Wouldn't it be nice to be able to highlight, reverse image, draw boxes, change the color of
the source code, etc. for the source code you want to emphasize? Although it's not provided in SEU, you
can do this by inserting the proper hexadecimal code(s) into your source file.
I've found that the hex values to add emphasis begin at about hex 22 and end somewhere before hex 40.
I find it easier to create a master source member with the desired emphasis and then copy those lines into
the programs where I want to emphasize the source code. The sample program will demonstrate a couple
ways to emphasize source as well as use them in combination to draw a box. If you have access to a
dumb terminal that allows entry of hex characters, you can skip the sample program and enter
the hex codes directly into your source member. While the highlighting codes are not visible in the edited
source, their value must remain in the source code and be displayed in the viewable part of the screen for
them to have their desired effect.
Here is a short list of hex values that you may find more interesting than others:
22 - Highlight White
23 - Highlight and Reverse Image White 24 - Underline
28 - Color Red
29 - Red Reverse imaged.
30 - Turquoise
31 - Turquoise reverse imaged
32 - Yellow
33 - Yellow reverse imaged
34 - Turquoise Underlined
35 - Turquoise Underlined & Reverse imaged 36 - Yellow underlined
38 - Pink
39 - Pink Reverse imaged.
Program source - BLDSRC - Builds a source member with sample highlighting
FOUTFIL1 O F
92
DISK
IOUTREC
DS
I
13 13 FLD1
I
15 15 FLD2
I
20 31 TEXT1
I
81 81 FLD3
I
83 83 FLD4
I
1 92 SRC
I
'SAMPLE TEXT'
C
TEXT
C
CLEARSRC
C
MOVELTEXT
TEXT1
C
MOVELX'21'
FLD1
RI
C
WRITEOUTFIL1 OUTREC
C
MOVELX'22'
FLD1
HI
C
WRITEOUTFIL1 OUTREC
C
MOVELX'23'
FLD1
HI RI
C
WRITEOUTFIL1 OUTREC
C
MOVELX'24'
FLD1
UL
C
WRITEOUTFIL1 OUTREC
C
MOVELX'28'
FLD1
RED
C
WRITEOUTFIL1 OUTREC
C* DRAW BOX
C
Z-ADD0
COUNT 10
C
COUNT
DOUEQ3
C
ADD 1
COUNT
C
CLEARSRC
C
MOVELX'23'
FLD1
C
MOVELX'22'
FLD4
C
COUNT
IFEQ 2
C
MOVELX'22'
FLD2
C
MOVELX'23'
FLD3
C
END
C
WRITEOUTFIL1 OUTREC
C
END
C
SETON
LR
Commands to run
CRTSRCPF FILE(MYLIB/SRCSMPLE) RCDLEN(92) MBR(SRCSMPLE)
OVRDBF FILE(OUTFIL1) TOFILE(MYLIB/SRCSMPLE) MBR(SRCSMPLE)
CALL PGM(BLDSRC)

- 263 -

Tips n Facts
Creating Flexible Join Files
Hey, Ted:
I was wondering if there is any way of creating a join file with some flexibility? I will try my best to provide
an example:
I have one file that contains several fields, one of which is a 998-byte string of data. I have another file
that contains the mapping (start position & field length) for the string. Part of each of the files is a part
number that I can use to join the files. Each part may be mapped differently. The number of fields mapped
from part to part may be different.
I would like to join the two files and create mapped fields that use the mapping coordinates to extract
appropriate substrings from the 998-byte field. The trick is that mapping coordinates may change from
part to part. Here's an example for two parts. Two values are to be extracted from part number 1, while
three values are to be extracted from part number 2.
String File
Part#
String (only showing 10 chars for my example) 1
1234567890
2
0987654321
Mapping file
Part#
Field Start
1
1
1
4

Field length
3
7

Mapped Value
123
4567890

2
1
4
0987 2
5
1
6
2
6
5
54321
Any suggestions?
That's a very interesting and intriguing question. I am a big fan of softcoding (placing information into
files, rather than in source code) and am always interesting in seeing how someone somewhere softcodes
applications. When information is softcoded, it is easily changed with a file maintenance program,which
means a programmer is not required to modify and recompile a program.
The challenge you've presented me is easily handled with SQL's substring function. Substring accepts
three arguments--the string from which data is to be extracted, the position at which to begin extracting,
and the number of characters to extract. Users of SQL typically use literal values for the second and third
arguments because we usually know in advance how many characters we need and where that string of
characters begins. However, the second and third arguments may be resolved at run-time. We tend to
forget
this, since we rarely use it.
Here's some SQL that builds your two files and loads the values in your example.
create table stringf (
PartNbr dec(5,0),
PartString char (10),
primary key (PartNbr))
create table mappingf (
PartNbr dec(5,0),
FieldStart dec(3,0),
FieldLen dec(3,0))
insert into stringf values (1,'1234567890') insert into stringf values
(2,'0987654321') insert into mappingf values (1, 1, 3) insert into mappingf
values (1, 4, 7) insert into mappingf values (2, 1, 4) insert into mappingf
values (2, 5, 1) insert into mappingf values (2, 6, 5)
Here's the SQL statement that extracts the mapped values you requested. Because I do not understand
the purpose of this mapped field, I called it XYZ. I'm sure you can come up with something more
descriptive.
select a.PartNbr, FieldStart,
FieldLen, PartString,
substr(PartString, Int(FieldStart),
Int(FieldLen)) as xyz
from stringf as a
inner join mappingf as b
on a.PartNbr = b.PartNbr
One way to make it easier to work with this definition is to store it as a view. A view is similar to a logical
file and is created from a select statement. The following SQL statement creates a view over the stringf
and mappingf tables. Using a view saves you from having to copy the join criteria.

- 264 -

Tips n Facts
Create view partmap as
select a.PartNbr, FieldStart,
FieldLen, PartString,
substr(PartString, Int(FieldStart),
Int(FieldLen)) as xyz
from stringf as a
inner join mappingf as b
on a.PartNbr = b.PartNbr
Query/400's substring function can also accept expressions in the starting and length arguments. Here's
the same calculation done with Query:
Field
XYZ

Expression
substr(PartString,FieldStart, FieldLen)

How Do You Say Midnight in RPG?


Hey, Ted:
On a recent project, I was faced with the dilemma as to whether or not 00:00:00 is a valid time value on
the AS/400. The reason for my quandary was triggered by a passage that I read in a popular RPG
textbook. According to what I read, T'00:00:00' is a fictitious time.
Would I ever get a time of 00:00:00? If so, how can I check for a NULL time
(i.e., NO time)? Thanks for the help.
-- Tim
Both 00:00:00 and 24:00:00 are valid times. A time of *loval is the same as 00:00:00. A time of *hival is
24:00:00.
Both stand for midnight. However, they are not identical:
0 hour is midnight at the beginning of the day. 24 hours is midnight at the end of the day. Furthermore, 0
hour at the beginning of one day is not the same as 24 hours at the end of the previous day.
We have provided a couple of short programs that you can compile and play with if you would like to get a
better idea of how RPG uses these two time values.
In the first program, two time variables are initialized to '00:00:00' and '24:00:00'. (You may substitute
*loval and *hival for the two time literals.) Then 1 second is added to the first time variable and 1 second
is subtracted from the second time variable. Next, the program determines the number of seconds
between the two time variables. Since there are 86,400 seconds in a 24-hour period, you will probably not
be surprised when the elapsed time is two seconds less than that.
H datfmt(*iso)
D Time1
s
t
D Time2
s
t
D elapsed
s
10u 0
C
eval
Time1 = t'00.00.00' C
eval
Time2 = t'24.00.00'
C
adddur 1:*s
Time1 C
subdur
1:*s
Time2
C
Time2
subdur Time1
elapsed:*s
C
elapsed
dsply
C
eval
*inlr = *on
The second program shows that 0 hour of one day is the same as 24 hours of the previous day, even
though RPG does not consider them the same. In this program, Time1a and Time2a are set to midnight at
the end of December 24 and midnight at the beginning of December 25, respectively. The two times are
compared and found to be unequal.
Next, 1 second is subtracted from those two times and the results are stored in variables Time1b and
Time2b. These two values are compared and found to be equal.
H
D
D
D
D
C
C
C
C
C
C

datfmt(*iso)
Time1a
Time1b
Time2a
Time2b

s
z
s
z
s
z
s
z
eval
Time1a = z'2001-12-24-24.00.00'
eval
Time2a = z'2001-12-25-00.00.00'
if
Time1a = Time2a
'a:equal'
dsply
else
'a:not equal' dsply

- 265 -

Tips n Facts
C
endif
C
Time1a
subdur 1:*s
Time1b
C
Time2a
subdur 1:*s
Time2b
C
if
Time1b = Time2b
C
'b:equal'
dsply
C
else
C
'b:not equal' dsply
C
endif
C
eval
*inlr = *on
With character variables, you can add the VARYING keyword and use a length of zero to represent null
values. RPG doesn't allow zero-length variables of other data types, including date, time, time stamp, and
the various numeric data types, nor does RPG allow you to place a special value in variables of those data
types. We have two workarounds that you can use to store a null time value.
The first is to code an additional Boolean-type variable for every variable that can have a null value. A
Boolean variable can have only a true value or a false value. Boolean variables are implemented in RPG IV
with the indicator data type, which is specified by a data type of n in the definition specification.
If indicator variable TimeNull is on, then variable Time is considered to be null, regardless of its value. If
TimeNull is off, then the value of Time is not null. Notice that it is the programmer's duty to look first at
the null flag before using the Time variable. The following snippet demonstrates this technique:
D Time
s
z
D TimeNull
s
n inz(*on)
* Set time if it hasn't been initialized
C
if
TimeNull
C
time
time
C
eval
TimeNull = *off
C
endif
In the second technique, use a basing pointer for null-capable fields. If the pointer is set to null, the Time
field is considered null. The ALLOC opcode allocates storage and sets the pointer to a non-null value. If
you need to set Time to null, use the DEALLOC keyword with an operation extender of (n). DEALLOC frees
storage. Operation extender n tells DEALLOC to set the pointer back to null after the storage is
successfully deallocated.
The following snippet of source code demonstrates this technique:
D Time
s
z based(pTime) D Size
s
5i 0
* Set time if it hasn't been initialized
C
if
pTime = *NULL
C
eval
size = %size(Time)
C
alloc
size
pTime
C
time
time
C
endif
* Deallocate storage and set pointer to null
C
if
pTime <> *NULL
C
dealloc(n)
pTime
C
endif
You can allow null values in fields of a database file regardless of data type, but that is a different question
and answer.
*
Ted and David
* Fun with SQL Date Math
Hey, Howard:
I have a question about SQL. Suppose I have a table containing sales for each day of a year, and it looks
like the following example:
SDATE SALETOTAL
-------------------------11/01/2000 5000
11/02/2000 5500
11/02/2001 7000
11/03/2001 5800
11/04/2001 6000
Then I have another table that describes our accounting year by week:
PHYR PHWK
SD
ED
-----------------------------------------------------------2000
40
2000 11 01
2000 11 07
2001
40
2001 11 03
2001 11 10

- 266 -

Tips n Facts
Now, I want a query that compares the sales for a day in this year to the corresponding accounting day
from the same week last year and yields results like the following:
Current Year
Sale
Last Year
Sale
-----------------------------------------------------------2001 11 03
5800
2000 11 01
5000
2001 11 04
6000
2000 11 02
5500
How can I perform this function in SQL?
-- Muhammad
This is a fun query because you get to take advantage of AS/400 date math, outer joins, and general
goofiness! Muhammad, I am going to include all of the create table and insert statements so that you can
try this example at home or at work. First, download a free SQLThing from http://www.sqlthing.com
<http://www.sqlthing.com>
to execute the following commands, (or use Operations Navigator or
interactive SQL if you are so inclined):
CREATE TABLE SQLBOOK/HTSALES (
SDATE DATE,
SALETOTAL DECIMAL(10,2),
PRIMARY KEY (sdate));
CREATE TABLE SQLBOOK/HTFISCAL (
PHYR SMALLINT,
PHWK SMALLINT,
SD DATE,
ED DATE,
PRIMARY KEY (PHYR, PHWK),
CHECK (SD<ED));
Note that I placed a check constraint into the HTFISCAL table to ensure that the SD field is always less
than the ED field when a record is entered. Execute the following insert statements to place test data into
your files:
/* Data for the HTFISCAL table */
INSERT INTO SQLBOOK/HTFISCAL VALUES (2000,39,'10/25/2000','10/31/2000');
INSERT INTO SQLBOOK/HTFISCAL VALUES (2001,39,'10/27/2001','11/02/2001');
INSERT INTO SQLBOOK/HTFISCAL VALUES (2000,40,'11/01/2000','11/07/2000');
INSERT INTO SQLBOOK/HTFISCAL VALUES (2001,40,'11/03/2001','11/10/2001');
INSERT INTO SQLBOOK/HTFISCAL VALUES (2000,41,'11/08/2000','11/14/2000');
INSERT INTO SQLBOOK/HTFISCAL VALUES (2001,41,'11/11/2001','11/17/2001');
INSERT INTO SQLBOOK/HTFISCAL VALUES (2000,42,'11/15/2000','11/21/2000');
INSERT INTO SQLBOOK/HTFISCAL VALUES (2001,42,'11/18/2001','11/24/2001');
/* Data for the HTSALES table */
INSERT INTO SQLBOOK/HTSALES VALUES ('11/01/2000',5000); INSERT INTO
SQLBOOK/HTSALES VALUES ('11/02/2000',5500); INSERT INTO SQLBOOK/HTSALES
VALUES ('11/03/2001',5800); INSERT INTO SQLBOOK/HTSALES VALUES
('11/04/2001',6000); INSERT INTO SQLBOOK/HTSALES VALUES ('11/02/2001',7000);
Now, we are ready to cook. Consider the following query:
SELECT * FROM SQLBOOK/HTSALES a
INNER JOIN SQLBOOK/HTFISCAL c
ON (a.sdate >= c.sd
AND a.sdate <= c.ed);
If you're at V5R1, you can use this form, if you prefer:
SELECT * FROM SQLBOOK/HTSALES a
INNER JOIN SQLBOOK/HTFISCAL c
ON (a.sdate BETWEEN c.sd AND c.ed);
This query asks for all of the fields from the HTFISCAL table and the HTSALES table and joins the two
tables where the SDATE (the date of the sale) falls between the SD (start date) and ED (end date). By
executing this statement, we now have a virtual table that consists of the total, date sold, accounting
week, accounting year, accounting start period, and accounting end period. The results should look like
this:
SDATE SALETOTAL PHYR PHWK SD ED
------------------------------------------------------------------------ --11/02/2001 7000 2001 39 10/27/2001 11/02/2001
11/01/2000 5000 2000 40 11/01/2000 11/07/2000
11/02/2000 5500 2000 40 11/01/2000 11/07/2000
11/03/2001 5800 2001 40 11/03/2001 11/10/2001
11/04/2001 6000 2001 40 11/03/2001 11/10/2001
Now, we need to know the start date of the week period for the prior year, so we add another join to the
query where the PHWK values are equal, but the year of the sales period is PHYR-1:
SELECT SDATE,SALETOTAL,C.SD,D.SD
FROM SQLBOOK/HTSALES a

- 267 -

Tips n Facts
INNER JOIN SQLBOOK/HTFISCAL c
ON (a.sdate >= c.sd
AND a.sdate <= c.ed)
INNER JOIN SQLBOOK/HTFISCAL d
ON (c.phwk = d.phwk AND c.phyr-1 = d.phyr);
V5R1 users may prefer to use BETWEEN in the join, like this:
SELECT SDATE,SALETOTAL,C.SD,D.SD
FROM SQLBOOK/HTSALES a
INNER JOIN SQLBOOK/HTFISCAL c
ON (a.sdate BETWEEN c.sd AND c.ed)
INNER JOIN SQLBOOK/HTFISCAL d
ON (c.phwk = d.phwk AND c.phyr-1 = d.phyr);
Notice that I am joining the HTFISCAL file to itself in order to find the previous year start date. The SQL
statement should yield
results similar to the following:
SDATE SALETOTAL C.SD D.SD
----------------------------------------------------------- 11/02/2001 7000
10/27/2001 10/25/2000
11/03/2001 5800 11/03/2001 11/01/2000 11/04/2001 6000 11/03/2001
11/01/2000
Now, it's time for some magic. Use date math to find the corresponding sales day for the previous year.
Calculating the previous sales date using the following expression does this:
PreviousSalesDate = (ThisSalesDate - ThisWeekStart) + LastYearStart
Note that this will only work if the difference between the ThisSalesDate and the ThisWeekStart value is
within a calendar month or so. This is because the AS/400 system returns results of date arithmetic in
durations. However, for the purposes of this report, we should never have a start date greater than seven
days from the sales date in order for it to work. If we did have a period greater than a month, we would
have to use some complex SQL to account for the greater durations. Since, we don't need to do this, the
query can remain simple. For more information on durations and date
math, check my Web site, http://www.sqlthing.com <http://www.sqlthing.com> ,
or purchase my book, "iSeries and AS/400 SQL at Work." So, to get the result, we just join again to the
HTSALES table, but this
time on our calculated previous-year sales date in order to yield a table of the correct data:
SELECT a.sdate, a.saletotal, b.sdate, b.saletotal FROM SQLBOOK/HTSALES a
INNER JOIN SQLBOOK/HTFISCAL c
ON (a.sdate >= c.sd AND a.sdate <= c.ed)
INNER JOIN SQLBOOK/HTFISCAL d
ON (c.phwk = d.phwk AND c.phyr -1 = d.phyr)
LEFT OUTER JOIN SQLBOOK/HTSALES b
ON (b.sdate = (a.sdate-c.sd) + d.sd);
V5R1 installations may use this form instead:
SELECT a.sdate, a.saletotal, b.sdate, b.saletotal FROM SQLBOOK/HTSALES a
INNER JOIN SQLBOOK/HTFISCAL c
ON (a.sdate BETWEEN c.sd AND c.ed)
INNER JOIN SQLBOOK/HTFISCAL d
ON (c.phwk = d.phwk AND c.phyr -1 = d.phyr)
LEFT OUTER JOIN SQLBOOK/HTSALES b
ON (b.sdate = (a.sdate-c.sd) + d.sd);
This SELECT statement uses a LEFT OUTER JOIN so that the AS/400 will return NULL for any dates and
totals that do not exist in the previous year's data. Either version of the SELECT statement yields the
following results:
SDATE SALETOTAL SDATE SALETOTAL
---------------------------------------------------------- 11/02/2001 7000
#NULL# #NULL#
11/03/2001 5800 11/01/2000 5000
11/04/2001 6000 11/02/2000 5500
See, joins and date math can be fun. I hope you enjoy it.
-- Howard
Positioning the cursor to a particular field
In the display file,
select record level key words.
Select output keywords.
in the place of 'cursor position for output:" specify an indicator.
Give two field names for row and column.
In the program,
Move the cursor location into the row and column variables specified in the display file.

- 268 -

Tips n Facts
Seton the indicator.
Now so EXFMT of the record format, the cursor will be positioned to the location which you specify.
Doing trigonometric functions
JUST CAN'T GET ENOUGH OF RPG AND TRIGONOMETRIC FUNCTIONS >Once more, trigonometric
functions are a topic of discussion! Ed >De Ryder wrote to share an enhancement to last week's program
example.
In the previous program example, Pi is defined as a constant in >the D-specs. Ed pointed out that the arc
cosine of -1 is Pi. >Because SQL's acos function returns a double float value, you can >use the function to
calculate the value of Pi with considerable >precision.
The following version of last week's sample program includes Ed's >enhancements:
*
========================================================= >
*
* = Using C function library trigonometric functions
=>
* ========================================================= >
H BndDir( 'QC2LE' )
H DftActGrp( *No )
D GetCosine
Pr
8F ExtProc( 'cos' )
D
8F Value
D GetArcCosine Pr
8F ExtProc( 'acos' )
D
8F Value
D Pi
S
8F
D Angle
S
3 0 Inz( 30 )
D Radians
S
8F
D Cosine
S
8F >
C
Eval
Pi = GetArcCosine( -1 )
C
Eval
Radians = ( Angle * Pi ) / 180
C
Eval
Cosine = GetCosine( Radians )
C
Eval
*InLR = *On
Debugging a batch Program
Using your interactive screen to debug a batch job submitted to the job queue allows you to put the batch
job into debug mode and to set breakpoints without having to change the program to run interactively.
1.
Submit the job with the HOLD (*YES) parameter: SBMJOB HOLD(*YES) or Hold the job queue
that before submitting the job by using the HLDJOBQ command.
2.
Determine the job name, user, and number of the submitted job by using the WRKSBMJOB
command.
3.
Type the Start Service Job command on your screen: STRSRVJOB
JOB(job name/user/number)
4.
Type the Start Debug command on your screen: STRDBG
5.
Release the job in the jobq. Type WRKSBMJOB and then put a 6 beside the job to be
released and press enter, or, if the job queue was put on hold, release the job queue with the RLSJOBQ
command.
6.
A display appears when the job is ready to start, saying that you can now begin
debugging the job. Press F10 to show the Command Entry display.
7.
Now you can start debugging by entering an Add Break Point command: ADDBKP
Some Max values
Description Maximum Value
Number of bytes in a record
32,766 bytes
Number of fields in a record format
8,000 fields
Number of key fields in a file
120 fields
Size of key for physical and logical files
2000 characters 1
Size of key for ORDER BY (SQL) and
KEYFLD (OPNQRYF)
10,000 bytes
Number of records contained in a file member
2,147,483,646 records 2
Number of bytes in a file member
266,757,734,400 bytes 3
Number of bytes in an access path
1,099,511,627,776 bytes 3 5
Number of keyed logical files built over a physical file member
3,686 files

- 269 -

Tips n Facts
Number of physical file members in a logical file member
32 members
Size of a character or DBCS field
32,766 bytes 4
Size of a zoned decimal or packed decimal field
31 digits
Maximum number of constraints per physical file
300 constraints
Maximum number of triggers per physical file
6 triggers
Maximum number of recursive insert and update trigger calls
200

http://publib.boulder.ibm.com/html/as400/infocenter.html
Q.1) I'd like to save spool files, and then restore them as spool files?
A.1)

CPYSPLF FILE (&SPLFNAME) TOFILE (QTEMP/Temp) +


JOB (&SPLFJNBR1/&SPLFUSER/&SPLFJOB) +
SPLNBR (&SPLFNBR) CTLCHAR (*FCFC) mbropt (*replace)
You will be able to save the file
this will create a spool file QSYSPRT from saved data
OVRPRTF FILE (QSYSPRT) CTLCHAR (*FCFC) OUTQ (&OUTQ) +
FORMTYPE (COPYPACK) HOLD (*NO) SAVE (*NO) +
USRDTA (DUPLICATE) SPLFNAME (&SPLFNAME)
CPYF

FROMFILE (QTEMP/Temp) TOFILE (QSYSPRT)

Q.2) How to change PF field color, it default showing white?


A.2) U cannot set COLOR attribute to a PF or LF.
(* You can view SQL query result in different colors using hexadecimal values)

Q.3) I have an interesting question for all of u,


I have a requirement in which i need to create 3 logical on one Physical, the key fields in logical will be like
that:
1st logical--->K1, K2, K3
IInd Logical-->K1, K3
IIIrd Logical-->K2, K3
I need to create all the 3 logical and going to use that in my program,
THE QUESTION IS WHICH LOGICAL I WILL CREATE FIRST AND WHY??????
Plz explain in Detail.
A.3) Order: 1st 2nd then Third.
Generating in this sequence will result in creation of ONLY ONE "Active Index". Whereas if you generate in
the reverse order three active indices will be generated.
OS/400 implements logical files by automatically creating "Active Index". There is a seperate active index
for each set of key and static selection maintenance.
It is always good to minimize the number of active indices because an active index causes
extra system overhead.
Compiling in the order mentioned above will lead to sharing of one active index by all the three logical
files. Obviously the number of active indices created depends upon the sequence in which the logical are
created.
Q.4) How to check who is allowed to do FTP in an AS400 machine? Where is the setting?
A.4) you can use Client Access Operations Navigator.

- 270 -

Tips n Facts
choose: (machine) ----- Users and groups - All users choose profile------ right click and choose------Properties---------- Capabilities button------------- Applications tab------------ Host Applications (from
drop-down menu)------------ Tcp/ip utilities for iSeries FTP--------- FTP Server and here is: Logon Server
or Specific Operations.
Q.5) I am writing a RPG progarm .In query ,where i need to write WHERE
condition as follows: WHERE date between 20050301(first day of curr.month) and 200050430 (lastday fo
next month). Can anyone plz tell me how to find last date of current month? and also last date of next
month?
A.5) To find the last date of the current month:
(1)Get the first day of the current month
Extract YY and MM from CurDate, then CurFstD=YY-MM-01
(2)Get the first day of the next month :
NxtFstD = AddDur of 1 Month to CurFstD
(3)The last day of the current month is:
CurLstD = SubDur 1 Day from NxtFstD
the same way to get the Last day of the Next Month
Q.6) How to convert a left aligned string to a right aligned string in RPG/400 or RPG-IV?
A.6) Use EVALR opcode.
Example: *stringL: left aligned
*stringR: right aligned
C
EVALR
stringR=%trim (stringL)
Q.7) Can anybody help me how to go about debugging RPG400 pgm using STRDBG?
A.7) Here are two points should be noted:
a.) 1. ) When you compile the program use CRTRPGPGM command, use *SRCDBG/*LSTDBG in
the 'Source list options parameter
2.) STRDBG PGM(yourpgmname) OPMSRC(*YES)
But if you use STRISDB command to debug RPG400 programs, you don't have to specify any parameters
intended.
8.) Does anybody knows the way to get the size of a member of a pf.
----DSPFD FILE(library/pfile) TYPE(*MBRLIST)
9.) consider CL pgm
pgm
call A
call B
call C
call D
endpgm
A & B run successfully & error occured while executing pgm C now I have corrected the error in pgm C
when i run main pgm control should directly goto pgm C skipping pgm A & B How to do it?
i think we can trasfer pgm A & B to data area but how to do it i dont know. can anybody explain?
-------

- 271 -

Tips n Facts

- 272 -

You might also like