what is an as400
TRANSCRIPT
What is an AS400?
The AS/400 (Application System/400) was first introduced by IBM on June 20th, 1988. The AS/400 is a popular family of mid-sized computer systems which can also be used as multiuser computer systems. By this, we mean that a single computer can interact with more than one user at a time.
The AS/400 can be utilized for different business facets. Some models are designed as systems that provide resources to other computers, also known as a "server" in a network of computers, while others are set up for use with terminals or "display stations". OS400 is the operating system for the AS/400. The AS/400 computers offer more compatibility across the product line than the earlier System/3X computers. Hence, the earlier IBM models of the System/36 and System/38 have since been replaced by the AS/400 systems.
IBM has sold over 600,000 AS/400's and over 350,000 of them are still active. From distribution warehouses to hospital administrators, and even manufacturing companies, the AS/400 is a strong component in aiding these companies daily business operations. The AS/400 utilizes a green screen interface, a built in database that resembles DB2, and a vast array of software to provide business solutions for todays business needs.
In October of 2000, IBM rebranded the AS/400 and announced its name as the IBM iSeries 400. In doing this, IBM has shown that it is evolving this mid range family of computers in an attempt to keep in tune with the fast paced demands and changes that the Internet and the e-business world reside in. For the purposes of our tutorial, we will continue to use the term AS400 rather than iSeries, although there is no distinction between the two. As well, since 95% of AS/400's use RPG, we will emphasize using RPG in this tutorial.
To answer the question of "why should you bother to learn to use the AS400", check out some of the job sites on the web, such as computerjobs.com or monster.com, and do a search on AS400 RPG, and see the career possibilities that await you.
Showcase Article - AS/400 Commands
You can run commands directly from any command line. Once you learn the commands, you can write "Control Language" or CL programs. CL programs are simply strings of commands that have been entered and compiled. So as you learn these commands, you are also learning to write CL programs. Managers and administrators who have duties in different environments may have trouble shifting gears from one operating system to another. We're going to look at some easy ways to help you learn and remember these commands.
The AS/400 operating system is consistent in its presentation and names. Commands have names of up to 10 letters. The commands typically take the form of three letters. For example, to work with active jobs, the command is WRKACTJOB. That's a single word with no spaces. WRK is the AS/400 abbreviation for "work" and ACT is the abbreviation for "active." Because the AS/400 is consistent in its naming style, after you know some of the abbreviations, you will be able to guess the names of commands.
In the sidebar are 11 important verbs and nouns that combine to form command names. The abbreviations are not all three letters but they are used consistently throughout the system. "F"
1
is always the abbreviation for file. You won't have to guess if it is sometimes abbreviated as "FIL."
If you don't know the exact name of a command, you can use the AS/400 menus to browse. If you key in GO VERB from a command line and hit Enter, you will go to the AS/400 menu named VERB. This menu lists all AS/400 verbs. From here you can navigate and browse to the exact command you need. Also, to see the major command groups, GO MAJOR.
If you already know the verb, but need the rest of the syntax, there is a menu named after the verb. For example, there is a CMDWRK menu with all "work" commands, there is a CMDDSP menu with all "display" commands and there is a CMDADD menu with all "add" commands. So you can key in GO CMDSTR and see all "start" commands.
To learn more about any command, type in the number of the command and then hit F1. The AS/400 has extensive, friendly help built into every command.
Some innocuous looking commands such as CPYF are deceptively powerful and complex. CPYF can copy a file, renaming it while selecting only records in which the field "STATE" has a value of "DC." In fact, there are six screens of key words you can use. Learning this one command can give the power to clean up a master file by copying only records you wish to keep while bypassing data created by an errant task.
To see a comprehensive list of AS/400 Commands, click here.
-sidebar-
It is important to become familiar with basic AS/400 command abbreviations. The following is a list of the most commonly used verbs and nouns that combine to make commands.
Command Abbreviations--Verbs
ADD - Add
CFG - Configure
CHG - Change
CPY - Copy
CRT - Create
DLT - Delete
DSP - Display
GO - Go to a Menu
RMV - Remove
STR - Start
WRK - Work with
2
Command Abbreviations--Nouns
DEV - Device
DEVD - Device Description
F - Files
FLR - Folder
LIB - Library
OUTQ - Output Queue
MSG - Message
SPLF - Spool File
WTR - Writer (Printer)
Library Lists
The library list on the AS/400 is similar to the "path" on PC's. Mainframe programmers may compare it to the "steplib" or "joblib". It defines the order of libraries that the operating system uses to find objects.
When you execute a command or call a program, the AS/400 must know where to find the command or program. Sometimes, you specify the library explicitly. But if you don't, the AS/400 will find your command or program by looking in each library in your library list. It will use the first one that it finds first.
This is very handy for testing. If you are testing a version of a program, you can put it in a test library which is at the top of your library list. Then, whenever you specify a program or refer to a file, the system will use any object it can find in the test library. If it can't find it there, it will look further through your library list until it finds it.
So, setting up a test environment is as simple as:
1) Create a test library.
2) Put objects that you want to test in the library. These can be files, menus, programs or any AS/400 object.
3) Insert the test library name into your library list, before your production libraries.
Now you can execute test programs and modify test data. The best part is that you don't need to copy production programs or files into the test library unless they will be affected by the test. That is, all those supporting database files that you need to run a program, but that are used for input only, do not need to be copied to the test library. Of course, if you are unsure if a file will be modified during your test procedure, copy it to the test library anyway.
3
Once you have inserted the test library name in your library list, you will want to make sure everything is in the proper order. Use the DSPLIBL command to see your library list. You will probably see three types of list entries:
1) The SYS libraries have operating system objects. This is where the AS/400 commands and menus are contained.
2) The CUR library is your current library. This is your first user library and is where objects are created if you don't specify which library to use.
3) The USR libraries list your other user libraries.
Use EDTLIBL to change your USR libraries. You can rearrange the list, remove libraries or add libraries. Notice that you can't see the SYS or CUR libraries when you use EDTLIBL. The only way to change the current library is with the CHGCURLIB command.
The WRKOBJ command will help see which object is being used. This command is similar to the directory ("dir") command on PC's. Use it to list objects in your library list.
So, if you have three copies of program, "PAYCALC", in different libraries, use the command WRKOBJ PAYCALC to see which copy of "PAYCALC" will be used. The command will list all objects named "PAYCALC" in the sequence that the AS/400 finds them . If you ever say to yourself in frustration, "I know I changed the program but it looks like I'm still running the original program", it's a pretty good bet that you're executing a different copy of the program than you think. This is only a fraction of the power of the WRKOBJ command. It is the easiest way to navigate through an undocumented system.
When you are copying files to your test library, use special care with the logical files. It is easy to create a logical file that resides in a test library but updates a physical file in a different library.
Review of Commands Discussed:
DSPLIBL - Display complete library list
EDTLIBL - Edit library list
CHGCURLIB - Change Current Library
WRKOBJ - Work with objects (similar to PC "dir")
Example of Library List Set Up for Testing:
QSYS SYS System Library
QSYS2 SYS System Library for CPI's
QHLPSYS SYS
QUSRSYS SYS
4
TESTFILES CUR Library for Test Files
TESTPGMS USR Library for Test Programs
GLFILES USR Library for Production G/L Files
GLPGMS USR Library for Production G/L Programs
PRPGMS USR Library for Production P/R Programs
PRFILES USR Library for Production P/R Files
TAATOOL USR Library for User Tools
QGPL USR General Purpose Library
QTEMP USR
PDM or How to Enter Programs
Before you work on this topic, there is an important option to change. From the command line, key in the command STRPDM and hit ENTER. Then, key in 1 and hit ENTER. Then hit ENTER again. Your screen should look like:
-------------------------------------------------------------------
Work with Libraries Using PDM
List type . . . . . . . *LIBL
Type options, press Enter.
2=Change 3=Copy 5=Display
8=Display description 9=Save 10=Restore
Opt Library Type Text
QSYS *PROD-SYS System Library
QHLPSYS *PROD-SYS
QUSRSYS *PROD-SYS
QPDA *PROD-PRD
QADM *PROD-PRD
5
QTEMP *TEST-USR
QGDDM *PROD-USR
QGPL *PROD-USR
--------------------------------------------------------------------
Now, hold down the SHIFT key and hit F6. You should now see:
---------------------------------------------------------------------
Change Defaults
Type choices, press Enter.
Object library . . . . . . . *SRCLIB Name, *CURLIB,
Replace object . . . . . . . N Y=Yes, N=No
Compile in batch . . . . . . Y Y=Yes, N=No
Run in batch . . . . . . . . N Y=Yes, N=No
Save session defaults . . . Y Y=Yes, N=No
Save/Restore option . . . . 1 1=Single, 2=All
Job description . . . . . . QBATCH Name, *USRPRF,
Library . . . . . . . . . *LIBL Name, *CURLIB,
Change type and text . . . . Y Y=Yes, N=No
Option file . . . . . . . . QAUOOPT Name
Library . . . . . . . . . QGPL Name, *CURLIB,
Member . . . . . . . . . . . QAUOOPT Name
Full screen mode . . . . . . N Y=Yes, N=No
Scan hierarchy . . . . . . . Y Y=Yes, N=No
Search path . . . . . . . . *DFT Name, *DFT
Build scope . . . . . . . . 1 1=Normal, 2=Lim
4=Direct Chain
--------------------------------------------------------------------
6
Hit TAB until the cursor is on the "Compile in batch" line. Change the value from Y to N and hit ENTER.
Okay, now you are ready for the PDM topic.
Programs are created from source statements. On the AS/400, source statements are entered using PDM, the Program Development manager. Technically, PDM uses the Source Entry Utility (SEU) as the editor. But you don't have to think of SEU as something different from PDM.
PDM provides a way to enter program source statements and then to compile the statements into executable programs. The source statements are needed only for the compiler. The compiled programs are the objects that are actually run on the AS/400. The source code and the compiled objects are separate things. But it is easy to confuse the two. At times, you may try to open the compiled object with PDM when you really mean to open the source code used to create the compiled object.
Source code is kept in a member of a file. The file is kept in a library. Each file can have many members. Each member is the source code for a program.
The source code files can have any name but conventionally the names start with Q and end with SRC, for source. Typically:
QCLSRC is the file for the CL program source statementsQDDSSRC is for the DDS program source statementsQRPGSRC is for the old RPG languageQRPGLESRC is for the new RPG/ILE languageQMNUSRC or QMENUSRC is for menusQCBLSRC or QLBLSRC is for COBOLQCMDSRC is for commands
You could keep most of the source statements is a single file. That is, one member could have CL source statements and another member could have DDS and another could have RPG source statements. Conventionally though, source code is not mixed up like that.
So, let's try it out by writing a simple CL program to change the "Current Library" to your library and to go to the programmer menu. CL is the Control Language of the AS/400. This is a lesson in PDM so don't fret too much about the specifics of CL.
When you got your user ID on this system, a library was also created for you with the same name as your user ID. Suppose that your ID is USER999. That means you have a library available to you named USER999. Some people relate an AS/400 library to a Directory or Folder on a PC.
Your library is probably empty. Since this is the first CL program ever written in your library, you need to create a file to store the CL source statements in.
On the command line, type in:
CRTSRCPF and then hit F4. (F4 always invokes the prompts)
From the earlier lesson in commands, you should remember that commands usually are made up of 3 letter abbreviations of verbs and such. In the case, the command CRTSRCPF stands for Create Source Physical File. That's not exactly intuitive but it's not too hard to remember.
For the library name, key in your library name, similar to USER999. For the Object (or File) name, key in QCLSRC. Now hit ENTER and you've created a source physical file named QCLSRC in the library
7
named USER999. Remember that QCLSRC is not a magic or reserved name. But almost everyone uses this name for their CL source.
Once you use commands for a while, you will learn how to enter simple commands without the prompts. In this case:
CRTSRCPF USER999/QCLSRC
So now you have a place to store your CL source statements. Lets start PDM and try to enter the simple program. PDM can be started from the programmer menu or with the Start PDM command. Most programmers use the Start PDM command. Type in STRPDM and hit ENTER.
Your screen should look something like:
------------------------------------------------------------------------
AS/400 Programming Development Manager (PDM)
Select one of the following:
1. Work with libraries
2. Work with objects
3. Work with members
4. Work with projects
5. Work with groups
6. Work with parts
9. Work with user-defined options
Selection or command
-----------------------------------------------------------------------
8
Now for the most confusing part of PDM… And it's not that confusing. PDM will let you navigate to your source statements 3 different ways. Let's try to draw a picture of the organization of the source statements.
Suppose you have 2 libraries. One for General Ledger programs and one for Payroll. Each one has CL, DDS and RPG programs. A schematic of this is:
Library Object or File Member or Program name
GLLIB QCLSRC GLC001
GLC003
GLC007
QRPGSRC GLR001
GLR002
GLR005
QDDSSRC GLD001
PRLIB QCLSRC PRC100
PRC101
PRC125AB
QRPGSRC PRR100
PRR125
QDDSSRC PRD105
PRD107
PRD108
The analogy on a PC is that you have two Folders in the root; one is GLLIB and the other is PRLIB. Each of those folders has three folders: QCLSRC, QRPGSRC and QDDSSRC. Each of those folders has a few documents, each one with the source statements for the program.
The schematic of your library right now is:
Library Object or File Member or Program name
9
USER99 QCLSRC
That is, you have one file in your library and that file has no members.
I prefer to navigate to my source code using selection 3 (Work with members). So, key in 3 and hit ENTER.
Your screen now looks like:
------------------------------------------------------------------------
Specify Members to Work With
Type choices, press Enter.
File . . . . . . . . . . QCLSRC Name, F4 for list
Library . . . . . . . . USER999 *LIBL, *CURLIB, name
Member:
Name . . . . . . . . . *ALL *ALL, name, *generic*
Type . . . . . . . . . *ALL *ALL, type, *generic*
------------------------------------------------------------------------
Key in the File name of QCLSRC and the library name like USER999. Finally for member name key in *ALL.
This is a little like saying on a PC, "Show me all the documents in the folder QCLSRC which is in the folder USER999".
The AS/400 now shows you the "WORK WITH MEMBERS WITH PDM" display and all of the members in QCLSRC. But since QCLSRC has no members it shows "NO MEMBERS IN FILE".
About ¼ from the top, the AS/400 tells you what options you can use in PDM. For example, 2 is to edit or change a member, 3 is to copy a member, 4 to delete a member. If you hit F23, the AS/400 will display more options. Your keyboard has only 12 "F" keys at the top. If you hold down the shift key when you hit an "F" key, it adds 12 to the "F" number. So, if you hold down shift and hit F11, this is the F23 key. When you do this, the AS/400 shows other option numbers.
Similarly, at the bottom, the AS/400 tells you what "F" keys you can use. Hitting F24 (shift while hitting F12) will cause the AS/400 to display more "F" keys. These "F" keys are called FUNCTION KEYS.
So, finally.. Let's add a member and write a simple Control Language program.
10
At the bottom-right of your screen you should see that F6=Create. This means that hitting F6 will let you create a new member. So, hit F6.
The screen will now show:
------------------------------------------------------------------------
Start Source Entry Utility (STRSEU)
Type choices, press Enter.
Source file . . . . . . . . . . > QCLSRC Name, *PRV
Library . . . . . . . . . . . > USER999 Name, *LIBL, *CURLIB, *PRV
Source member . . . . . . . . . FIRSTCL Name, *PRV, *SELECT
Source type . . . . . . . . . . CLP Name, *SAME, BAS, BASP...
Text 'description' . . . . . . . My First CL Program
------------------------------------------------------------------------
Fill in the Source member name. This will become the program name. Name it FIRSTCL.
The Source type is important. It will tell the AS/400 what compiler to use to compile the source code. CL programs are designated as Source type CLP. So, enter CLP.
For the text description, enter a short description.
Now hit ENTER and the screen should look like:
-----------------------------------------------------------------------
Columns . . . : 1 71 Edit USER001/QCLSRC
SEU==> FIRSTCL
FMT ** ...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7
*************** Beginning of data*************************
'''''''
'''''''
'''''''
11
'''''''
'''''''
'''''''
'''''''
'''''''
'''''''
'''''''
'''''''
'''''''
-----------------------------------------------------------------------
You now have an empty member to key source code into. If you were to hit ENTER right now, the editor (SEU) would assume that you don't want to keep any of these lines since you haven't entered anything on them.
So, to make things simple, key a space on the top line, then TAB twice to the next line and key another space. Do this on about 10 lines.
Now, when you hit ENTER, SEU sees that you keyed something (a space) on those lines and it keeps them for you.
If you did this, SEU replaced the dots on the left with numbers and should look like:
------------------------------------------------------------------------
Columns . . . : 1 71 Edit USER001/QCLSRC
SEU==> FIRSTCL
FMT ** ...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7
*************** Beginning of data**************************
0001.00
0002.00
0003.00
0004.00
0005.00
0006.00
0007.00
12
0008.00
0009.00
-----------------------------------------------------------------------
Languages have syntax rules to follow. CL is mostly a free format syntax. Blank lines are allowed and commands can be placed in any column. Also, CL programs must begin with a PGM statement.
So, key PGM on the first line and hit ENTER. Your screen should now look like:
------------------------------------------------------------------------
Columns . . . : 1 71 Edit USER001/QCLSRC
SEU==> FIRSTCL
FMT ** ...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7
*************** Beginning of data**************************
0001.00 PGM
0002.00
0003.00
0004.00
0005.00
0006.00
0007.00
0008.00
0009.00
-----------------------------------------------------------------------
Now, it's time to experiment a bit with the line editor. SEU (the name of the editor being used by PDM) is a line editor. That just means that commands to copy, insert and delete lines are entered in the left portion of the screen where the numbers are.
Try a simple line command. Key in D right on top of the number 0001.00 at the top left. your screen should look like:
------------------------------------------------------------------------
Columns . . . : 1 71 Edit USER001/QCLSRC
SEU==> FIRSTCL
13
FMT ** ...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7
*************** Beginning of data**************************
D001.00 PGM
0002.00
0003.00
0004.00
0005.00
0006.00
0007.00
0008.00
0009.00
-----------------------------------------------------------------------
This D tells the editor to delete this line when the ENTER key is hit. So, go ahead and hit ENTER and watch that line disappear.
Now key the PGM back in on another line.
Just to experiment, copy line 0001 and insert it after line 0005. Do this by keying a C (for "copy") on line 0001 and an A (for "after") on line 0005.
Your screen should look like:
------------------------------------------------------------------------
Columns . . . : 1 71 Edit USER001/QCLSRC
SEU==> FIRSTCL
FMT ** ...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7
*************** Beginning of data**************************
C001.00 PGM
0002.00
0003.00
0004.00
A005.00
0006.00
14
0007.00
0008.00
0009.00
-----------------------------------------------------------------------
When you hit ENTER, SEU will copy line 1 and place it on a new line after line 5.
If you key C3 on line 0001, SEU will copy three lines and place them after the line with an A.
Or, if you key CC on line 0001 and CC on line 0004, SEU will copy from line 0001 thru 0004.
Similarly, putting DD on line 0001 and DD on line 2000 would delete all lines from line 1 to line 2000.
Okay, let's finish the program. The complete program will do only two things. The first is that it will change your "CURRENT LIBRARY" to your library USER999 and the second thing is it will go to the Program menu on the AS/400.
Since this isn't a lesson in CL programming, trust me and key in the following program. Be sure to use your USERID in place of USER999.
------------------------------------------------------------------------
Columns . . . : 1 71 Edit USER001/QCLSRC
SEU==> FIRSTCL
FMT ** ...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7
*************** Beginning of data**************************
0001.00 PGM
0002.00
0003.00 CHGCURLIB USER999
0004.00
0005.00 GO PROGRAM
0006.00
0007.00
0008.00
0009.00
-----------------------------------------------------------------------
Now hit F3 to tell PDM that you are done. Hit ENTER to accept the values on the screen. PDM has saved your program and you can now see it in your PDM list of members.
15
The screen should now show:
---------------------------------------------------------------------
Work with Members Using PDM
File . . . . . . QCLSRC
Library . . . . USER999 Position to . . . . .
Type options, press Enter.
2=Edit 3=Copy 4=Delete 5=Display 6=Print 7=Rename
8=Display description 9=Save 13=Change text 14=Compile 15=Create
Opt Member Type Text
FIRSTCL CLP My First Cl Program
---------------------------------------------------------------------
So, you have now entered the statements needed by the AS/400 compiler to compile a CL program. Each time you add a member, this list of members will grow. Just for fun, key a 2 next to FIRSTCL under OPT on the screen. Hit ENTER and PDM will open the source file up again so you can see and change it. Hit F3 and ENTER to get back.
To compile the program, key 14 under OPT next to FIRSTCL and hit enter. This tells PDM to compile the statements that are in the member named FIRSTCL.
If all went well, in a few seconds, the AS/400 will have compiled your program. Hit TAB to get to the bottom of the screen. This is the command line.
Key CALL USER999/FIRSTCL on the command line (be sure to use your USERID in place of USER999). If your program compiled, you should now see:
-----------------------------------------------------------------------
PROGRAM Programming
Select one of the following:
16
1. Programmer menu
2. Programming Development Manager (PDM)
3. Utilities
4. Programming language debug
5. Structured Query Language (SQL) pre-compiler
6. Question and answer
8. Copy screen image
9. Cross System Product/Application Execution (CSP/AE)
50. System/36 programming
70. Related commands
Selection or command
-----------------------------------------------------------------------
That's the end of this lesson. Try not to be frustrated with the lack of user friendliness of PDM. The wonderful news is that 99% of AS/400's use PDM. So anytime you log on to an AS/400, you will be familiar with the source code editor.
It takes most people a week or so of using PDM to get comfortable with it. But you must learn PDM well. You will use it to create files, logical files (indexes), display screens, print files, RPG programs, CL programs and more.
Take a break and review the following link to IBM's publication site.
Finally, e-mail me and tell me how your first hands-on experience went.
Thanks,
Additional Material
Here is the link to IBM's Online Manuals
17
http://publib.boulder.ibm.com/pubs/html/as400/online/v4r2eng.htm
Click on "SEARCH OR VIEW ALL BOOKS"Key in SEU and click on FIND.It should find the book titled "Source Entry Utility". Chapter 13 is a tutorial on entering source code.
Library Lists and Copy File
More on Library List (LIBL) and Copy File (CPYF)
If you have read through the topics you are probably getting a bit bored. It's time to jump in and start trying things out.
First, it is important to learn a bit more about your library list. I hope you read the earlier topic on LIBRARY LISTS and understood some of it. Sign on to the AS/400, and from a command line, key in DSPLIBL and hit ENTER.
Your LIBRARY LIST should look like:
Opt Library Type Text
QSYS SYS System Library
QHLPSYS SYS
QUSRSYS SYS
QTEMP USR
QGDDM USR
QGPL USR
This simply means that whenever you key in a command, call a program or go to a menu, the AS/400 will look for what it needs in those libraries and in that sequence.
In fact, when you keyed in the command DSPLIBL, the AS/400 looked for it in the first library, QSYS. Not by accident, that is the library that has all of the AS/400 commands. So, the AS/400 executed the command DSPLIBL that it found in the library QSYS.
Since we will do a lot of things in your personal library, it will make things easier if your library is in the library list. For now, the best way to do this is to make your personal library the CURRENT LIBRARY. The CURRENT LIBRARY is a slightly special designation. The CURRENT LIBRARY is the first user library. Also, if you create files and don't tell the AS/400 where to put them, it will put them in the CURRENT LIBRARY.
Key in the command to change the CURRENT LIBRARY to your personal library. The command is Change Current Library. This is an excellent example of the way the AS/400 usually makes the command name from the 3 letter abbreviations. The command is CHGCURLIB. So, key in:
CHGCURLIB USER999
18
Of course, replace USER999 with your user ID. When I set up your user ID, I created a library with the same name as your user ID. So, don't get confused and think that this command changes the current library to your user ID. It is changing your current library to a library that happens to be named the same as your ID.
Now display your library list again. You remember, DSPLIBL.
Your library list now looks like:
Opt Library Type Text
QSYS SYS System Library
QHLPSYS SYS
QUSRSYS SYS
USER999 CUR
QTEMP USR
QGDDM USR
QGPL USR
Now let's have some real fun. There is a file in library USER000 named CUST. It has a little over 1,000 records in it. Some people think of a record like a line on a spreadsheet.
We will need some data for a query we will write in a minute. So, let's copy this file to your personal library. In doing this, we will learn about AS/400 commands, the very powerful COPY FILE command and a few other commands as well.
The command to copy the CUST file from the library USER000 to your personal library, USER999 is pretty scary looking. It is:
CPYF FROMFILE(USER000/CUST) TOFILE(USER999/CUST) CRTFILE(*YES)
Memorizing the keywords and options would be impossible. Fortunately, it's not that hard. Let's see how the AS/400 makes it easy to use complex commands.
First, you must remember the command name. This command, CPYF (COPY FILE) is a common command. But if you need help remembering it you could try going to one of the menus that lists the commands.
If you remember that COPY is abbreviated CPY, you could key in:
GO CMDCPY
You would see a list of commands and number 6 is CPYF.
Or, you could key in:
19
GO MAJOR
You would see a list of the major groups of commands. Since you see "more" in the lower right hand of the screen, you know that you can hit the PAGE-DOWN key to see more. You don't need to though since you can see that selection 5 will show you the FILE COMMANDS. you will find CPYF on that list. Or you could have selected 2 for VERB COMMANDS and found the COPY COMMANDS as #18 on that list.
Are you started to get the idea? This menu (most of them start with CMD) show you all of the commands on the system.
Remember, we were looking for the command to copy a file. It is CPYF. So, let's see how to use a command now that we know its name.
Key in the command on the command line but don't hit ENTER. Instead, hit F4. The AS/400 understands that F4 means that you want to see the options and the prompts for the options.
So, key in CPYF and hit F4. You should see:
Copy File (CPYF)
Type choices, press Enter.
From file . . . . . . . . . . . Name
Library . . . . . . . . . . . *LIBL Name, *LIBL, *CURLIB
To file . . . . . . . . . . . . Name, *PRINT
Library . . . . . . . . . . . *LIBL Name, *LIBL, *CURLIB
From member . . . . . . . . . . *FIRST Name, generic*, *FIRST, *ALL
To member or label . . . . . . . *FIRST Name, *FIRST, *FROMMBR
Replace or add records . . . . . *NONE *NONE, *ADD, *REPLACE...
Create file . . . . . . . . . . *NO *NO, *YES
Print format . . . . . . . . . . *CHAR *CHAR, *HEX
20
Bottom
F3=Exit F4=Prompt F5=Refresh F10=Additional parameters F12=Cancel
F13=How to use this display F24=More keys
With just a little experimentation, you will learn that the critical values on this screen are:
FROM FILE which we want to be CUSTLibrary for FROM FILE which we want to be USER000TO FILE which we want to be CUSTLibrary for TO FILE which should be your personal libraryCREATE FILE which needs to be *YES
So your screen should look like:
From file . . . . . . . . . . . > CUST Name
Library . . . . . . . . . . . > USER000 Name, *LIBL, *CURLIB
To file . . . . . . . . . . . . > CUST Name, *PRINT
Library . . . . . . . . . . . > USER999 Name, *LIBL, *CURLIB
From member . . . . . . . . . . *FIRST Name, generic*, *FIRST, *ALL
To member or label . . . . . . . *FIRST Name, *FIRST, *FROMMBR
Replace or add records . . . . . *NONE *NONE, *ADD, *REPLACE...
Create file . . . . . . . . . . > *YES *NO, *YES
Print format . . . . . . . . . . *CHAR *CHAR, *HEX
Of course, replace USER999 with yuour personal library name. Hit ENTER now and see how quickly these 1000 records are copied into a file in your personal library.
You now have a file named CUST in your personal library and it has over 1000 records of data in it.
Now, you can learn some important things about the way commands work. You can hit F9 to RETRIEVE the last command executed. This is a handy shortcut. But it also shows exactly what command was executed and what the options were. So hit F9 and you will see:
CPYF FROMFILE(USER000/CUST) TOFILE(USER999/CUST) CRTFILE(*YES)
For simple commands, the keywords (FROMFILE, TOFILE and CRTFILE) are not needed. That is, if you key in all the right options in the right order, you may leave out the keywords. For a command as complicated as CPYF, that is almost impossible. Most commands are simpler though.
21
To see the data in the file, you might expect to use a command DSPF for display file. As it turns out the command is actually, DISPLAY PHYSICAL FILE MEMBER and is named DSPPFM.
Now that you know the name of the command, you know that you can key DSPPFM and hit F4 to see the keywords and options. If you do, you'll see:
Display Physical File Member (DSPPFM)
Type choices, press Enter.
File . . . . . . . . . . . . . . Name
Library . . . . . . . . . . . *LIBL Name, *LIBL, *CURLIB
Member . . . . . . . . . . . . . *FIRST Name, *FIRST, *LAST
From record . . . . . . . . . . 1 Number, *END, *ALLDATA
That's not too bad. The only options are the name of the file, the library the file is in, the member (we'll discuss this in another topic) and the first record number.
Notice that most of the default values are filled in with the value that you probably want. For example, the FROM RECORD# is already set to 1.
So all you really need to fill in is the FILE NAME of CUST and the LIBRARY name where the FILE is located. In fact, it's even simpler than that. The default value for the LIBRARY is *LIBL. This means that the command will look for the FILE in the LIBRARY LIST. And since your personal library is the CURRENT LIBRARY, all you need to enter is the file name.
So if you fill in the FILE name as CUST and hit ENTER, you should see a screen full of customer name and address data:
001002E LUMPKIN 123 MAIN STREET ANYTOWN
001084CHISOLM 123 MAIN STREET ANYTOWN
001105HAGGINS 123 MAIN STREET ANYTOWN
001109BYRD 123 MAIN STREET ANYTOWN
001168ROMERO 123 MAIN STREET ANYTOWN
001177POUNDS 123 MAIN STREET ANYTOWN
001183HINTON 123 MAIN STREET ANYTOWN
001184YANCEY 123 MAIN STREET ANYTOWN
001186MCDOUGLE 123 MAIN STREET ANYTOWN
22
001202DAVIS 123 MAIN STREET ANYTOWN
001208TARVIN 123 MAIN STREET ANYTOWN
001214GOOSEBERRY 123 MAIN STREET ANYTOWN
001234REID 123 MAIN STREET ANYTOWN
001239COLBERT 123 MAIN STREET ANYTOWN
001259BLACKMON 123 MAIN STREET ANYTOWN
Now to keep learning about how commands are executed, hit F9 to see the command that you just ran. It is:
DSPPFM FILE(CUST)
What happened is that the AS/400 followed a line of logic like this:
I'm supposed to run the command DSPPFM so first I need to find the command in one of the libraries in the library list. The first library in the library list is QSYS and it has a command named DSPPFM so I'll run that.
Next, I need to find a file named CUST. There is no CUST file in the first library QSYS. There isn't a CUST file in QHLPSYS or QUSRSYS either. There isn't a CUST file in QPDA or QADM. There is a CUST file in USER999, which happens to be the CURRENT LIBRARY. So, I'll run the command DSPPFM that I found in the library QSYS and I'll display the file CUST that I found in USER999.
Like many commands, this one is so simply that you don't need to prompt the keywords. You could just key in:
DSPPFM CUST
By the way, you could display the original CUST file that you copied from USER000. Key in DSPPFM , hit F4 and fill in the file name of CUST and the library name of USER000.
The shortcut form of that command is:
DSPPFM USER000/CUST
Just for fun, delete the file you copied and then copy it again.
To delete the file, use the command DELETE FILE, which is DLTF. So if you key in:
DLTF CUST
or
DLTF USER999/CUST
and hit ENTER and you will delete your CUST file.
Now, use the CPYF command to copy it again from the USER000 library. Or, if you are efficient, hit F9 a few times until your CPYF command is retrieved and then hit ENTER and run it again.
23
The data displayed with the DSPPFM command is unformatted. That is, it is just a string of letters and numbers. Try the command:
RUNQRY QRYFILE(CUST)
This command is a tiny part of the QUERY/400 programming language. It displays the file but separates the data into fields with headings. It should look like:
Position to line . . . . . Shift to column . . . . . .
Line ....+....1....+....2....+....3....+....4....+....5....+....6....+....7.
CSNBR CSNAME CSADR1
000001 1,002 E LUMPKIN 123 MAIN STREET
000002 1,084 CHISOLM 123 MAIN STREET
000003 1,105 HAGGINS 123 MAIN STREET
000004 1,109 BYRD 123 MAIN STREET
000005 1,168 ROMERO 123 MAIN STREET
000006 1,177 POUNDS 123 MAIN STREET
000007 1,183 HINTON 123 MAIN STREET
000008 1,184 YANCEY 123 MAIN STREET
000009 1,186 MCDOUGLE 123 MAIN STREET
000010 1,202 DAVIS 123 MAIN STREET
000011 1,208 TARVIN 123 MAIN STREET
000012 1,214 GOOSEBERRY 123 MAIN STREET
000013 1,234 REID 123 MAIN STREET
000014 1,239 COLBERT 123 MAIN STREET
000015 1,259 BLACKMON 123 MAIN STREET
000016 1,264 CRANFORD 123 MAIN STREET
You can see from the prompts at the bottom of the screen that you can shift the data to see more by hitting F20. F20 is SHIFT and F8. F19 will shift back.
I hope you're having fun and starting to see the power of the AS/400.
Notice when you shift to the right by hitting SHIFT and F20 that the field name for the STATE is CSSTE.
For the last lesson in executing commands, let's copy the original file but select only customers from Texas (where else?). We know that the field that has the state is CSSTE.
24
First, delete the file you copied:
DLTF CUST
Now, key in the CPYF command and hit F4. As before fill in the file names and library names and the create file option.
Notice that at the bottom, F10 will show ADDITIONAL PARAMETERS. If you hit F10, you will see "more…' at the bottom right of the screen. This means that you can hit the PAGE DOWN key to see more options.
The CPYF command has many, many options. If you hit PAGE DOWN 4 times, you will see:
Copy File (CPYF)
Type choices, press Enter.
Include records by field test:
Relationship . . . . . . . . . *NONE *NONE, *IF, *AND, *OR
Field . . . . . . . . . . . . Name
Relational operator . . . . . *EQ, *GT, *LT, *NE, *GE...
Value . . . . . . . . . . . .
+ for more values
Record format field mapping . . *NONE *NONE, *NOCHK, *CVTSRC...
Source update options . . . . . *SAME *SAME, *SEQNBR, *DATE
Source sequence numbering:
Starting sequence number . . . 1.00 0.01-9999.99
Increment number . . . . . . . 1.00 0.01-9999.99
More...
25
Here, you can enter selection values. Fill in the top of the screen to look like:
Include records by field test:
Relationship . . . . . . . . . *IF *NONE, *IF, *AND, *OR
Field . . . . . . . . . . . . CSSTE Name
Relational operator . . . . . *EQ *EQ, *GT, *LT, *NE, *GE...
Value . . . . . . . . . . . . 'TX'
These values say, "copy only records in which the field CSSTE is equal to "TX""
Now if you hit enter, you will copy CUST from library USER000 to USER999 but it will copy only customers from Texas.
When you have run this command, re-run the RUN QUERY command to see the data:
RUNQRY QRYFILE(CUST)
You should see only data for customers in Texas.
That's it for now. Experiment with your new knowledge. Use CPYF to copy your file. Use DLTF to delete it. Use DSPPFM and RUNQRY to look at the data.
I hope you're looking forward to the next topic. I am.
Writing Queries and Looking at Print Output
Most AS/400's have the IBM provided query language QUERY/400. If is an easy to use and powerful tool for viewing and printing data. Here, we will write a query to see some of the data in your CUST file. Then, we'll copy it and change it to create a printed report. Then, we'll learn how to view printed reports. Finally, I'll have a few comments on how you could actually print reports on your laser printer (don't get too excited though, its expensive).
Make sure you have read through the earlier topic "Library Lists and Copy File". In that topic you should have copied a file named CUST to your user library. From here on, whenever you see USER999 be sure to substitute your user library.
There are several ways to get to the Query programming screen. My favorite is with the command WRKQRY. After keying in WRKQRY and hitting ENTER you should see:
----------------------------------------------------------------
Work with Queries
Type choices, press Enter.
26
Option . . . . . . 1=Create, 2=Change, 3=Copy, 4=Delete
5=Display, 6=Print
8=Run in batch, 9=Run
Query . . . . . . . Name, F4 for list
Library . . . . . Name, *LIBL, F4 for list
-----------------------------------------------------------------
This interface is easy to use but is different from PDM. One of the unexpected things is that you can write a query without ever naming it. Of course, you must name it if you wish to save it.
We are going to write a query to view the data in the CUST file. Key in 1 for the option to create a query. We'll name it later so for now just hit ENTER.
You should see:
-----------------------------------------------------------------
Define the Query
Query . . . . . . : Option . . . . . : CREATE
Library . . . . : ZET CCSID . . . . . . : 65535
Type options, press Enter. Press F21 to select all.
1=Select
Opt Query Definition Option
1 Specify file selections
Define result fields
Select and sequence fields
Select records
Select sort fields
Select collating sequence
Specify report column formatting
27
Select report summary functions
Define report breaks
Select output type and output form
Specify processing options
-----------------------------------------------------------------
If you have ever worked with a database query product (like Microsoft's Access) this will have a familiarity to it. Microsoft Access needs about the same information as the AS/400. It just presents the options in a way that you point and click. With QUERY/400, you must view lists and select by keying in "1" next to each item.
The essential things that a query needs to know are:
what file(s) are you displaying or printing?
which fields are you interested in?
how should the data be presented (titles, sequence of data)?
do you want to sort or order the data?
do you want to calculate break totals?
do you want to see details or summary?
The most important question is "what file are you displaying?" This is so important that the AS/400 has already put a "1" next to "Specify file selections". SO, just hit ENTER and you will see:
--------------------------------------------------------------
Specify File Selections
Type choices, press Enter. Press F9 to specify an additional
file selection.
File . . . . . . . . . Name, F4 for list
Library . . . . . . Name, *LIBL, F4 for list
Member . . . . . . . . *FIRST Name, *FIRST, F4 for list
Format . . . . . . . . *FIRST Name, *FIRST, F4 for list
---------------------------------------------------------------
28
You are simply specifying which file you want to query. Enter CUST and the file and USER999 as the Library and hit ENTER. Hit ENTER again and you go back to the previous screen.
Now, select fields you want to see. Do this by keying "1" next to "Select and Sequence Fields". Use either the TAB key or the "down-arrow" to get to that line and key in "1" and hit ENTER.
You should now see:
----------------------------------------------------------------
Select and Sequence Fields
Type sequence number (0-9999) for the names of up to 500 fields to appear in the report,
press Enter.
Seq Field Text
CSNBR CUST NUMBER
CSNAME CUST NAME
CSADR1 ADDRESS LINE 1
CSCTY CITY
CSSTE STATE
CSZIP 9 DIGIT ZIP
CSDLOR DATE OF LAST ORDER
CSDLPM DATE OF LAST PMT
CS#OPN # OF OPEN ORDERS
CS$OPN AMT OF OPEN ORDERS
----------------------------------------------------------------
Since the AS/400 knows the file you want to see, it has retrieved the fields in the file and listed them for you. If there were more fields, you would see the now familiar "more..." at the bottom right. "more..." tells you that if you use the PAGE-DOWN key you will see more.
Lets make a display that shows the following columns:cust namecust numbercust adr1
29
cust citycust statecust zip
So, key in a sequence number next to each field. Key 2 next to CSNBR, 1 next to CSNAME, 3 next to CSADR1, 4 next to CSCTY, 5 next to CSSTE and 6 next to CSZIP. Then hit ENTER twice and you'll be back at the main screen.
One of the great things with QUERY/400 is that you can work on query, then view it, then change it, view it again and change it until it is what you want.
F5 says that F5=Report. Maybe it should say F5=Run. If you hit F5 the query will run. It should look like:
---------------------------------------------------------------
Display Report
Report width . . . . . : 115
Position to line . . . . . Shift to column . . .
....1....+....2....+....3....+....4....+....5....+....6....+....7
CSNAME CSNBR CSADR1
000001 E LUMPKIN 1,002 123 MAIN STREET
000002 CHISOLM 1,084 123 MAIN STREET
000003 HAGGINS 1,105 123 MAIN STREET
000004 BYRD 1,109 123 MAIN STREET
000005 ROMERO 1,168 123 MAIN STREET
000006 POUNDS 1,177 123 MAIN STREET
000007 HINTON 1,183 123 MAIN STREET
000008 YANCEY 1,184 123 MAIN STREET
000009 MCDOUGLE 1,186 123 MAIN STREET
-----------------------------------------------------------------
Just like that you have written a query to display data from an AS/400 database file. Notice a few things about the query display: it says "more..." so you can hit PAGE DOWN to go down a page. At the top is an area to position to any line. You could key in 50 and hit ENTER and the query would advance to line 50. You can also enter "B" (for bottom) and hit enter to go to the bottom or "T" to get back to the top.
Notice the F-KEY prompts at the bottom of the screen. If you hit F20 (Shift F8) you will scroll to the right. F19 (Shift F7) scrolls back to the left. You can even split the screen with F21 (Shift F9).
30
Once you have played around with that for a while, hit F12 (cancel) to get back to the main screen.
Now change the titles of the rows to be description. Do this by keying "1" next to Column Formatting. Key in more descriptive columns like Name, Customer#, etc.. You can use all three lines for the column heading.
Anytime you want, hit F5 to see the data.
You might revisit the "Select and Sequence Fields" selection to add a field or move fields around.
If in the process of working on the query you hit F3 at the wrong time, you will see the EXIT screen which looks like:
-------------------------------------------------------
Exit this Query
Type choices, press Enter.
Save definition . . . Y Y=Yes, N=No
Run option . . . . . . 3 1=Run interactively
2=Run in batch
3=Do not run
For a saved definition:
Query . . . . . . . Name
Library . . . . . ZET Name, F4 for list
Text . . . . . . . .
Authority . . . . . *LIBCRTAUT *LIBCRTAUT
*CHANGE, *ALL, *EXCLUDE
----------------------------------------------------------
You can hit F12 to get back to your query. Boy that wasn't very obvious was it?
31
Now key "1" next to "Select Sort Fields". Key a "1" next to CSNAME and hit ENTER. Now hit F5 and your query will sort the data by name when it displays.
Notice that this is real-world data. Some of the names start with a space and are therefore sorted to the beginning.
Finally, key a "1" next to select records. Lets select only the records for accounts that live in "TX". Fill in the screen to look like:
----------------------------------------------------------
Select Records
Type comparisons, press Enter. Specify OR to start each new
Tests: EQ, NE, LE, GE, LT, GT, RANGE, LIST, LIKE, IS, ISN
AND/OR Field Test Value (Field, Number, 'Char
CSSTE EQ 'TX'
----------------------------------------------------------
Now when you hit F5 you will see only accounts in Texas and in sequence by name.
You can also create totals of columns and break totals. You can specify if you want details (like this) or summary only.
For now, quit and save this query. Hit F3 and fill in the screen to save the query as CSQ001.
-------------------------------------------------------------
Exit this Query
Type choices, press Enter.
Save definition . . . Y Y=Yes, N=No
Run option . . . . . . 3 1=Run interactively
2=Run in batch
32
3=Do not run
For a saved definition:
Query . . . . . . . CSQ001 Name
Library . . . . . USER999 Name, F4 for list
Text . . . . . . . . Display CUST File
---------------------------------------------------------------
Now, from a command line, key in the command to run a query:
RUNQRY USER999/CSQ001
Your query should display what you saw earlier when you hit F5.
So, that was pretty incredible. In just a few minutes, you wrote and saved it so that it can be run from the command line. Next topic will show you how to put that on a menu.
Now, copy the query and change it to print a report.
To do that, work with queries again (WRKQRY). Then fill in the screen like:
-----------------------------------------------------------------
Work with Queries
Type choices, press Enter.
Option . . . . . . 3 1=Create, 2=Change, 3=Copy
5=Display, 6=Print
8=Run in batch, 9=Run
Query . . . . . . . csq001 Name, F4 for list
Library . . . . . USER999 Name, *LIBL, F4 for list
--------------------------------------------------------------
33
Hit ENTER and you will see the "Copy Queries" screen. Under "To Query" change the query name from CSQ001 to CSQ002 and hit ENTER.
There is now a query named CSQ002 that is identical to CSQ001. Open that query up so you can change it to print. Do this by keying:
--------------------------------------------------------------
Work with Queries
Type choices, press Enter.
Option . . . . . . 2 1=Create, 2=Change
5=Display, 6=Print
8=Run in batch, 9=
Query . . . . . . . CSQ002 Name, F4 for list
Library . . . . . USER999 Name, *LIBL,
---------------------------------------------------------------
Put "1" next to "Select Output Type and Output Form" and hit ENTER.
You should see:
---------------------------------------------------------------
Select Output Type and Output Form
Type choices, press Enter.
Output type . . . . . . . . . . . 1 1=Display
2=Printer
3=Database file
Form of output . . . . . . . . . . 1 1=Detail
34
2=Summary only
Line wrapping . . . . . . . . . . N Y=Yes, N=No
Wrapping width . . . . . . . . . Blank, 1-378
Record on one page . . . . . . . N Y=Yes, N=No
---------------------------------------------------------------
You can see that the AS/400 defaults each query to display detail information without line wrapping. You can experiment with the line wrapping later. For now, change the Output Type form 1 to 2 and hit ENTER.
On the "Define Printer Output", hit ENTER to accept all of the defaults. Also hit ENTER for the "Define Spool Output" screen.
You can try different values here but for now, change the "Print Cover Page" form "Y" to "N" and hit ENTER.
You should now see the "Specify Page Headings and Footings". Fill it in with something like:
----------------------------------------------------------------
Specify Page Headings and Footings
Type choices, press Enter.
(Type &date, &time, and &page, or choose standard page headings.)
Print standard
page headings . . . . . Y Y=Yes, N=No
Page heading
Customer File
Texas Only
Sorted by Name
Page footing
35
CSQ002
---------------------------------------------------------------
I've put in a three line heading and entered the query name as a footer. Hit ENTER to get back to the main query screen.
Note that if you hit F5 right now, you will see exactly what the other query saw. The headings and footers are not displayed. They will show up in the report though.
Hit F3 to get to the EXIT screen and save the query.
Now run the query from the command line by keying in:
RUNQRY USER999/CSQ002
The query has now created a report and written it to the Spool File. The Spool File is a storage area for the report. If you had an AS/400 printer connected and ready to print, the file would print to the report. Since you don't have an AS/400 printer, the report is still sitting in the Spool File.
There are many Spool File areas on the AS/400. Which one is yours in? It depends on the values used to set up your user profile. That is, when a user ID is defined, the printer for that user ID is also defined. In your case, it isn't really a printer... it's a dummy printer.
So, how can you look at the reports in your Spool File. You use the "Work with Spool Files" command. Key:
WRKSPLF
and hit ENTER.
You will see the Spool File with all the reports in it. Many of them will have odd names and some may be error logs generated automatically. For example, if you disconnect from the internet before you sign off, the AS/400 may generate a system log report of your "abnormally terminated" job.
Reports created by QUERY/400 are given the messy name of QPQUPRFIL. So you should now see a list of all the reports in your Spool File.
Near the top of the screen you can see the options you can use. The only ones you should need are 4=DELETE and 5=DISPLAY.
By keying the option number "5" next to a report and hitting enter, you can see the report. Here you can see your headings. Similar to the interface for QUERY/400 you can: F20 to scroll right (shift F8)F19 to scroll left (shift F7)Key in "B" and hit ENTER to go to the bottomKey in "T" and hit ENTER to go to the top
Once you've looked at your report, exit out of it by hitting F3. Now put a "4" next to it in the Spool File list and hit ENTER and you have deleted it.
Experiment by making several reports. Do this by running your query several times. Then use WRKSPLF to view your spool file.
Feel free to delete all of the reports in your Spool File. I try to keep mine empty. Especially, feel free to delete the reports you don't understand because they were created by the system.
36
In conclusion, here is a short discussion on routing print data to your printer.
Not too long ago, all AS/400 printers were connected directly to AS/400's or AS/400 remote controllers. With the internet has come the ability to easily route print data to a remote. Doing so requires the client machine (that is, your PC) to have an AS/400 Telnet Client that is capable of creating virtual print devices.
With such a Telnet Client, you can easily print reports, like this query, directly to your printer. These Telnet Clients are about $150 to $200. I like the one sold by Synapse (www.synapse.com). There are others including IBM's Client Access.
You do not need print capabilities to do this tutorial. I rarely print reports out. I never print programs out. It is important to realize how easily your reports could be printed on a PC printer though. A $200 investment for a company to be able to use a remote AS/400 is not very much money.
Showcase Article - Physical and Logical Files
The AS/400 database, DB2/400 is part of the AS/400 operating system. It is a relational database and has features similar to other databases you may have used such as Microsoft Access, Oracle or Dbase. The standard method of creating files is to define the specifications of the file using DDS. Of course DDS is used for other things on the AS/400 like defining display files and print files.
Create a Physical File
To create a physical database file, enter your source statements in a DDS source file member. For now, name the member "CUS" for customer file. Make sure the member type is "PF". This tells the compiler that this is for a physical file. Enter the records in Figure 1 to define a simple customer file. Notice that the first record has an "R" in position 17. This means that this line is specifying the record name, in this case "CUREC". The "TEXT" is optional but helps to document the file.
After the line naming the record, each line describes a field. The field name is followed by the field length and its data type. The three most used data types are "A" for alpha or character, "S" for numeric and "P" for packed decimal. For numeric fields, you must also specify the number of decimal positions. So here, the company number field is a three digit number with no decimal places. The customer number and zip code are also numeric fields with no decimal places. The credit limit is a numeric, packed decimal field with 9 digits, of which two are after the decimal point. The rest of the fields are character fields.
Once you have entered the DDS source code, you must compile it. You do this by keying option 14 next to your member name on the PDM screen. If you pay attention you will see that the AS/400 is actually executing the CRTPF (Create Physical File) command. It knows to use this command because the member type of the source code is "PF".
You now have a database physical file. This file has built into it the fields and their attributes.
Create a Physical File With Key Fields
Let's modify this file definition to add key fields. If a physical file has key fields, programs can randomly access the records or read them sequentially in the order of the key fields. You can see in Figure 2 that it is simple to add key fields.
37
The "UNIQUE" record at the beginning of the source is used if you want the AS/400 to insist on having no records with duplicate keys. This is optional.
At the end of the source code, there are two lines with "K" in position 17. These lines define the key fields. So, this file will build a key using the company number and then the customer number. Further, it will not allow a duplicate company number / customer number records to be written.
The records are written to the file in arrival sequence. If you read the data by specifying keyed access, the records will read as though they have been sorted by company number and customer number. Also, your programs can randomly retrieve records. For example, a "CHAIN" instruction in RPG can now randomly read the record for a specific company number / customer number.
Create a Logical File To Resequence Order of Records
Now for the real magic. In only a few lines of source code, you can create a logical file. This is a way of reading the file with a different key. A logical file is a list of key values that point to the physical file. It does NOT contain copies of the data in the physical file.
To create a logical file, again enter your source statements in a DDS source file member named "CUS01". This time, make sure the member type is "LF". Enter the source code in Figure 3.
The first line tells the compiler that this logical file will resequence the records in the physical file named in the "PFILE" specification. In this case it is the "CUST" file. Also, notice that here we are using the same record name as the physical file, "CUREC".
The only remaining lines are like the last two lines of the physical file source. They name the fields that you want to use as keys.
Again compile the file by using option 14. This time, the AS/400 will execute the "CRTLF" (create logical file) command. You now can read the customer file in city / state sequence simply by reading the file "CUS01" in keyed sequence.
Create a Logical File To Select and Resequence Records
Finally, look at Figure 4. The "S" type record will select only records that have customer status equal to "A". Also, this logical file will read the records in customer name sequence.
So, a program reading this file in keyed sequence, will read the records alphabetically by customer name and will read only records of active customers.
Figure 1 - DDS for Physical File Without Key
A R CUREC TEXT('CUSTOMER FILE')
A CUCO 3S 0 TEXT('COMPANY #')
A CUSTS 1A TEXT('STATUS CODE')
38
A CUNUM 5S 0 TEXT('CUSTOMER #')
A CUNAME 30A TEXT('CUSTOMER NAME')
A CUADR 30A TEXT('CUSTOMER ADDRESS')
A CUCITY 18A TEXT('CUSTOMER CITY')
A CUSTAT 2A TEXT('CUSTOMER STATE')
A CUZIP 9S 0 TEXT('CUSTOMER ZIP')
A CUCRLM 9P 2 TEXT('CUST CREDIT LIMIT')
Figure 2 - DDS for Physical File With Key Fields
A UNIQUE
A R CUREC TEXT('CUSTOMER FILE')
A CUCO 3S 0 TEXT('COMPANY #')
A CUSTS 1A TEXT('STATUS CODE')
A CUNUM 5S 0 TEXT('CUSTOMER #')
A CUNAME 30A TEXT('CUSTOMER NAME')
A CUADR 30A TEXT('CUSTOMER ADDRESS')
A CUCITY 18A TEXT('CUSTOMER CITY')
A CUSTAT 2A TEXT('CUSTOMER STATE')
A CUZIP 9S 0 TEXT('CUSTOMER ZIP')
A CUCRLM 9P 2 TEXT('CUST CREDIT LIMIT')
*
A K CUCO
A K CUNUM
Figure 3 - DDS for Logical File to Resequence Order of Records
39
A R CUREC PFILE(CUS)
A TEXT('CUST BY CITY / STATE')
*
A K CUCITY
A K CUSTAT
Figure 4 - DDS for Logical File to Select and Resequence
A R CUREC PFILE(CUS)
A TEXT('CUST NAME/ACTIVE ONLY')
A K CUNAME
*
A S CUSTAT COMP(EQ 'A')
RPG Lesson 1 - A 7 statement RPG-III program
It is important to understand the history behind the RPG language. The language was originally developed in the 1960's. It was a very high-level language meaning that a lot could be done with few programming statements. It was originally intended to be used as a report writer, hence the name Report Program Generator.
This original form of RPG was unique is several ways:
1 - 5 different record types were used to do everything
"F" was for file definitions
"I" was for input definitions (record layouts)
"C" was for calculations
"O" was for output definitions
"E" was for exception processing
40
2 - There were many automatic processing features like the "cycle"
The cycle processing automatically read the input file and
created the output files… that is, no read or write statements were
needed.
3 - Fixed column locations for values of each programming statement. That is,
unlike COBOL, C, Java, or Basic, the code is not free form.
4 - The use of Indicators or Switches was painfully required. A switch with
a value of '0' is off and a value of '1' is on. Switches were used to
determine the results of I-O operations and needed for simple compare
instructions. For example, instead of a statement that read like:
IF CTR > 0, Do SOMETHING
RPG read more like
COMPARE CTR to 0 and turn Indicator 90 on if it is >
If Indicator 90 is on, Do SOMETHING
The programs were sometimes rather ugly. The use of indicators made many programs very hard to understand.
RPG has evolved nicely to look more and more like other modern languages. While indicators are still used for Input-Output (read and write) operations, standard conditional operations are now available. IF/THEN, DoWhile, Do Until and Select Case operands exist. While still not completely freeform, the statements have portions that are free form. Also, powerful string handling functions like %trim, %subst, %len and %scan are available. If you are familiar the concepts of structured programming you will see that RPG has everything required for structured code.
So, while RPG is about 40 years old, its newest form (RPG IV) is modern and structured. The problem is that many programs are still in use that have very old programming styles. So, you really must be familiar with both RPG/400 (also known as RPG III) and RPG IV (also known as RPG ILE).
RPG is a full featured language that can do all functions of data processing: reading files, randomly retrieving data, navigating through indexes, reading and writing to data terminal or display files, creating print reports and database files.
41
If you are still concerned that RPG is too old to be useful, consider that Visual Basic and ASP are really just new versions of BASIC. BASIC is as old as RPG. Also, you should know that RPG ILE can create compiled objects that bind with modules written in other languages (like C) and can be used to process CGI scripts on the internet and output dynamic HTML. No kidding.
If you have an RPG book, I suggest you use it in addition to (or in place of) this tutorial. It is a challenging task to describe such a complex language in short, readable topics.
To proceed you need to be familiar with PDM (see topic 4) and should have completed the exercise in topic 5 that copies a file.
Since it important to know the old way of doing things (RPG/400) and the new way (RPG/ILE), I will present each program we write in both languages. Learn the RPG/400 style so you can get a job. Learn the RPG/ILE so you can see how modern the language has become.
Topic 5 showed you how to copy a file named CUST into your user library. Since this will be the input file to our program, make sure that your library list includes your user library. I prefer to have this library as my current library.
So, use DSPLIBL to display your library list. If you don't see your user library in the list, use the CHGCURLIB USER999 command. This will change your current library to USER999. Remember that when I say USER999, I mean your user ID.
You can look at your data file with the command:RUNQRY QRYFILE(CUST)
If this doesn't show your file, either you didn't copy the file (see Topic 5) or your library list does not include your user library. You should see that the address for every record is "123 MAIN STREET". We will write a program to read the first record of the file and change the address to "456 OAK". In the next tutorial we will convert the program to RPG-ILE (RPG IV). In later topics we will change the program to read every record in the file and change the address to "456 OAK" in every record.
We need to enter program source statements, so start PDM (STRPDM). You should see something like:
------------------------------------------------------------------------------------
AS/400 Programming Development Manager (PDM)
Select one of the following:
1. Work with libraries
2. Work with objects
3. Work with members
4. Work with projects
42
5. Work with groups
6. Work with parts
9. Work with user-defined options
---------------------------------------------------------------------------------
Key in 3 and hit ENTER. Fill in the screen to look like:
Specify Members to Work With
Type choices, press Enter.
File . . . . . . . . . . QRPGSRC Name, F4 for list
Library . . . . . . . . user999 *LIBL, *CURLIB, name
Member:
Name . . . . . . . . . *ALL *ALL, name, *generic*
Type . . . . . . . . . *ALL *ALL, type, *generic*,
-------------------------------------------------------------------------------
Of course, change the USER999 to your user ID. Hit ENTER now.
If you get an error message that QRPGSRC was not found in USER999, you need to create the file QRPGSRC to hold your RPG-III (RPG/400) source code. For a refresher on this, review the topic on PDM. The command to create QRPGSRC in your library is:
CRTSRCPF USER999/QRPGSRC Your screen should look like:
File . . . . . . QRPGSRC
Library . . . . USER999 Position to . . . . .
Type options, press Enter.
43
2=Edit 3=Copy 4=Delete 5=Display 6=Print 7=Rename
8=Display description 9=Save 13=Change text 14=Compile 15=Create module..
Opt Member Type Text
(No members in file)
Remember from your PDM lesson that this is trying to show you a list of all of the RPG programs that you have entered. Since you haven't entered any, there is nothing to show.
You need to add a program. Let's call the program TUTR001. This name could be any 10 characters but if you don't follow a naming convention you will confused quickly. This name is derived from TUT (for tutorial), R for RPG and 001.
Hit F6 to add the program. Key in the name (the source member), RPG for the source type and a short description. Your screen should look like:
---------------------------------------------------------------------------
Start Source Entry Utility (STRSEU)
Type choices, press Enter.
Source file . . . . . . . . . . > QRPGSRC Name, *PRV
Library . . . . . . . . . . . > USER000 Name, *LIBL, *CURLIB,
Source member . . . . . . . . . tutr001 Name, *PRV, *SELECT
Source type . . . . . . . . . . rpg Name, *SAME, BAS, BASP
Text 'description' . . . . . . . Change the first record in CUST
-----------------------------------------------------------------------
Now hit enter and you will see a blank screen where you can enter RPG source code.
Back in the seventies, programmers had to keep track of what column each operand of the RPG statement was in. It was a mess.
With PDM (actually SEU, the Source Entry Utility), things are easier. Not easy, but easier. The problem is that RPG is a fixed column language. It is not a free format language. SEU provides prompting to help you but even it is a bit complicated at first.
44
The problem is that the different records types (F, I, E, C, O) do multiple things. That is, the I record type can be used several different ways so it has several different ways of prompting.
The first statement of this program is a FILE specification. That is, it will name the file that we will read and update. Since we want to read the CUST file, we will enter an F record to define the file CUST.
To do this, hit F23. Since your PC keyboard doesn't have an F23 key, the Telnet5250 product you are using has mapped the SHIFT-F11 key as an F23 key. So, hold down SHIFT and hit F11. The top of your screen should look like:
Select Prompt
Type choice, press Enter.
Prompt type . . . . . . . . . . . . Values listed below
RPG/400: H,F,FC,FK,FX,U,E,L,I,IX,J (I cont),JX,DS,SS,SV,C,O,
OD,P (O cont),N,* (Comment)
Wow. This means that there are 21 different formats to choose from. This is an easy one. Since this is a FILE specification, we will use the F prompt. So key F for the Prompt and hit ENTER.
You should now see:
0001.00
****************** End of data ********************************
Prompt type . . . F Sequence number . . . 0001.00
File File End of File
Filename Type Designation File Sequence Format
Record Mode of Length of Record
Length Processing Key Field Address Type
File Overflow Key Field Extn
45
Organization Indicator Start Loc Code Device
File File
Continuation Exit Entry Addition Condition
What a mess! A couple of things have happened. The first is that the display shows your first line of the program as line 0001.00. Not only that, the SEU editor has highlighted it because it is blank, RPG-III does not allow blank lines! The rest of the screen shows all of the fields that might be used to define a file. Don't panic yet. All you need to enter is:
CUST for Filename
I for File Type
F for File Designation
E for File Format
DISK for Device (2nd line from the bottom on the right)
Hit ENTER and your values will go in the right places. Amazingly, the one value that you can't enter here is the F that tells RPG that this is a FILE specification. So hit enter, your screen looks like:
FMT F .....FFilenameIPEAF....RlenLK1AIOvKlocEDevice+
*************** Beginning of data ************
0001.00 CUST IF E DISK
****************** End of data ***************
It also displays an error that "The Type entry is not H, F, I, C ……"
So put your cursor on the character right before CUST and key an F.
Now you have a valid file specification:
FMT F .....FFilenameIPEAF....RlenLK1AIOvKlocEDevice+
*************** Beginning of data ************
0001.00 FCUST IF E DISK
****************** End of data ***************
Now, calm down. This may be the only time in your life that you actually key in a FILE specification. In the world of programming, everything is copied and changed, cut and paste. Normally, you will simple copy an existing program and then change and add statements to it.
46
So, what did you just define? You told the program that you will be using the file CUST, that the file is being used for Input (you will read the file), that the file is Fixed length (almost all files are fixed length), that the file is Externally defined (that is, it was defined by the database language of the AS/400) and finally that the file is a DISK file (not a PRINTER or Display Screen).
Imagine for a moment a program where the user enters a customer number on the display screen. The program reads the customer record, looks up the customer's most recent order and prints it. Such a program will have at least 4 files: Display screen file (a WORKSTN file) Customer file (a DISK file) Order file (a DISK file) Printer file (a PRINTER file)
This is a simple program. It has only one file.
Now we are ready for the processing logic of the program. The total logic of this program will be only 6 statements. Processing logic in RPG is known as CALCULATION statements and uses the C specification and the C prompt type.
Soon, you will get more comfortable with PDM and SEU. Now, we need to add a line to after the F statement. Do this by keying an I (for insert) on top of the 0001.00.
Your screen should look like:
FMT FX .....FFilenameIPEAF........L..I........Device+
*************** Beginning of data ************
I001.00 FCUST IF E DISK
When you hit ENTER, the editor will create a blank line for you and even place your cursor in column 6 where you can enter the C for CALCULATION. With the cursor on the line with the C, hit Shift-F11 to prompt and this time use C for the prompt type.
Your screen will now show:
Prompt type . . . C Sequence number . . . 0002.00
Level N01N02N03 Factor 1 Operation Factor 2 Result
Decimal
Length Positions H/N/P HI LO EQ Comment
Now finally some good news. Most of the RPG programming you do is using the C specification. This type of statement is not too messy.
The first processing step of the program is to read the first record of the CUST
file. RPG needs to know 2 things about a read statement:
47
1) what file to read
2) what indicator to turn on if there was not a "next" record in the file
(that is, what indicator will tell you that there is no more data in
the file)
Indicators are numbered from 01 to 99. There are some other special ones too.
I like to use indicators 90 thru 99 for the read statements. So enter
READ for the Operation
CUST for FACTOR 1
90 for EQ
Your screen should look like:
0001.00 FCUST IF E DISK
0002.00 C
'''''''
****************** End of data *******************************
Prompt type . . . C Sequence number . . . 0002.00
Level N01N02N03 Factor 1 Operation Factor 2 Result
READ CUST
Decimal
Length Positions H/N/P HI LO EQ Comment
90
48
When you hit ENTER, it will look like:
FMT FX .....FFilenameIPEAF........L..I........Device+......KExit++En
*************** Beginning of data ***************************
0001.00 FCUST IF E DISK
0002.00 C READ CUST 90
****************** End of data ******************************
There are 3 places to enter indicators for statements. Unfortunately, it is not always easy to figure out which place to use. The HI, LO and EQ headings come from the obsolete way indicators were first used. In old RPG, there were no IF statements. Instead, you used a COMP (Compare) statement to compare the values of FACTOR1 and FACTOR2 and then would set on an indicator if FACTOR1 was higher than FACTOR2, a different indicator if FACTOR1 was lower that FACTOR2 and finally an indicator if they were equal. We will NEVER do this.
The lesson here is simple. For a READ instruction, the indicator mentioned in the EQ field will be turned on when there are no more records in the file.
Let's pause for a minute and look at all that is happening with these 2 statements.
The F specification tells the AS400 to set up a way to read the CUST file. It also tells it to find the fields and attributes of the fields using the database definition of the CUST file. In most other languages, you would need a statement to OPEN the file. Such a statement tells the computer that you are ready to use the file. RPG assumes that you want to read the file and automatically opens the file for you. There is a simple way to tell the AS400 that you want to OPEN and CLOSE the file explicitly but there is no reason to do that.
The READ statement reads the first record of the file CUST and populates an area in your program's memory with the data that is in the first field. You program has each field defined and now has data in each field.
After the READ, the field CSNBR has a value of 1002, the field CSNAME has a value of E LUMPKIN, the field CSADR1 has a value of 123 MAIN STREET.
We now want to change the value in CSADR1. Unlike other languages, if we move only a few characters to a field that is 30 characters long, RPG will change only the first 3 characters. So we will first blank out the field and then move 456 OAK to the address.
Insert a line for a new C statement. One way to do this is to key an I over the
0002.00 and hit ENTER. Then key C in column 6 and hit Shift-F11. Key C for prompt
type and hit ENTER. We want to blank out the CSADR1 field so we will move blanks
to it. RPG has some system values defined that are named like:
49
*BLANK or *BLANKS
*ZERO or *ZEROES
*ON or *OFF
*IN90 (for indicator 90)
As you might guess, we want to move the value *BLANK to CSADR1. So fill in your screen to look like:
Prompt type . . . C Sequence number . . . 0003.00
Level N01N02N03 Factor 1 Operation Factor 2 Result
MOVE *BLANK CSADR1
Decimal
Length Positions H/N/P HI LO EQ Comment
Hit ENTER and your program should look like:
*************** Beginning of data *****************************
0001.00 FCUST IF E DISK
0002.00 C READ CUST 90
0003.00 C MOVE *BLANK CSADR1
****************** End of data ********************************
Now insert another line to MOVEL '456 OAK' to CSADR1. This says to move the characters
in between the quotes to the field named CSADR1. The operand is MOVEL for MOVE LEFT.
This means that since '456 OAK' is only 7 characters and CSADR1 is 30 characters,
move '456 OAK' to the left
You program should look like:
*************** Beginning of data **************************
50
0001.00 FCUST IF E DISK
0002.00 C READ CUST 90
0003.00 C MOVE *BLANK CSADR1
0004.00 C MOVE '456 OAK' CSADR1
****************** End of data *****************************
At this moment, the data on the disk has the value '123 MAIN STREET' in the area of
the record for CSADR1. If you ran this program, at this spot in the program, the
value of the field CSADR1 in memory would be '123 OAK'. But if you stopped here,
the new value ('123 OAK') would not get stored in the file. To do that you must
UPDATE the record. In RPG-III verbs or operands can be only 5 characters so the
verb is UPDAT. Also, you must use the record name for the file. This is too
complicated to explain here but trust me that the record name for the CUST file
is CSREC.
So add the statement to update the record CSREC. Now that we see that we are using
the file for Update (not just Input), it is time to change the I in the FILE
definition from I to U.
0001.00 FCUST UF E DISK
0002.00 C READ CUST 90
0003.00 C MOVE *BLANK CSADR1
0004.00 C MOVEL'456 OAK' CSADR1
0005.00 C UPDATCSREC
Now all that is left to do is to tell the program to stop.
First, we have to discuss a housekeeping item left over from the very early days
of RPG. We know that RPG will automatically open the file. However, it will only
51
close the file if the "LAST RECORD" indicator is ON. For now, just make sure the
last 2 statements to execute in a program are:
MOVE *ON *INLR
RETRN
The last statement is a RETRN which is an abbreviation of RETURN.
So the final program is:
0001.00 FCUST UF E DISK
0002.00 C READ CUST 90
0003.00 C MOVE *BLANK CSADR1
0004.00 C MOVEL'456 OAK' CSADR1
0005.00 C UPDATCSREC
0006.00 C MOVE *ON *INLR
0007.00 C RETRN
Now that you are finished, hit F3 and ENTER to save your statements.
So you now have the source statements to compile an RPG program. You compile it just like you compiled the CL program. Key a 14 on the line next to the program name in PDM and hit ENTER. Like:
Work with Members Using PDM
File . . . . . . QRPGSRC
Library . . . . USER999 Position to . . . . .
Type options, press Enter.
2=Edit 3=Copy 4=Delete 5=Display 6=Print 7=Re
8=Display description 9=Save 13=Change text 14=Compile 15=Cr
Opt Member Type Text
52
14 TUTR001 RPG Change the first record in CUST file
By the way, this program is in the USER000 library. You can see it using PDM.
After compiling your program, you will want to look at the compiled listing. Remember, you do this with the command:
WRKSPLF
You will see something like:
Work with All Spooled Files
Type options, press Enter.
1=Send 2=Change 3=Hold 4=Delete 5=Display 6=Release
8=Attributes 9=Work with printing status
Device or Total
Opt File User Queue User Data Sts Pages
TUTR001 DAVIDMOUNT PRTDGM RDY 5
TUTR001 DAVIDMOUNT PRTDGM RDY 5
Put your cursor next to the last one and key in a 5 and hit ENTER.
You will see your compiler listing. If you key in a B at the top and hit ENTER, the AS400 will take you to the bottom of your listing. If your compile worked, it will look like:
F i n a l S u m m a r y
Message Count: (by Severity Number)
TOTAL 00 10 20 30 40 50
2 2 0 0 0 0 0
Program Source Totals:
Records . . . . . . . . . . : 7
Specifications . . . . . . : 7
Table Records . . . . . . . : 0
Comments . . . . . . . . . : 0
53
PRM has been called.
Program TUTR001 is placed in library USER000. 00 highest severity.
* * * * * E N D O F C O M P I L A T I O N * * * *
The phrase "Program TUTR001 is placed in library USER???" means the AS400 understood your statements well enough to crate an executable program.
If your compile didn't work, start by making sure that you have your user library in your library list. The easy way to do this is:
CHGCURLIB USER999
All that is left is to run the program. There are several ways to do this but the most straightforward way is to use this command:
CALL TUTR001
The program will run almost instantly. Then if you look at the CUST file the address of the first record will have changed:
RUNQRY QRYFILE(CUST)
Boy what a long topic! Each lesson will build on this program. It is important that you get familiar with entering programs, compiling them and looking at the compile listings.
Viewing a Compiler Listing
To view the results of a program compiling, use the Work With Spool File command, WRKSPLF.
You will see a list of reports in your spool file. It will look like:
Device or Total
Opt File User Queue User Data Sts Pages
QSYSPRT AIRPGMR PRTDGM RDY 1
QPJOBLOG AIRPGMR QPRINT AIRNRA RDY 2
QSYSPRT AIRPGMR PRTDGM RDY 1
QSYSPRT AIRPGMR PRTDGM RDY 1
QPJOBLOG AIRPGMR QPRINT TQE07 RDY 2
QSYSPRT AIRPGMR PRTDGM RDY 1
QSYSPRT AIRPGMR PRTDGM RDY 1
Each line is the name of a report on your Spool File. The most recent reports are at the bottom. Key a 5 next the report you want to view.
54
You should now be looking at the compiler listing. To quickly locate errors, key B (for bottom) in the CONTROL field and hit ENTER. You are now looking at the bottom of the compiler report.
If your program compiled successfully, the last few lines will look like:
* * * * * E N D O F F I N A L S U M M A R Y * * * *
Program CMNR020 placed in library AIR. 00 highest severity. Created on
* * * * * E N D O F C O M P I L A T I O N * * * * *
If not, it will look more like:
* * * * * E N D O F F I N A L S U M M A R Y
Compilation stopped. Severity 30 errors found in program.
* * * * * E N D O F C O M P I L A T I O N * *
To find the errors, hit the PAGE UP key until you see:
* * * * * E N D O F E X T E R N A L R E F E R E N C E S * *
5769RG1 V4R2M0 980228 RN IBM ILE RPG AIR/CMNR020
M e s s a g e S u m m a r y
Msg id Sv Number Message text
*RNF7031 00 61 The name or indicator is not referenced.
*RNF7066 00 1 Record-Format name of Externally-Described file is not
*RNF7030 30 1 The name or indicator is not defined.
*RNF7503 30 1 Expression contains an operand that is not defined.
* * * * * E N D O F M E S S A G E S U M M A R Y * * * *
These are the errors that need correcting. Anything with severity level 00 is NOT an error.
55
To find the error, go to the top of the report. Do this by keying T in the CONTROL field and hitting ENTER.
Then, key the error message ID in the FIND field. In this case, I keyed RNF7030 in the FIND field. Then, hit F16 to search. Remember F16 is SHIFT / F4.
In my case, the errors look like:
*RNF7066 00 2 000200 Record-Format CUSREC not used for
*RNF7030 30 123 005200 The name or indicator SYSDTECC is
*RNF7503 30 123 005200 Expression contains an operand tha
The errors RMF7030 and RNF7503 need to be fixed. They are both related to sequence # 123 in the compile listing which is line number 52.00 in the source file.
In my case, I misspelled a variable name. This caused 2 errors. Often, 1 error will cause more than 1 error message.
RPG Lesson 2 - Converting RPG-III to RPG IV
First RPG IV Program
Hopefully you were able to complete the previous topic and compile a simple RPG III program. Though introduced in 1994, RPG IV is known as the "new" RPG. Because of the huge number of programs written in RPG III, the industry has been slow to adopt RPG IV. It is undoubtedly the way of the future on the AS/400.
RPG III is more accurately known as RPG/400 when it runs on an AS/400. RPG IV supports the "Integrated Language Environment" concept introduced in 1994. This is known as ILE and allows program modules to be bound together at compile time so that an RPG IV program can use routines written in C or any other language. So RPG III is essentially the same as RPG/400 and RPG IV is essentially the same as RPG ILE.
Before you go any further, read this short article:
Converting RPG-III to RPG-ILE
Now you are emotionally ready to convert your program TUTR001 to RPG IV.
First you must create a place for your program statements. Since RPG IV statements are longer than other program source statements, the command to create the source physical file is slightly different. To create the appropriately named place for RPG IV source:
CRTSRCPF FILE(USER999/QRPGLESRC) RCDLEN(112)
Of course, change the USER999 to your user ID. This command creates a source physical file named QRPGLESRC to hold your programs written in RPG IV. The name is the AS/400 standard for RPG IV or RPG ILE source code. It starts with "Q" followed by RPGLE (short for RPG ILE) and then SRC for source.
Now, use the AS400 command to convert the old program to RPG ILE. Key CVTRPGSRC (Convert RPG Source) and hit F4 to see the prompts. Your screen should look like:
56
Convert RPG Source (CVTRPGSRC)
Type choices, press Enter.
From file . . . . . . . . . . . Name
Library . . . . . . . . . . . *LIBL Name, *LIBL, *CURLIB
From member . . . . . . . . . . Name, generic*, *ALL
To file . . . . . . . . . . . . QRPGLESRC Name, *NONE, QRPGLESRC
Library . . . . . . . . . . . *LIBL Name, *LIBL, *CURLIB
To member . . . . . . . . . . . *FROMMBR Name, *FROMMBR
Now fill in the values to indicate that you want to convert the program located in source physical file QRPGSRC in library USER999 that is named TUTR001 and that you want the converted program to be in the same library with the name TUTR002.
Convert RPG Source (CVTRPGSRC
Type choices, press Enter.
From file . . . . . . . . . . . qrpgsrc Name
Library . . . . . . . . . . . user999 Name
From member . . . . . . . . . . tutr001 Name
To file . . . . . . . . . . . . QRPGLESRC Name
Library . . . . . . . . . . . user999 Name
To member . . . . . . . . . . . tutr002 Name
Hit ENTER and the command will copy and modify your program.
You can now use PDM to look at the converted program. From the PGM screen key in 3 and hit ENTER. Then fill in the screen to look like:
Specify Members to Work With
57
Type choices, press Enter.
File . . . . . . . . . . QRPGLESRC Name, F
Library . . . . . . . . USER999 *LIBL,
Member:
Name . . . . . . . . . *ALL *ALL
Type . . . . . . . . . *ALL *ALL
Hit enter and you will see your converted program in the list of programs:
Work with Members Using PDM
File . . . . . . QRPGLESRC
Library . . . . USER000 Position to . .
Type options, press Enter.
2=Edit 3=Copy 4=Delete 5=Display 6=Print
8=Display description 9=Save 13=Change text 14=Compile
Opt Member Type Text
TUTR002 RPGLE Change the first record in CUST
Notice that the "Type" is RPGLE. That tells the AS400 to compile this as RPG ILE instead of RPG III.
Key a 2 next to the program name (TUTR002) and hit ENTER and you will see the source code:
0001.00 FCUST UF E DISK
0002.00 C READ CUST 90
0003.00 C MOVE *BLANK CSADR1
0004.00 C MOVEL '456 OAK' CSADR1
58
0005.00 C UPDATE CSREC
0006.00 C MOVE *ON *INLR
0007.00 C RETURN
****************** End of data ****************************************
You can see that not much has changed. RPG IV has more room for operand names so the UPDAT and RETRN are now spelled out. The other values are spread out a bit more.
You can compile and run this program. You should try that now. Remember that you compile by using option 14. You can then CALL TUTR002 to run it.
Now copy this program and modify it to reflect the new coding style of RPG IV. Copy the program using PDM. Simply key 3 as the option:
Work with Members Using PDM
File . . . . . . QRPGLESRC
Library . . . . USER000 Position to . . . . .
Type options, press Enter.
2=Edit 3=Copy 4=Delete 5=Display 6=Print 7=Rename
8=Display description 9=Save 13=Change text 14=Compile 15=Create
Opt Member Type Text
3 TUTR002 RPGLE Change the first record in CUST file
When you hit ENTER, fill in TUTR003 as the new name:
Copy Members
From file . . . . . . . : QRPGLESRC
59
From library . . . . : USER000
Type the file name and library name to receive the copied members.
To file . . . . . . . . QRPGLESRC Name, F4 for list
To library . . . . . USER000
To rename copied member, type New Name, press Enter.
Member New Name
TUTR002 TUTR003
Now hit ENTER again and PDM will copy TUTR002 and name it TUTR003.
Edit TUTR003 by keying 2 as the option.
One way RPG IV is different is that lower case letters are allowed. This doesn't change the functionality of the program but it certainly makes it feel more modern.
You must tell SEU that you want to use lower case letters. When you are editing the TUTR003 program, hit F13 (well actually Shift-F1) and you will get the options for the editor:
Change Session Defaults
Type choices, press Enter.
Amount to roll . . . . . . . . . . . C H=Half, F=Full
C=Cursor, D=Data
1-999
Uppercase input only . . . . . . . . N Y=Yes, N=No
Tabs on . . . . . . . . . . . . . . N Y=Yes, N=No
Increment of insert record . . . . . 0.01 0.01-999.99
Full screen mode . . . . . . . . . . N Y=Yes, N=No
60
Source type . . . . . . . . . . . . RPGLE
Syntax checking:
When added/modified . . . . . . . Y Y=Yes, N=No
From sequence number . . . . . . . 0000.00-9999.99
To sequence number . . . . . . . . 0000.00-9999.99
Set records to date . . . . . . . . / / YY/MM/DD
It is best to change the first value to C. This affects how the screen scrolls when you PAGE-UP and PAGE-DOWN. Make sure the "Uppercase input only" selection is N. This allows you to key lowercase characters.
For now, make 2 changes in the style. First, use lower case characters when you want. Second, use the EVAL operand in place of MOVE and MOVEL. EVAL is short for EVALUATE and like the old BASIC "LET". It is not only more like other modern languages, it has other enhancements that make string handling easy.
Also, since there is more room, change the address to 456 OAK STREET.
The modified program should look like:
0001.00 FCUST UF E disk
0002.00 C Read CUST 90
0004.00 C Eval CSADR1 = '456 OAK STREET'
0005.00 C Update CSREC
0006.00 C Eval *inlr = *on
0007.00 C Return
Since the EVAL instruction works a little differently from the MOVE, it is no longer necessary to move blanks to CSADR1 before moving 456 OAK STREET to it.
Now compile and run the program. After running TUTR003 you can look at the file with:
RUNQRY QRYFILE(CUST)
and see that the address has changed to 456 OAK STREET.
Boy, in just 10 minutes you have learned a new language!
You should be getting more comfortable with PDM, SEU, compiling programs and looking at spool files. If so, you are on your way to being a productive programmer.
61
RPG III - Adding a Loop, IF and Subroutine
In a previous topic, you should have written a very short RPG III program to change the first record in the CUST file.
Let's add so more statements to the program so that it will read all records in the file and change the zip code for everyone in Tennessee.
You may want to read this very short article on data navigation first:
Data Navigation
Your program will still reference the CUST file, so, use DSPLIBL to display your library list. If you don't see your user library in the list, use the CHGCURLIB USER999 command. This will change your current library to USER999. Remember that when I say USER999, I mean your user ID.
You can look at your data file with the command: RUNQRY QRYFILE(CUST)
Now, use PDM to copy your old program. Start PDM (STRPDM). You should see something like:
---------------------------------------------------------------------
AS/400 Programming Development Manager (PDM)
Select one of the following:
1. Work with libraries
2. Work with objects
3. Work with members
4. Work with projects
5. Work with groups
6. Work with parts
9. Work with user-defined options
---------------------------------------------------------------------
Key in 3 and hit ENTER. Fill in the screen to look like:
Specify Members to Work With
62
Type choices, press Enter.
File . . . . . . . . . . QRPGSRC Name, F4 for list
Library . . . . . . . . user999 *LIBL, *CURLIB, name
Member:
Name . . . . . . . . . *ALL *ALL, name, *generic*
Type . . . . . . . . . *ALL *ALL, type, *generic*,
-----------------------------------------------------------------------
Of course, change the USER999 to your user ID. Hit ENTER now.
Your screen should look like:
File . . . . . . QRPGSRC
Library . . . . USER999 Position to . . . . .
Type options, press Enter.
2=Edit 3=Copy 4=Delete 5=Display 6=Print 7=Rename
8=Display description 9=Save 13=Change text 14=Compile 15=Create module..
Opt Member Type Text
TUTR001 RPG Change the first record in CUST file
Key a 3 as the option next to TUTR001. Hit ENTER and then fill in the screen to copy the program and name it TUTR004:
Copy Members
From file . . . . . . . : QRPGSRC
63
From library . . . . : USER999
Type the file name and library name to receive the copied members
To file . . . . . . . . QRPGSRC Name, F4 for list
To library . . . . . USER999
To rename copied member, type New Name, press Enter.
Member New Name
TUTR001 TUTR004
Hit ETER and you should now see the copied program in your list. You may want to change the description of the program so you'll remember which program does what. Your screen should look like:
Remember from your PDM lesson that this is trying to show you a list of all of the RPG
Work with Members Using PDM
File . . . . . . QRPGSRC
Library . . . . USER000 Position to . . . . .
Type options, press Enter.
2=Edit 3=Copy 4=Delete 5=Display 6=Print 7=Rename
8=Display description 9=Save 13=Change text 14=Compile 15=Create
Opt Member Type Text
TUTR001 RPG Change the first record in CUST file
TUTR004 RPG Change all TN records in CUST file
Key a 2 next to TUTR004 so you can change the source statements to the program.
Before we make the changes to the program we need to discuss different ways to write a loop. We want a loop that will read every record in the CUST file and change the records that have TN (Tennessee) as the state.
I always think of a loop as saying:
64
Try to Read a record from the file
If there was a record then
change it
update it
Go back and try to read the next record
Remember that when RPG III reads a record, you must specify which indicator to turn on it there are no more records; that is, it is END OF FILE.
You could write the instructions above in RPG III like this:
FCUST UF E DISK
C READIT TAG
C READ CUST 90
C *IN90 IFEQ *OFF
C MOVE *BLANK CSADR1
C MOVEL'456 OAK' CSADR1
C UPDATCSREC
C GOTO READIT
C ENDIF
C MOVE *ON *INLR
C RETRN
This program says to define a file named CUST.
Then, name the first line of the Calculations READIT. The, try to read a record (if END OF FILE, move ON to indicator# 90) If indicator# 90 is *OFF Move … Move … Update … Go back to the first line of the program Turn on the "magic" LR indicator End the program
This will work. The only problem is that for about 15 years, it has been considered bad style to use GOTO statements. This is an industry trend that includes all languages and all computers.
The reason is that long programs are hard to understand when there are a lot of GOTO statements. Programs with lots of GOTO's are nicknamed spaghetti programs because the statements can be as hard to follow as a strand of spaghetti.
SO, the industry prefers that we use DO statements. We can use a DO WHILE or a DO UNTIL. This still leaves us with 2 good ways to write the loop. I prefer the first because it looks a lot like the GOTO loop but without the GOTO:
65
FCUST UF E DISK
C *IN90 DOWEQ*OFF
C READ CUST 90
C *IN90 IFEQ *OFF
C MOVE *BLANK CSADR1
C MOVEL'456 OAK' CSADR1
C UPDATCSREC
C ENDIF
C ENDDO
C MOVE *ON *INLR
C RETRN
This program defines the file and then starts a DO loop.
The DOWEQ statement says that as long as indicator # 90 is OFF, execute all of the statements until the ENDDO (End DO) statement.
Then, start back at the top (a lot like a GOTO). If indicator # 90 is still OFF, execute the statements again. Eventually, the program will read all 1,000+ records in the file. When it does, indicator # 90 will be turned ON.
When indicator # 90 is ON, the program will not update the record and it will not continue to loop.
The other way to code the loop is with what is called a priming read statement. This method needs 2 READ statements but does not need the IF statement.
If looks like:
FCUST UF E DISK
C READ CUST 90
C *IN90 DOWEQ*OFF
C MOVE *BLANK CSADR1
C MOVEL'456 OAK' CSADR1
C UPDATCSREC
C READ CUST 90
C ENDDO
66
C MOVE *ON *INLR
C RETRN
Here, the first record is read before the DO begins. The statements are executed and the READ statement is at the end of the DO loop.
Either of these 2 methods is considered good code. I prefer the first.
Using the first acceptable loop, add the IF statement to test to see if the state is TN. Also, replace the code so that it changes the ZIP to 987650000.
First, do this by putting in an IF statement like this:
C CSSTE IFEQ 'TN'
C MOVE 987650000 CSZIP
C UPDATCSREC
C ENDIF
So, the whole program looks like:
FCUST UF E DISK
C *IN90 DOWEQ*OFF
C READ CUST 90
C *IN90 IFEQ *OFF
C CSSTE IFEQ 'TN'
C MOVE 987650000 CSZIP
C UPDATCSREC
C ENDIF
C ENDIF
C ENDDO
C MOVE *ON *INLR
C RETRN
This is considered good code by most programmers. But it really helps to move the update logic to a separate place in the program as a subroutine. This is done here only to help readability. It doesn't change the outcome.
67
In RPG, subroutines begin with a BEGSR (BEGIN SUBROUTINE) statement which also has the name of the subroutine. They end with ENDSR (END SUBROUTINE). They are run with the EXSR (EXECUTE SUBROUTINE) command.
If we move the update logic to a subroutine named UPD, the program looks cleaner. Also, we can add "COMMENTS" records. Any statement with a * after the record type, is a "COMMENT". In fact you can even remove the record type (the C or F in column 6).
With a few comment lines added to define the sections of the program, we get a pretty readable program:
FCUST UF E DISK
*-----------------------------------------------------
C *IN90 DOWEQ*OFF
C*
C READ CUST 90
C *IN90 IFEQ *OFF
C EXSR UPD
C ENDIF
C ENDDO
C*
C MOVE *ON *INLR
C RETRN
*-----------------------------------------------------
C UPD BEGSR
C*
C CSSTE IFEQ 'TN'
C MOVE 987650000 CSZIP
C UPDATCSREC
C ENDIF
C*
C ENDSR
*------------------------------------------------------
Now, compile this (remember… option 14) and run it (CALL TUTR004).
68
Then use RUNQRY QRYFILE(CUST) to see the data. If you scroll right by hitting F20 (actually Shift and F8) you will see that you changed the zip in all of the records with TN as CSSTE.
RPG III - Adding a Loop, IF and Subroutine to the RPG IV Program
In the previous topic, we added a DO loop to read all records in the file, an IF statement to test the state for "TN" and a subroutine.
You should be beginning to sense that RPG III is powerful but ugly.
Let's recreate this program using the easier to read syntax of RPG IV. The simplest way to do this is to copy TUTR003 in the QRPGLESRC source object and then modify the copied program.
Use PDM to copy TUTR003. Start PDM (STRPDM). You should see something like:
------------------------------------------------------------------------------------------
AS/400 Programming Development Manager (PDM)
Select one of the following:
1. Work with libraries
2. Work with objects
3. Work with members
4. Work with projects
5. Work with groups
6. Work with parts
9. Work with user-defined options
------------------------------------------------------------------------------------------
Key in 3 and hit ENTER. Fill in the screen to look like:
Specify Members to Work With
Type choices, press Enter.
69
File . . . . . . . . . . QRPGLESRC Name, F4 for list
Library . . . . . . . . user999 *LIBL, *CURLIB, name
Member:
Name . . . . . . . . . *ALL *ALL, name, *generic*
Type . . . . . . . . . *ALL *ALL, type, *generic*,
Of course, change the USER999 to your user ID. Hit ENTER now.
Your screen should look like:
Work with Members Using PDM
File . . . . . . QRPGLESRC
Library . . . . USER999 Position to . . . . .
Type options, press Enter.
2=Edit 3=Copy 4=Delete 5=Display 6=Print 7=Rename
8=Display description 9=Save 13=Change text 14=Compile 15=Create
Opt Member Type Text
TUTR002 RPGLE Change the first record in CUST file
TUTR003 RPGLE TUTR002 modified to modern style
Key a 3 as the option next to TUTR003. Hit ENTER and then fill in the screen to copy the program and name it TUTR005:
Copy Members
From file . . . . . . . : QRPGLESRC
From library . . . . : USER999
70
Type the file name and library name to receive the copied members
To file . . . . . . . . QRPGLESRC Name, F4 for list
To library . . . . . USER999
To rename copied member, type New Name, press Enter.
Member New Name
TUTR003 TUTR005
Hit ENTER and you should now see the copied program in your list. You may want to change the description of the program so you'll remember which program does what.
Key a 2 next to TUTR005 so you can change the source statements to the program.
The old syntax on the IF and DO statements is legal. So you can choose between:
C *in90 DOWEQ *off
AND
C DoW *in90 = *off
Not only is the second form more readable, it is more free form. You can put spaces and parentheses in the conditional part of the statement like this:
C DoW (*in90 = *off)
This may not look like such a big deal, but compare this old style IF statement:
C *in90 IFEQ *off
C STATUS ANDEQ 'D'
C STATUS OREQ 'A'
71
C CITY ANDEQ 'ATHENS'
with the newer style
C If (In90 = *off) and
C ((STATUS = 'D') or (STATUS = 'A')) and
C (CITY = 'ATHENS')
The newer style is not only more readable but you can actually figure out how the conditions are checked.
One of the other big changes in form from RPG III to RPG IV is that the subroutine names can be only 6 characters in RPG III. In RPG IV, the subroutine names can be 14 characters. These longer names make the programs many times easier to follow.
So using this new found knowledge about RPG IV, change the program to look like:
FCUST UF E disk
C*---------------------------------------------------------------------
C DoW *in90 = *off
C Read CUST 90
C If *in90 = *off
C Exsr UpdateCSREC
C EndIf
C EndDo
C
C Eval *inlr = *on
C Return
C*---------------------------------------------------------------------
C UpdateCSREC BegSR
C
C If CSSTE = 'TN'
C Eval CSZIP = 987650000
C Update CSREC
C EndIf
72
C
C EndSR
Compile the program with option 14 and you are done.
If you really hate using the indicators - and you probably do - you can use one of the new built in functions to check to see if the last record has been read. That is, you are checking to see if the file is at END OF FILE or EOF.
The Do loop can be written:
C DoW not %eof(CUST)
C Read CUST
C If not %eof(CUST)
C Exsr UpdateCSREC
C EndIf
C EndDo
In fact, the %EOF function will refer to the last file used by default. So you could write:
C DoW not %eof
C Read CUST
C If not %eof
C Exsr UpdateCSREC
C EndIf
C EndDo
If you have ever used Visual Basic, the EOF function will look familiar.
That's it!
Using SDA to set up a User Menu
You are beginning to see how to create the different pieces of a complete system. You have written queries that display and print data, you know how to view printed data and you have written several small programs that can change data. After this topic, you will learn to write programs to display and change data interactively - data maintenance, entry, update and display. In this topic, you will use yet another three letter acronym, SDA, as a tool. You will also make a couple of changes to your user profile. The end result will be a user interface that you could use as an entry point to an application system. The user would sign on to the AS/400 and immediately see the user menu. The user would never see the AS/400 programmer and operator menus. In summary, here is the task:
73
1) Create a menu named STARTMEN that will let the user:
Run the display query that you wrote in Topic 6
Run query to print a report from Topic 6
Run the program to change the address line in the CUST file
Display the CUST file using RUNQRY
Display Print Spool files
Sign Off
2) Change your user profile so that when you sign on, you see this new menu. One of the
most intuitive development tools on the AS/400 is SDA, Screen Design Aid. With it, you
build display screens and menus in a WYSIWYG (what you see is what you get) mode. We're
going to look at how easy it is to create a user menu.
Start SDA with the command STRSDA. You will see that SDA has three functions:
1) Design Screens
2) Design Menus
3) Test Display Files
You'll want to experiment with each of these later. For now, use selection 2 to design a menu. Enter the name of your new menu, where you want to store the source (usually QDDSSRC) and the library that it will be in. SDA will look for that menu and since it can't find it, it will create it.
Your screen should look like:
Design Menus
Type choices, press Enter.
Source file . . . . . . . . QDDSSRC Name, F4 for list
Library . . . . . . . . . user999 Name, *LIBL, *CURLIB
Menu . . . . . . . . . . . startmen Name, F4 for list
74
Of course, replace USER999 with your user library name. When you hit ENTER you will see:
Specify Menu Functions
File . . . . . . : QDDSSRC Menu . . . . . . . : STARTMEN
Library . . . . : USER999
Type choices, press Enter.
Work with menu image and commands . . . . . . Y Y=Yes, N=No
Work with menu help . . . . . . . . . . . . . N Y=Yes, N=No
The AS/400 even fills in the "Y" to indicate that you want to work with menu images and commands. Hit ENTER again and you see the following template menu.
STARTMEN STARTMEN Menu
Select one of the following:
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
75
Selection or command
SDA creates a template for you that has the menu name and a list of ten selections. On this screen, you list the selections for the user. On a separate screen, you list the commands associated with each selection. Avoid keying in "insert" mode since that will shift all text on the screen. To remove text, just space over it.
So, key on the screen so that it looks like:
STARTMEN STARTMEN Menu
Select one of the following:
1. Run Customer Query
2. Print Customer Query
3. Change Addresses in Customer file
4. Show Customer file
5. Work with Print files
6.
7.
8.
9.
10. Sign Off
When you hit enter, SDA uses your screen to build literals in a display file. F20 (Shift and F8) provides a way to display the text blocks that SDA will use. Each text block is preceded by a hidden character that contains the display attribute for that string of text. If you key an "H" right in front of a block of text, SDA will display that text in high intensity or white characters. An "R" will display the text in reverse image. "D" will delete the text.
Next, define the commands for each selection. Hit F10 to enter the commands. You now can key in the commands for selections 1 through 99. After hitting F10, you should see:
Define Menu Commands
Menu . . . . . . : STARTMEN Position to menu option . .
76
Type commands, press Enter.
Option Command
01
02
03
04
05
06
07
Here, you enter the commands associated with each selection. So enter the commands like this:
Define Menu Commands
Menu . . . . . . : STARTMEN Position to menu option .
Type commands, press Enter.
Option Command
01 runqry csq001
77
02 runqry csq002
03 call tutr005
04 RUNQRY QRYFILE(CUST)
05 wrksplf
06
07
Then, hit page down so you can enter SIGNOFF as the command for selection 10. You can enter any command that you want the user to run. You can run queries, submit print queries to run in batch and use standard utility commands such as "Work with Spool Files", WRKSPLF. Finally, you can help the user navigate to another menu with the "GO" command used for selection 6. Hit F3 a few times to exit. When you exit SDA, check the "object library" name. This is where your compiled menu objects will go.
Your screen should look like:
Exit SDA Menus
File . . . . . . : QDDSSRC DDS member . . . . . : STARTMEN
Library . . . . : USER999 Commands member . . . : STARTMENQQ
Type choices, press Enter.
Save new or updated menu source . . . . Y Y=Yes, N=No
For choice Y=Yes:
Source file . . . . . . . . . . . . QDDSSRC Name,
F4 for list
Library . . . . . . . . . . . . . USER999 Name, *LIBL, *CURLI
Text . . . . . . . . . . . . . . . .
78
Replace menu members . . . . . . . . Y Y=Yes, N=No
Create menu objects . . . . . . . . . . Y Y=Yes, N=No
For choice Y=Yes:
Prompt for parameters . . . . . . . N Y=Yes, N=No
Object library . . . . . . . . . . . USER999 Name, *CURLIB
Replace menu objects . . . . . . . . Y Y=Yes, N=No
Wait! Let me say again - the value near the bottom of the screen - Object Library - must be your user library. Otherwise you will create your menu somewhere else. Hit enter and the AS/400 will compile your source code and your menu will be ready to run. SDA creates three objects, all with the same name: the commands, the display file and a message file for the menu. If you want some added fun, go back to the menu source using SDA and this time make the selection to "work with menu help". Here you can define help screens that will display if your user enters the selection number and hits F1. Now you can tie this menu to your new employee's user profile. Use the command to change your profile,CHGPRF. From a command line key CHGPRF and hit F4.
You should see a screen like:
Change Profile (CHGPRF)
Type choices, press Enter.
Assistance level . . . . . . . . *SYSVAL *SAME, *SYSVAL, *BASIC...
Current library . . . . . . . . *crtdft Name, *SAME, *CRTDFT
Initial program to call . . . . SOC000 Name, *SAME, *NONE
Library . . . . . . . . . . . SOLIB Name, *LIBL, *CURLIB
Initial menu . . . . . . . . . . MAIN Name, *SAME, *SIGNOFF
Library . . . . . . . . . . . *LIBL Name, *LIBL, *CURLIB
Text 'description' . . . . . . . 'your email address'
When you sign on to the AS/400, these values tell the operator what your current library should be and what menu is your default menu. Presently, your current library is probably *CRTDFT which is a system value that means "NONE". Your initial menu is named MAIN. This is the menu you have gotten accustomed to seeing when you sign on. Change your current library from *CRTDFT to your user library.
79
Also change your initial menu to STARTMEN. Make the LIBRARY value under your initial menu your user library. Your screen should look like:
Change Profile (CHGPRF)
Type choices, press Enter.
Assistance level . . . . . . . . *SYSVAL *SAME, *SYSVAL, *BASIC
Current library . . . . . . . . USER999 Name, *SAME, *CRTDFT
Initial program to call . . . . SOC000 Name, *SAME, *NONE
Library . . . . . . . . . . . SOLIB Name, *LIBL, *CURLIB
Initial menu . . . . . . . . . . STARTMEN Name, *SAME, *SIGNOFF
Library . . . . . . . . . . . USER999 Name, *LIBL, *CURLIB
Text 'description' . . . . . . . 'your email address'
If you sign off and sign back on, you will see your new menu. By the way, if you set it up wrong, you may have to e-mail me to reset your profile. For example, if you changed your profile to run the menu ABCDEF as the initial menu, the AS/400 won't know what to do (since there is no ABCDEF menu). If you want to see the familiar sign on screen, key in the command GO MAIN. It's that easy to customize the screen selections for a user.
Using SDA to set up a simple Help Screen
One of the most intuitive development tools on the AS/400 is SDA, Screen Design Aid. With it, you build display screens and menus in a WYSIWYG (what you see is what you get) mode. We're going to look at how easy it is to create a simple help screen.
In only a few minutes, you can build a custom help screen for your user. Start SDA with the command STRSDA. You will see that SDA has three functions:
1) Design Screens2) Design Menus3) Test Display Files
Use selection 2 to design a menu. Enter the name of your menu, where you have stored the source (usually QDDSSRC) and the library that it is in.
Now choose the selection to "Work with menu help" by changing the "N" to a "Y". Here you can define help screens that will display if your user enters a selection number and hits F1.
This is where you will "Create" the text for your help screen. You will also have 3 Range Options to choose from.
80
Valid ranges are:
00-00 General help for the entire menu.
nn-nn Where nn is a number between 01 and 99. This is specific help for one option of
the menu.
nn-mm Where nn is a number between 00 and 99 and mm is a number between 01 and 99 and
is greater that nn. This is help for a range of options on your menu.
Note: You cannot create more than a single page of help for each range of options.
You will see this screen displayed. Type in a 1 for Create in the Opt field, and 01 - 01 in the Range field. The 01 is only used for Selection 1 of your main menu selection. Option 02 is for Selection 2, etc..
Work with Menu Help Records
File . . . . . . : QDDSSRC Menu . . . . . . . : MRCM001
Library . . . . : User999
Type options (and Range), press Enter.
1=Create 3=Copy 4=Delete 12=Update
Opt Range Text
___ __ - __
81
Bottom
F3=Exit F5=Refresh F9=Display image F12=Cancel
Create Menu Help Record
File . . . . . . : QDDSSRC Menu . . . . . . . : MRCM001
Library . . . . : USER999
Type choices, press Enter.
Create help for option . . . . . . . . . . . . . . . 01 01-99
-OR-
Create help for option range (range xx-yy)
From menu option . . . . . . . . . . . . . . . . . ___ 00-99
To menu option . . . . . . . . . . . . . . . . . . ___ 01-99
-OR-
Create general help (range 00-00) . . . . . . . . . . N Y=Yes, N=No
82
F3=Exit F5=Refresh F9=Display image F12=Cancel
From here, you will press Enter, a blank screen will appear and now you can type in the text
you want for your help screen.
Once you have created the text help for each option you chose, you should see the following
screen with your enhancements:
Work with Menu Help Records
File . . . . . . : QDDSSRC Menu . . . . . . . : MRCM001
Library . . . . : User999
Type options (and Range), press Enter.
1=Create 3=Copy 4=Delete 12=Update
Opt Range Text
-
01 - 01 Run Customer Query
02 - 02 Print Customer Query
03 - 03 Change Address in Customer File
04 - 04 Show Customer File
05 - 05 Work with Printer Files
83
Bottom
F3=Exit F5=Refresh F9=Display image F12=Cancel
When you exit SDA, check the "object library" name. This is where your compiled menu objects will go. Hit enter and the AS/400 will compile your source code and your menu will be ready to run. SDA creates three objects, all with the same name: the commands, the display file and a message file for the menu.
When you run the menu you have created, type in selection 1 and press F1, when you do this you will see the following help screen.
HELP Running Customer Query Information
This option will run the Customer Query. The information of
this query will show you the Customer Name, Customer Number
and Address.
Hit F3 to Exit, and Enter to run query.
84
F3=Exit F12=Cancel
You can also use SDA to test and design display files. With the "Test Display Files" selection of SDA, you can see the fields and presentation of a display file. This works even if you don't have the source code.
Use selection 25 in PDM to search through source code.
There are a couple of ways to search through source code for information you are looking for (ie. program names, files, attributes, etc.). The 1st way is to do a search on a single or multi-program file level through the work with members option, in which you search only specific program(s) for your information. The other way is to do a search through an entire object such as QRPGLESRC or QDDSSRC.
In using the 1st method, start the Program Development Manager (STRPDM), and use option 3 to 'Work with members'.
You will see this screen pop up.
AS/400 Programming Development Manager (PDM)
Select one of the following:
1. Work with libraries
2. Work with objects
3. Work with members
4. Work with projects
5. Work with groups
6. Work with parts
9. Work with user-defined options
85
Selection or command
F3=Exit F4=Prompt F9=Retrieve F10=Command entry
F12=Cancel F18=Change defaults
Now type in the needed information for the file and library to which you want to
conduct the search.
Specify Members to Work With
Type choices, press Enter.
File . . . . . . . . . . QRPGLESRC Name, F4 for list
Library . . . . . . . . USER999 *LIBL, *CURLIB, name
Member:
Name . . . . . . . . . *ALL *ALL, name, *generic*
Type . . . . . . . . . *ALL *ALL, type, *generic*, *BLANK
From here, type in 25 in the Opt space of the Member you would like to do the search on.
If you would like to check all the programs listed on this members screen, simple hit
86
F13 (Shift F1) and you will see that 25 is filled in on all the options.
Work with Members Using PDM S103C160
File . . . . . . QRPGLESRC
Library . . . . USER999 Position to . . . . .
Type options, press Enter.
2=Edit 3=Copy 4=Delete 5=Display 6=Print 7=Rename
8=Display description 9=Save 13=Change text 14=Compile 15=Create module..
Opt Member Type Text
25 ABC101 RPGLE Add all ABC customers
25 ABC102 RPGLE Add CSBTN to customer file
25 ABC400 RPGLE SUBFILE for ABC pgm
25 SAM001 RPGLE Parse leads for Sample pgm
25 SAM002 RPGLE 1 time program to populate ADDR field
25 SAM003 RPGLE Subfile maintenance for Sample pgm Leads
25 SAM004 RPGLE Dup check leads Sample pgm
More...
Parameters or command
===>
F3=Exit F4=Prompt F5=Refresh F6=Create
F9=Retrieve F10=Command entry F23=More options F24=More keys
87
Now hit Enter, and you will see the Find String screen. In the blank to the right of "Find",
type in the information you are seeking and press enter. In this example we are looking for
all the programs that use the Physical File ABP001.
Find String
Type choices, press Enter.
Find . . . . . . . . . . . . . . ABP001___________________
From column number . . . . . . 1 1 - *RCDLEN
To column number . . . . . . . *RCDLEN 1 - *RCDLEN
Kind of match . . . . . . . . 2 1=Same case, 2=Ignore case
Option . . . . . . . . . . . . . 2 *NONE, Valid option
Prompt . . . . . . . . . . . . N Y=Yes, N=No
Print list . . . . . . . . . . . N Y=Yes, N=No
Print records . . . . . . . . . N Y=Yes, N=No
Number to find . . . . . . . . *ALL *ALL, number
Print format . . . . . . . . . *CHAR *CHAR, *HEX, *ALTHEX
Mark record . . . . . . . . . Y Y=Yes, N=No
Record overflow . . . . . . . 1 1=Fold, 2=Truncate
Find string in batch . . . . . . N Y=Yes, N=No
Parameters . . . . . . . . . . .
F3=Exit F5=Refresh F12=Cancel F16=User options
F18=Change defaults
88
You can see now that the search found the PF in program ABC102. Hit Enter to continue the
search, and it will look through all the files you have chosen and will pop up the screen
when it finds the PF once again.
Columns . . . : 6 76 Edit USER999/QRPGLESRC
SEU==> ABC102
FMT FX FFilename++IPEASF.....L.....A.Device+.Keywords+++++++++++++++++++++++++
*************** Beginning of data *************************************
0001.00 FABP001 IF E DISK
0002.00 FBT O E DISK
0003.00 *---------------------------------------------------------------------
0004.00 C DoW *In90 = *Off
0005.00 C Read ABD001 90
0006.00 C If *In90 = *Off and
0007.00 C ABCRNTO = *Zero and
0008.00 C ABBTN > 2000000000
0009.00 C Eval BTBTN = CSBTN
0010.00 C Write ABDREC
0011.00 C EndIf
0012.00 C EndDo
0013.00 C Eval *Inlr = *On
0014.00 C Return
0015.00 *---------------------------------------------------------------------
89
0016.00 *---------------------------------------------------------------------
F3=Exit F4=Prompt F5=Refresh F9=Retrieve F10=Cursor F11=Toggle
F16=Repeat find F17=Repeat change F24=More keys
Another method to conduct the search is through Option 2 of the PDM. Here is where
you work with objects. Once again, type in your Library name, and for Object name, type in Q*.
This will list all of the Q objects, such as QDDSSRC, QRPGSRC, etc...
Specify Objects to Work With
Type choices, press Enter.
Library . . . . . . . . . . USER999 *CURLIB, name
Object:
Name . . . . . . . . . . . Q* *ALL, name, *generic*
Type . . . . . . . . . . . *ALL *ALL, *type
Attribute . . . . . . . . *ALL *ALL, attribute, *generic*,
*BLANK
The next screen you see will contain the specified objects. Now all you need to do is type
in 25 in the object you want to do the search in, and it will search through all files/programs
90
associated with that object.
Work with Objects Using PDM S103C160
Library . . . . . USER999 Position to . . . . . . . .
Position to type . . . . .
Type options, press Enter.
2=Change 3=Copy 4=Delete 5=Display 7=Rename
8=Display description 9=Save 10=Restore 11=Move ...
Opt Object Type Attribute Text
__ QCLSRC *FILE PF-SRC
__ QCMDSRC *FILE PF-SRC
__ QDDSSRC *FILE PF-SRC
25 QRPGLESRC *FILE PF-SRC
__ QRPGSRC *FILE PF-SRC
Bottom
Parameters or command
===>
F3=Exit F4=Prompt F5=Refresh F6=Create
F9=Retrieve F10=Command entry F23=More options F24=More keys
91
Now hit Enter, and the search will begin through all the members associated with the object you
have chosen to search. You will notice the same result as above was located in the search.
So there you have it, 2 different ways of conducting a search for information using Option 25 in
PDM.
Using Output Specs to Print a Report
There are 3 ways that reports get printed using RPG.
The oldest and obsolete method uses the RPG cycle and is not covered in this tutorial.
The next and most widely used is covered in this topic. The report is formatted using Output Specs. These are identified with the letter O. Be sure to use F4 when entering O specs because they have many options.
An O spec is written by using the EXCEPT operation. This comes from the history of RPG. When using the RPG cycle, the O Specs are automatically written. When you don't use the RPG cycle, the O Specs are written as an EXCEPTion to the cycle.
The F spec for the printer file QPRINT identifies an indicator which the AS/400 turns *ON when the page is full.
The third way of printing will be covered in the next topic. It uses a printer file defined using DDS specs
Writing a Print Program in RPG with O specs
This is the RPG program for writing a Print Report using O Specs. At the bottom, you will see a sample of the report layout in the spool file.
Columns . . . : 1 71 Edit USER000/QRPGSRC
SEU==> TUTR005
FMT FX .....FFilenameIPEAF........L..I........Device+......KExit++Entry+A....U
*************** Beginning of data *************************************
0001.00 FCUST IF E DISK
92
0002.00 * The AS/400 includes a pre-defined printer file named QPRINT
0003.00 * Here, I use indicator 10 as the overflow indicator
0004.00 * That means that *IN10 will be *ON when the printed page
0005.00 * is full.
0006.00 FQPRINT O F 132 10 PRINTER
0007.00 *----------------------------------------------------------------
0008.00 C* Print the heading
0009.00 C EXCPTHEADS
0010.00 C* Read the first record
0011.00 C READ CUST 90
0012.00 C*
0013.00 C *IN90 DOWEQ*OFF
0014.00 C* See if the page is full. If so, print the heading.
0015.00 C *IN10 IFEQ *ON
0016.00 C EXCPTHEADS
0017.00 C MOVE *OFF *IN10
0018.00 C ENDIF
0019.00 C* Print the detail
0020.00 C EXCPTDETAIL
0021.00 C READ CUST 90
0022.00 C ENDDO
0023.00 C*
0024.00 C MOVE *ON *INLR
0025.00 C RETRN
0026.00 *----------------------------------------------------------------
0027.00 OQPRINT E 202 HEADS
93
0028.00 O 6 'PAGE'
0029.00 C* PAGE is a system value that will keep track of the page#
0030.00 O PAGE 10
0031.00 O 47 'CUSTOMER ORDER REPORT'
0032.00 O 65 'DATE'
0033.00 C* UDATE is a system value that is today's date
0034.00 C* The edit code Y will edit the date like xx/xx/xx
0035.00 O UDATE Y 75
0036.00 O*
0037.00 O E 1 HEADS
0038.00 O 61 '# OPEN'
0039.00 O 71 'AMT OPEN'
0040.00 O*
0041.00 O E 1 HEADS
0042.00 O 17 'CUST #'
0043.00 O 23 'NAME'
0044.00 O 61 'ORDERS'
0045.00 O 70 'ORDERS'
0046.00 O*
0047.00 O E 1 DETAIL
0048.00 O CSNBR 17
0049.00 O CSNAME 49
0050.00 C* The edit code 1 will edit the amount like 1,234.50
0051.00 O CS#OPN1 60
0052.00 O CS$OPN1 70
****************** End of data ****************************************
94
Once you have written the program, compile it using option 14. After you have compiled the
program, you want to call it and see what the report looks like. To call the program, simply
type on the command line: CALL PGM(USER000/TUTROO5)
Next, go to the Work Spool File (WRKSPLF), find the program, and key in a 5 to view the report.
This is what the report will look like:
PAGE 1 CUSTOMER ORDER REPORT DATE 11/14/02
# OPEN AMT OPEN
CUST # NAME ORDERS ORDERS
001002 E LUMPKIN 0 .00
001084 CHISOLM 0 .00
001105 HAGGINS 0 .00
001109 BYRD 0 .00
001168 ROMERO 0 .00
001177 POUNDS 0 .00
001183 HINTON 0 .00
001184 YANCEY 0 .00
95
001186 MCDOUGLE 0 .00
001202 DAVIS 0 .00
001208 TARVIN 0 .00
001214 GOOSEBERRY 0 .00
001234 REID 0 .00
001239 COLBERT 0 .00
001259 BLACKMON 0 .00
001264 CRANFORD 0 .00
001266 DODSON 0 .00
001269 LENSON 0 .00
001274 JACKSON 0 .00
001284 TAPER 0 .00
001287 WILLIAMS 0 .00
001293 FEAZELL 0 .00
001294 MC CULLUM 0 .00
001301 SMITH 0 .00
001303 MCGHEE 0 .00
001308 WALLACE 0 .00
96
001318 ROBINSON 0 .00
001321 SPIVEY 0 .00
001322 HILLARD 0 .00
PAGE 2 CUSTOMER ORDER REPORT DATE 11/14/02
# OPEN AMT OPEN
CUST # NAME ORDERS ORDERS
001480 BAILEY 0 .00
001485 POLLARD 0 .00
001492 JORDAN 0 .00
001502 EVERETT 0 .00
001504 HIGGINS 0 .00
001509 JONES 0 .00
001523 BENDER 0 .00
001539 BUDD 0 .00
001557 KINSEY 0 .00
001561 PILKINGTON 0 .00
001579 HAWKINS 0 .00
001583 MOBBS 0 .00
97
001584 SELLERS 0 .00
001587 WALKER 0 .00
001591 SLACK 0 .00
001604 HINKLE 0 .00
001606 ALLEN 0 .00
Writing a Print Program in RPG-ILE with O specs
This is the RPG-ILE program for writing a Print Report using O Specs. At the bottom, you will see a sample of the report layout in the spool file.
Columns . . . : 6 76 Edit USER000/QRPGLESRC
SEU==> TUTR006
FMT FX FFilename++IPEASF.....L.....A.Device+.Keywords+++++++++++++++++++++++++
*************** Beginning of data *************************************
0001.00 FCUST IF E DISK
0002.00 * The AS/400 includes a pre-defined printer file named QPRINT
0003.00 * Here, I use indicator 10 as the overflow indicator
0004.00 * That means that *IN10 will be *ON when the printed page
0005.00 * is full.
0006.00 FQPRINT O F 132 PRINTER OFLIND(*In10)
0007.00 *----------------------------------------------------------------
0008.00 C* Print the heading
0009.00 C Except Headings
98
0010.00 C* Read the first record
0011.00 C Read CSREC 90
0012.00 C*
0013.00 C DoW *In90 = *Off
0014.00 C* See if the page is full. If so, print the heading.
0015.00 C If *In10 = *On
0016.00 C Except Headings
0017.00 C Eval *In10 = *Off
0018.00 C EndIf
0019.00 C Except Detail
0020.00 C Read CSREC 90
0021.00 C EndDo
0022.00 C*
0023.00 C Eval *InLR = *On
0024.00 C Return
0025.00 *----------------------------------------------------------------
0026.00 OQPRINT E Headings 2 2
0027.00 O 6 'PAGE'
0028.00 C* PAGE is a system value that will keep track of the page#
0029.00 O Page 10
0030.00 O 47 'CUSTOMER ORDER REPORT'
0031.00 O 65 'DATE'
0032.00 C* UDATE is a system value that is today's date
0033.00 C* The edit code Y will edit the date like xx/xx/xx
0034.00 O Udate Y 75
0035.00 O*
0036.00 O E Headings 1
99
0037.00 O 61 '# OPEN'
0038.00 O 71 'AMT OPEN'
0039.00 O*
0040.00 O E Headings 1
0041.00 O 17 'CUST #'
0042.00 O 23 'NAME'
0043.00 O 61 'ORDERS'
0044.00 O 70 'ORDERS'
0045.00 O*
0046.00 O E Detail 1
0047.00 O CSNBR 17
0048.00 O CSNAME 49
0049.00 C* The edit code 1 will edit the amount like 1,234.50
0050.00 O CS#OPN 1 60
0051.00 O CS$OPN 1 70
****************** End of data ****************************************
Once you have written the program, compile it using option 14. After you have compiled the
program, you want to call it and see what the report looks like. To call the program, simply
type on the command line: CALL PGM(USER000/TUTROO5)
Next, go to the Work Spool File (WRKSPLF), find the program, and key in a 5 to view the report.
This is what the report will look like:
100
PAGE 1 CUSTOMER ORDER REPORT DATE 11/14/02
# OPEN AMT OPEN
CUST # NAME ORDERS ORDERS
001002 E LUMPKIN 0 .00
001084 CHISOLM 0 .00
001105 HAGGINS 0 .00
001109 BYRD 0 .00
001168 ROMERO 0 .00
001177 POUNDS 0 .00
001183 HINTON 0 .00
001184 YANCEY 0 .00
001186 MCDOUGLE 0 .00
001202 DAVIS 0 .00
001208 TARVIN 0 .00
001214 GOOSEBERRY 0 .00
001234 REID 0 .00
001239 COLBERT 0 .00
001259 BLACKMON 0 .00
101
001264 CRANFORD 0 .00
001266 DODSON 0 .00
001269 LENSON 0 .00
001274 JACKSON 0 .00
001284 TAPER 0 .00
001287 WILLIAMS 0 .00
001293 FEAZELL 0 .00
001294 MC CULLUM 0 .00
001301 SMITH 0 .00
001303 MCGHEE 0 .00
001308 WALLACE 0 .00
001318 ROBINSON 0 .00
001321 SPIVEY 0 .00
001322 HILLARD 0 .00
PAGE 2 CUSTOMER ORDER REPORT DATE 11/14/02
# OPEN AMT OPEN
CUST # NAME ORDERS ORDERS
001480 BAILEY 0 .00
102
001485 POLLARD 0 .00
001492 JORDAN 0 .00
001502 EVERETT 0 .00
001504 HIGGINS 0 .00
001509 JONES 0 .00
001523 BENDER 0 .00
001539 BUDD 0 .00
001557 KINSEY 0 .00
001561 PILKINGTON 0 .00
001579 HAWKINS 0 .00
001583 MOBBS 0 .00
001584 SELLERS 0 .00
001587 WALKER 0 .00
001591 SLACK 0 .00
001604 HINKLE 0 .00
001606 ALLEN 0 .00
Using DDS Specs to Print a Report
As mentioned in the previous topic, there are 3 ways that reports get printed using RPG.
This topic will look at how to print using a print file defined with DDS specs.
103
In an earlier topic, we saw how to use DDS to define a physical file and a logical file. DDS is also used to define print files and display files. A future topic will discuss display files.
A display and print file are different from a physical file in two ways:1) A physical file can have only 1 record definition.2) A print file and a display file are really defining different records, not data. I think of print files as a buffer in memory that describes a print line.
To create the print file, STRPDM and add a member to QDDSSRC in your library. Make sure the TYPE is PRTF.
Add a member named CUSW007. Enter the specs shown in the DDS attachment. Or if you are lazy, copy it from library USER000.
Columns . . . : 1 71 Edit USER000/QDDSSRC
SEU==> CUSW007
FMT A* .....A*. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7
*************** Beginning of data *************************************
0001.00 A* THE NEXT LINE TELLS THE COMPILER TO LOOK IN THIS FILE
0002.00 A* FOR FIELDS THAT USE THE R FOR REFERENCE
0003.00 A REF(CUST)
0004.00 A* SKIPB(1) MEANS SKIP TO THE TOP OF THE NEXT PAGE BEFORE
0005.00 A* PRINTING THE HDG1 RECORD
0006.00 A R HDG1
0007.00 A SKIPB(1)
0008.00 A 2DATE(*YY)
0009.00 A 26'CUSTOMER ORDER REPORT'
0010.00 A 60'PAGE'
0011.00 A 67PAGNBR
0012.00 A* SPACEA(2) MEANS TO SPACE DOWN 2 LINES AFTER THE HDG1 RECORD
0013.00 A SPACEA(2)
104
0014.00 A*----------------------------------------------------------------
0015.00 A R HDG2
0016.00 A SPACEA(1)
0017.00 A 48'# OPEN'
0018.00 A 59'AMT OPEN'
0019.00 A*----------------------------------------------------------------
0020.00 A R HDG3
0021.00 A SPACEA(1)
0022.00 A 2'CUST #'
0023.00 A 10'CUSTOMER NAME'
0024.00 A 48'ORDERS'
0025.00 A 60'ORDERS'
0026.00 A SPACEA(2)
0027.00 A*----------------------------------------------------------------
0028.00 A R DETAIL
0029.00 A SPACEA(001)
0030.00 A CSNBR 6S 0O 2
0031.00 A CSNAME 30A O 10
0032.00 A* THE EDTCDE(1) INDICATES TO EDIT THE NUMERIC FIELD USING
0033.00 A* THE SYSTME DEFINED CODE OF 1. THIS IS WITH COMMAS, DECIMALS
0034.00 A* AND NEGATIVE SIGN
0035.00 A CS$OPN R O 45EDTCDE(1)
0036.00 A CS#OPN R O 58EDTCDE(1)
0037.00 A*----------------------------------------------------------------
0038.00 A R TOTAL
105
0039.00 A SPACEA(001)
0040.00 A 30'TOTAL'
0041.00 A TOTOPN 9S 2O 58EDTCDE(1)
****************** End of data ****************************************
I have chosen to use the same field names in the print file as the input file that I will read. I could have used different field names, but RPG handles fields with identical names in an interesting way.
If a field is defined in more than one place:1) it must be the same length and type in all places.2) the most recently assigned value will be used for all occurrences of the field.
So, since we use the same values in the print file as the input, we need only read the input file and write the print records. As before, we still need to take care of headings and page control.
To show you different techniques, I stated the length and type of CSNBR and CSNAME in the DDS. For the other fields, I put in R in the REF column. This tells the compiler to look for the field with this name in the file named at the top in the REF option. It gets the field type and length from the file CUST since that is the file named in the REF parameter. Defined fields using the REF technique are easier and preferred.
If you are familiar with RLU (Report Layout Utility), you could use it to create the DDS for the print file. RLU is confusing to most AS/400 programmers and is not widely used.
When you have entered the DDS, use option 14 to compile it. Since the type is PRTF, the AS/400 compiler knows to execute command CRTPRTF.
Then, enter the RPG or RPG-ILE source code and compile. Notice that the RPG programs use the printer file as the output file.
Call the program from the command line and a print file will be created. Use WRKSPLF to see it.
Writing an RPG Print Program using DDS
This is the RPG program for writing a Print Report using DDS. At the bottom, you will see a sample of the report layout in the spool file.
Columns . . . : 1 71 Edit USER000/QRPGSRC
SEU==> TUTR007
FMT FX .....FFilenameIPEAF........L..I........Device+......KExit++Entry+A....U
*************** Beginning of data *************************************
106
0001.00 FCUST IF E DISK
0002.00 * The AS/400 includes a pre-defined printer file named QPRINT
0003.00 * Here, I use indicator 10 as the overflow indicator
0004.00 * That means that *IN10 will be *ON when the printed page
0005.00 * is full.
0006.00 FCUSW007 O E 10 PRINTER
0007.00 *----------------------------------------------------------------
0008.00 C* Print the heading
0009.00 C WRITEHDG1
0010.00 C WRITEHDG2
0011.00 C WRITEHDG3
0012.00 C* Read the first record
0013.00 C READ CUST 90
0014.00 C*
0015.00 C *IN90 DOWEQ*OFF
0016.00 C* See if the page is full. If so, print the heading.
0017.00 C *IN10 IFEQ *ON
0018.00 C WRITEHDG1
0019.00 C WRITEHDG2
0020.00 C WRITEHDG3
0021.00 C MOVE *OFF *IN10
0022.00 C ENDIF
0023.00 C* Print the detail
0024.00 C WRITEDETAIL
0025.00 C READ CUST 90
0026.00 C ENDDO
0027.00 C*
107
0028.00 C MOVE *ON *INLR
0029.00 C RETRN
****************** End of data ****************************************
Once you have written the program, compile it using option 14. After you have compiled the
program, you want to call it and see what the report looks like. To call the program, simply
type on the command line: CALL PGM(USER000/TUTROO7)
Next, go to the Work Spool File (WRKSPLF), find the program, and key in a 5 to view the report.
This is what the report will look like:
11192002 CUSTOMER ORDER REPORT PAGE 0001
# OPEN AMT OPEN
CUST # CUSTOMER NAME ORDERS ORDERS
001002 E LUMPKIN .00 0
001084 CHISOLM .00 0
001105 HAGGINS .00 0
001109 BYRD .00 0
001168 ROMERO .00 0
001177 POUNDS .00 0
001183 HINTON .00 0
001184 YANCEY .00 0
001186 MCDOUGLE .00 0
001202 DAVIS .00 0
108
001208 TARVIN .00 0
001214 GOOSEBERRY .00 0
001234 REID .00 0
001239 COLBERT .00 0
001259 BLACKMON .00 0
001264 CRANFORD .00 0
001266 DODSON .00 0
001269 LENSON .00 0
001274 JACKSON .00 0
001284 TAPER .00 0
001287 WILLIAMS .00 0
001293 FEAZELL .00 0
001294 MC CULLUM .00 0
001301 SMITH .00 0
001303 MCGHEE .00 0
001308 WALLACE .00 0
001318 ROBINSON .00 0
11192002 CUSTOMER ORDER REPORT PAGE 0002
# OPEN AMT OPEN
CUST # CUSTOMER NAME ORDERS ORDERS
001480 VALLIERE .00 0
001480 BAILEY .00 0
001485 POLLARD .00 0
001492 JORDAN .00 0
001502 EVERETT .00 0
001504 HIGGINS .00 0
001509 JONES .00 0
001523 BENDER .00 0
109
001539 BUDD .00 0
001557 KINSEY .00 0
001561 PILKINGTON .00 0
001579 HAWKINS .00 0
001583 MOBBS .00 0
001584 SELLERS .00 0
001587 WALKER .00 0
001591 SLACK .00 0
001604 HINKLE .00 0
001606 ALLEN .00 0
001608 R MALONE .00 0
001614 JACKSON .00 0
Writing an RPG Print Program using DDS
This is the RPG program for writing a Print Report using DDS. At the bottom, you will see a sample of the report layout in the spool file.
Columns . . . : 6 76 Edit USER000/QRPGLESRC
SEU==> TUTR008
FMT FX FFilename++IPEASF.....L.....A.Device+.Keywords+++++++++++++++++++++++++
*************** Beginning of data *************************************
0001.00 FCUST IF E DISK
0002.00 * The AS/400 includes a pre-defined printer file named QPRINT
0003.00 * Here, I use indicator 10 as the overflow indicator
0004.00 * That means that *IN10 will be *ON when the printed page
0005.00 * is full.
110
0006.00 FCUSW007 O E PRINTER OFLIND(*In10)
0007.00 *----------------------------------------------------------------
0008.00 C* Print the heading
0009.00 C Write Hdg1
0010.00 C Write Hdg2
0011.00 C Write Hdg3
0012.00 C* Read the first record
0013.00 C Read CSREC 90
0014.00 C*
0015.00 C DoW *In90 = *Off
0016.00 C* See if the page is full. If so, print the heading.
0017.00 C If *In10 = *On
0018.00 C Write Hdg1
0019.00 C Write Hdg2
0020.00 C Write Hdg3
0021.00 C Eval *In10 = *Off
0022.00 C EndIf
0023.00 C Write Detail
0024.00 C Read CSREC 90
0025.00 C EndDo
0026.00 C*
0027.00 C Eval *InLR = *On
0028.00 C Return
****************** End of data ****************************************
111
Once you have written the program, compile it using option 14. After you have compiled the
program, you want to call it and see what the report looks like. To call the program, simply
type on the command line: CALL PGM(USER000/TUTROO8)
Next, go to the Work Spool File (WRKSPLF), find the program, and key in a 5 to view the report.
This is what the report will look like:
11192002 CUSTOMER ORDER REPORT PAGE 0001
# OPEN AMT OPEN
CUST # CUSTOMER NAME ORDERS ORDERS
001002 E LUMPKIN .00 0
001084 CHISOLM .00 0
001105 HAGGINS .00 0
001109 BYRD .00 0
001168 ROMERO .00 0
001177 POUNDS .00 0
001183 HINTON .00 0
001184 YANCEY .00 0
001186 MCDOUGLE .00 0
001202 DAVIS .00 0
001208 TARVIN .00 0
001214 GOOSEBERRY .00 0
001234 REID .00 0
001239 COLBERT .00 0
001259 BLACKMON .00 0
001264 CRANFORD .00 0
112
001266 DODSON .00 0
001269 LENSON .00 0
001274 JACKSON .00 0
001284 TAPER .00 0
001287 WILLIAMS .00 0
001293 FEAZELL .00 0
001294 MC CULLUM .00 0
001301 SMITH .00 0
001303 MCGHEE .00 0
001308 WALLACE .00 0
001318 ROBINSON .00 0
11192002 CUSTOMER ORDER REPORT PAGE 0002
# OPEN AMT OPEN
CUST # CUSTOMER NAME ORDERS ORDERS
001480 VALLIERE .00 0
001480 BAILEY .00 0
001485 POLLARD .00 0
001492 JORDAN .00 0
001502 EVERETT .00 0
001504 HIGGINS .00 0
001509 JONES .00 0
001523 BENDER .00 0
001539 BUDD .00 0
001557 KINSEY .00 0
001561 PILKINGTON .00 0
001579 HAWKINS .00 0
001583 MOBBS .00 0
001584 SELLERS .00 0
113
001587 WALKER .00 0
001591 SLACK .00 0
001604 HINKLE .00 0
001606 ALLEN .00 0
001608 R MALONE .00 0
001614 JACKSON .00 0
RPG Program to Change Database Records Using a Display File
Finally, we get to the fun stuff! Hold on tight because things are about to get a lot more complicated.
Up to now, you have learned about the Control Language of the AS/400. You have also been introduced to DDS. In fact, you have seen how to use DDS to define a Physical File, a Logical File and a Print File. You have also seen some simple RPG programs.
Now, we will use DDS to create a Display File. Then, we will write a program to look up a Customer# record and change it. In the next topic, we will add the ability to enter new records and to delete records. Then, we will modify the program search by customer name.
Rather than talk you through all of the details, I am showing you the source code with lots of comments. There are so many comments that it looks harder than it is. So, I have also provided source code without the comments.
First, you must create a display file. This is often thought of as a screen map. It maps fields and characters on the screen. Each record in the display file is a different screen.
You can copy the display file from the USER000 library or key it in yourself.
Before you get started, try using SDA to view the screens that I have created in USER000. First, start SDA with the command STRSDA. Use selection 3 to TEST DISPLAY FILES. For the display file, use TUTD010. For library, use USER000. For RECORD TO BE TESTED, put the cursor in the field and hit F4. SDA will list all records defined. Select a record and hit ENTER a few times to see the screen.
To use SDA this way, the display file must already be created. That is, the source code must have been entered and it must have been compiled successfully.
Now that you can see what you want to create, try keying in the source code.
To key it in, STRPDM. Use option 3. Fill in file QDDSSRC, in your library for *ALL member names. Use F6 to add the member TUTD010. Make sure the TYPE is DSPF (for DISPLAY FILE).
When entering source code lines, try using F4 to prompt the fields. To turn off prompting, hit F12.
Click here to see the source code with all the comments. This is TUTD010 in QDDSSRC in USER000.
Click here to see the source code without all the comments. This is TUTD011 in QDDSSRC in USER000.
114
When you are finished, compile the source code with option 14. This is running the command CRTDSPF (Create Display File). When you are done, try using SDA again to test your display file.
If you have gotten this far, pat yourself on the back.
Now, we need to write the RPG program.
The program will display the first screen, SCRN1. The user will enter an A to add, C to CHANGE or D to DELETE. But for this portion, we will only program the CHANGE logic. In the next topice, we will add the ADD and DELETE logic.
The user also must enter a Customer #.
The program will first check to make sure that a C for CHANGE was entered. It then looks in the CUST database file for the Customer #. If either of these conditions is not met, the program moves an error message to the field DSPMSG and shows SCRN1 again.
If a Customer # is found, the program shows SCRN2. This screen shows the values in the record. If the user changes any values and hits ENTER, the program will rewrite the changes to the database.
Click here to see the RPG III source code with all the comments. This is TUTR010 in QRPGSRC in USER000.
TUTR010 in QRPGSRC in USER000
* Define the CUST file with file type U for UPDATE
* (update means that you can read and re-write data)
* and with record address type K for Keyed.
* (Keyed means the data can be directly read using the key field
FCUST UF E K DISK
* Next, define the display file. It must already exist.
* The C indeicates combined input and output. WORKSTN is
* always used to indicate a display file.
FTUTD010 CF E WORKSTN
*----------------------------------------------------------------
I* This next few statements define constants that will be used
I* as error messages
I 'You must enter A, C,-C ERR1
I ' or D'
115
I 'Customer # is not fo-C ERR2
I 'und'
I 'Name cannot be blank'C ERR3
I 'Addr cannot be blank'C ERR4
I 'City cannot be blank'C ERR5
I 'State cannot be blan-C ERR6
I 'k'
I 'Zip is invalid' C ERR7
*---------------------------------------------------------------
C* This is the main loop.
C* It will continue to show the first screen until F3 is pressed.
C* When F3 is pressed, *IN03 will be truned *ON
C *IN03 DOWEQ*OFF
C* The next statement, executes the format (EXFMT) for SCRN1.
C* EXFMT displays the SCRN1 and waits until the user presses
C* ENTER or F3. Then, it continues to the next statement.
C EXFMTSCRN1
C* If F3 was pressed, *IN03 will be *ON so the IF will go to
C* ENDIF and the DO will go to ENDDO
C *IN03 IFEQ *OFF
C* EXSR is Execute Subroutine. It will process the subroutine
C* named MAIN.
C EXSR MAIN
C ENDIF
C ENDDO
C* The next 2 statements end the program.
C MOVE *ON *INLR
C RETRN
C*----------------------------------------------------------------
116
C* Subroutines begin with BEGSR and end with ENDSR.
C*
C MAIN BEGSR
C* Use the CHAIN instruction to look for the Cust# entered in
C* the field DSPCST.
C* This statement says to use the value in DSPACT to look up
C* the value in CUST and to turn *IN90 to *ON if it is NOT found.
C DSPCST CHAINCUST 95
C*
C MOVE *BLANKS DSPMSG
C MOVE *OFF *IN90
C*
C* Because this will eventually test for Add, Chg, Delete
C* use the SELEC instead of IF.
C SELEC
C DSPACT WHEQ 'C'
C* If user wants to Change the record but it was not found,
C* show error message. Otherwise Execute Subroutine to change it.
C *IN95 IFEQ *ON
C MOVELERR2 DSPMSG
C MOVE *ON *IN90
C ELSE
C EXSR CHG
C ENDIF
C*
C OTHER
C* MOVEL is Move Left. It moves the value and justifies left.
C MOVELERR1 DSPMSG
C* Setting *IN90 to *ON will cause the error message to be
117
C* displayed in reverse image (see the DDS for DSPMSG).
C MOVE *ON *IN90
C ENDSL
C*
C ENDSR
C*----------------------------------------------------------------
C CHG BEGSR
C*
C* Show SCRN2. The values will be loaded from the CHAIN.
C* Continue showing SCRN2 until either F12 is pressed or
C* the data entered is OK. The subroutine EDTVAL will put
C* a message in DSPMSG if there is an error. If DSPMSG is
C* still blank after EDTVAL, then data is OK.
C*
C* This starts a DO loop that will continue to loop
C* until DSPMSG is not blank OR *IN12 is *ON.
C DSPMSG DOUNE*BLANKS
C *IN12 OREQ *ON
C EXFMTSCRN2
C* If the user hits F12 do not process,
C* otherwise, Edit the values to see if they are OK.
C *IN12 IFEQ *OFF
C EXSR EDTVAL
C* If there are no errors, update the record. The UPDAT
C* uses the record name for the CUST file.
C DSPMSG IFEQ *BLANK
C* UPDAT rewrites the record in the database file. Since the
C* field names in the display file are the same as in the
C* database file, RPG synchronizes the values.
118
C UPDATCSREC
C* LEAVE will go to the ENDDO.
C LEAVE
C ENDIF
C ENDIF
C*
C ENDDO
C*
C ENDSR
C*----------------------------------------------------------------
C EDTVAL BEGSR
C* Make sure the values on the screen are OK.
C CSNAME IFEQ *BLANKS
C MOVELERR3 DSPMSG
C MOVE *ON *IN90
C ENDIF
C*
C CSADR1 IFEQ *BLANKS
C MOVELERR4 DSPMSG
C MOVE *ON *IN90
C ENDIF
C*
C CSCTY IFEQ *BLANKS
C MOVELERR5 DSPMSG
C MOVE *ON *IN90
C ENDIF
C*
C CSSTE IFEQ *BLANKS
C MOVELERR6 DSPMSG
119
C MOVE *ON *IN90
C ENDIF
C*
C CSZIP IFLT 10000000
C MOVELERR7 DSPMSG
C MOVE *ON *IN90
C ENDIF
C*
C ENDSR
Click here to see the RPG III source code without the comments. This is TUTR010NC.
TUTR010NC in QRPGSRC in USER000
FCUST UF E K DISK
FTUTD010 CF E WORKSTN
*----------------------------------------------------------------
I 'You must enter A, C,-C ERR1
I ' or D'
I 'Customer # is not fo-C ERR2
I 'und'
I 'Name cannot be blank'C ERR3
I 'Addr cannot be blank'C ERR4
I 'City cannot be blank'C ERR5
I 'State cannot be blan-C ERR6
I 'k'
I 'Zip is invalid' C ERR7
*----------------------------------------------------------------
C *IN03 DOWEQ*OFF
120
C EXFMTSCRN1
C EXFMTSCRN1
C*
C *IN03 IFEQ *OFF
C EXSR MAIN
C ENDIF
C*
C ENDDO
C*
C MOVE *ON *INLR
C RETRN
C*----------------------------------------------------------------
C MAIN BEGSR
C*
C DSPCST CHAINCUST 95
C*
C MOVE *BLANKS DSPMSG
C MOVE *OFF *IN90
C*
C SELEC
C DSPACT WHEQ 'C'
C *IN95 IFEQ *ON
C MOVELERR2 DSPMSG
C MOVE *ON *IN90
C ELSE
C EXSR CHG
C ENDIF
C*
C OTHER
121
C MOVELERR1 DSPMSG
C MOVE *ON *IN90
C ENDSL
C*
C ENDSR
C*----------------------------------------------------------------
C CHG BEGSR
C*
C DSPMSG DOUNE*BLANKS
C *IN12 OREQ *ON
C EXFMTSCRN2
C *IN12 IFEQ *OFF
C EXSR EDTVAL
C DSPMSG IFEQ *BLANK
C UPDATCSREC
C LEAVE
C ENDIF
C ENDIF
C*
C ENDDO
C*
C ENDSR
C*----------------------------------------------------------------
C EDTVAL BEGSR
C* Make sure the values on the screen are OK
C CSNAME IFEQ *BLANKS
C MOVELERR3 DSPMSG
C MOVE *ON *IN90
C ENDIF
122
C*
C CSADR1 IFEQ *BLANKS
C MOVELERR4 DSPMSG
C MOVE *ON *IN90
C ENDIF
C*
C CSCTY IFEQ *BLANKS
C MOVELERR5 DSPMSG
C MOVE *ON *IN90
C ENDIF
C*
C CSSTE IFEQ *BLANKS
C MOVELERR6 DSPMSG
C MOVE *ON *IN90
C ENDIF
C*
C CSZIP IFLT 10000000
C MOVELERR7 DSPMSG
C MOVE *ON *IN90
C ENDIF
C*
C ENDSR
Click here to see the RPG IV source code with all the comments. This is TUTR011 in QRPGLESRC in USER000.
TUTR011 in QRPGLESRC in USER000
* Define the CUST file with file type U for UPDATE
123
* (update means that you can read and re-write data)
* and with record address type K for Keyed.
* (Keyed means the data can be directly read using the key field)
FCUST UF E K DISK
* Next, define the display file. It must already exist.
* The C indicates combined input and output. WORKSTN is
* always used to indicate a display file.
FTUTD010 CF E WORKSTN
*----------------------------------------------------------------
D* This next few statements define constants that will be used
D* as error messages.
D ERR1 C CONST('You must enter A, C,-
D or D')
D ERR2 C CONST('Customer # is not fo-
D und')
D ERR3 C CONST('Name cannot be blank')
D ERR4 C CONST('Addr cannot be blank')
D ERR5 C CONST('City cannot be blank')
D ERR6 C CONST('State cannot be blan-
D k')
D ERR7 C CONST('Zip is invalid')
*----------------------------------------------------------------
C* This is the main loop.
C* It will continue to show the first screen until F3 is pressed.
C* When F3 is pressed, *IN03 will be truned *ON
C DoW *in03 = *off
C* The next statement, executes the format (EXFMT) for SCRN1
C* EXFMT displays the SCRN1 and waits until the user presses
C* ENTER or F3. Then, it continues to the next statement.
124
C ExFmt SCRN1
C* If F3 was pressed, *IN03 will be *ON so the IF will go to
C* ENDIF and the DO will go to ENDDO.
C If *in03 = *off
C* EXSR is Execute Subroutine. It will process the subroutine
C* named MAIN.
C ExSr Main
C EndIf
C EndDo
C* The next 2 statments end the program.
C Eval *inlr = *on
C Return
C*----------------------------------------------------------------
C* Subroutines begin with BEGSR and end with ENDSR.
C*
C Main BegSr
C* Use the CHAIN instruction to look for the Cust# entered in
C* the field DSPCST.
C* This statements says to use the value in DSPACT to look up
C* the value in CUST and to turn *IN90 to *ON if it is NOT found.
C DSPCST Chain CUST 95
C*
C Eval DSPMSG = *blanks
C Eval *in90 = *off
C*
C* Because this will eventually test for Add, Chg, Delete
C* use the SELECT instead of IF.
C Select
C When DSPACT = 'C'
125
C* If user wants to Change the record but it was not found,
C* show error message. Otherwise Execute Subroutine to change it.
C If *in95 = *on
C Eval DSPMSG = ERR2
C Eval *in90 = *on
C Else
C ExSr ChangeRecord
C EndIf
C*
C Other
C Eval DSPMSG = ERR1
C* Setting *IN90 to *ON will cause the error message to be
C* displayed in reverse image (see the DDS for DSPMSG).
C Eval *in90 = *on
C EndSl
C*
C EndSr
C*----------------------------------------------------------------
C ChangeRecord BegSr
C*
C*
C* Show SCRN2. The values will be loaded from the CHAIN.
C* Continue showing SCRN2 until either F12 is pressed or
C* the data entered is OK. The subroutine EDITVALUES will put
C* a message in DSPMSG if there is an error. If DSPMSG is
C* still blank after EDITVALUES, then data is OK.
C*
C* This starts a DO loop that will continue to loop
C* Until DSPMSG is not blank OR *IN12 is *ON.
126
C DoU DSPMSG = *BLANKS or
C *in12 = *on
C ExFmt SCRN2
C* If the user hits F12 do not process,
C* otherwise, Edit the values to see if they are OK.
C If *in12 = *off
C ExSr EditValues
C* If there are no errors, update the record. The UPDATE
C* uses the record name for the CUST file.
C If DSPMSG = *blanks
C* UPDATE rewrites the record in the database file. Since the
C* field names in the display file are the same as in the
C* database file, RPG synchronizes the values.
C Update CSREC
C* LEAVE will go to the ENDDO.
C Leave
C EndIf
C EndIf
C*
C EndDo
C*
C EndSr
C*----------------------------------------------------------------
C EditValues BegSr
C* Make sure the values on the screen are OK.
C If CSNAME = *BLANKS
C Eval DSPMSG = ERR3
C Eval *in90 = *on
C EndIf
127
C*
C If CSADR1 = *BLANKS
C Eval DSPMSG = ERR4
C Eval *in90 = *on
C EndIf
C*
C If CSCTY = *BLANKS
C Eval DSPMSG = ERR5
C Eval *in90 = *on
C EndIf
C*
C If CSSTE = *BLANKS
C Eval DSPMSG = ERR6
C Eval *in90 = *on
C EndIf
C*
C If CSZIP < 10000000
C Eval DSPMSG = ERR7
C Eval *in90 = *on
C EndIf
C*
C EndSr
Click here to see the RPG IV source code without the comments. This is TUTR011NC.
TUTR011NC in QRPGLESRC in USER000
FCUST UF E K DISK
FTUTD010 CF E WORKSTN
128
*----------------------------------------------------------------
D ERR1 C CONST('You must enter A, C,-
D or D')
D ERR2 C CONST('Customer # is not fo-
D und')
D ERR3 C CONST('Name cannot be blank')
D ERR4 C CONST('Addr cannot be blank')
D ERR5 C CONST('City cannot be blank')
D ERR6 C CONST('State cannot be blan-
D k')
D ERR7 C CONST('Zip is invalid')
*----------------------------------------------------------------
C DoW *in03 = *off
C
C ExFmt SCRN1
C
C If *in03 = *off
C ExSr Main
C EndIf
C
C EndDo
C
C Eval *inlr = *on
C Return
C*----------------------------------------------------------------
C Main BegSr
C
C DSPCST Chain CUST 95
C
129
C Eval DSPMSG = *blanks
C Eval *in90 = *off
C
C Select
C
C When DSPACT = 'C'
C If *in95 = *on
C Eval DSPMSG = ERR2
C Eval *in90 = *on
C Else
C ExSr ChangeRecord
C EndIf
C
C Other
C Eval DSPMSG = ERR1
C Eval *in90 = *on
C EndSl
C
C EndSr
C*----------------------------------------------------------------
C ChangeRecord BegSr
C
C* This starts a DO loop that will continue to loop
C* Until DSPMSG is not blank OR *IN12 is *ON
C DoU DSPMSG = *BLANKS or
C *in12 = *on
C ExFmt SCRN2
C
C If *in12 = *off
130
C ExSr EditValues
C If DSPMSG = *blanks
C Update CSREC
C Leave
C EndIf
C EndIf
C
C EndDo
C
C EndSr
C*----------------------------------------------------------------
C EditValues BegSr
C* Make sure the values on the screen are OK
C If CSNAME = *BLANKS
C Eval DSPMSG = ERR3
C Eval *in90 = *on
C EndIf
C
C If CSADR1 = *BLANKS
C Eval DSPMSG = ERR4
C Eval *in90 = *on
C EndIf
C
C If CSCTY = *BLANKS
C Eval DSPMSG = ERR5
C Eval *in90 = *on
C EndIf
C
C If CSSTE = *BLANKS
131
C Eval DSPMSG = ERR6
C Eval *in90 = *on
C EndIf
C
C If CSZIP < 10000000
C Eval DSPMSG = ERR7
C Eval *in90 = *on
C EndIf
C
C EndSr
Debugging RPG ILE with the iSeries / AS400 Debugger STRDBG
The AS/400 has a built in debugging tool, though very powerful, it is not completely intuitive. Sometimes you may find yourself in need of a procedure that can help you locate program errors that you cannot visually find by looking at your program. RPG-ILE's program debugger can be very useful in these situations. It allows you to trace a program as it is executing, stepping through a program a statement at a time, or stopping at "breakpoints" that you designate so you can see the values of fields at that point of execution. Follow the steps below to start the "debugging" mode for your programs.
First, you must compile the program in an appropriate mode. Do this from PDM by keying a 14 next the program source and hitting F4.
Your screen should look like this:
Create Bound RPG Program (CRTBNDRPG)
Type choices, press Enter.
Program . . . . . . . . . . . . > LXR001 Name, *CTLSPEC
Library . . . . . . . . . . . > T40 Name, *CURLIB
Source file . . . . . . . . . . > QRPGLESRC Name, QRPGLESRC
Library . . . . . . . . . . . > T40 Name, *LIBL, *CURLIB
Source member . . . . . . . . . > LXR001 Name, *PGM
Generation severity level . . . 10 0-20
132
Text 'description' . . . . . . . *SRCMBRTXT
Default activation group . . . . *YES *YES, *NO
Now, hit F10 to get more options. Key in *LIST as the value for "Debugging View".
The screen should look like:
Create Bound RPG Program (CRTBNDRPG)
Type choices, press Enter.
Program . . . . . . . . . . . . > LXR001 Name, *CTLSPEC
Library . . . . . . . . . . . > T40 Name, *CURLIB
Source file . . . . . . . . . . > QRPGLESRC Name, QRPGLESRC
Library . . . . . . . . . . . > T40 Name, *LIBL, *CURLIB
Source member . . . . . . . . . > LXR001 Name, *PGM
Generation severity level . . . 10 0-20
Text 'description' . . . . . . . *SRCMBRTXT
Default activation group . . . . *YES *YES, *NO
Additional Parameters
Compiler options . . . . . . . . *XREF, *NOXREF, *GEN...
+ for more values
Debugging views . . . . . . . . *LIST *STMT, *SOURCE, *LIST...
Output . . . . . . . . . . . . . *PRINT *PRINT, *NONE
Now ENTER to compile your program. If this program calls other programs, you may want to compile them in debug mode also.
133
Now it gets a little tricky. Start the debugging mode with the "Start Debug" for the program you want to debug. In this case, the program is LXR001 so the command to use is STRDBG LXR001. Key in STRDBG LXR001 and hit F14:
Start Debug (STRDBG)
Type choices, press Enter.
Program . . . . . . . . . . . . > LXR001 Name, *NONE
Library . . . . . . . . . . . *LIBL Name, *LIBL, *CURLIB
+ for more values
*LIBL
Default program . . . . . . . . *PGM Name, *PGM, *NONE
Maximum trace statements . . . . 200 Number
Trace full . . . . . . . . . . . *STOPTRC *STOPTRC, *WRAP
Update production files . . . . *NO *NO, *YES
OPM source level debug . . . . . *NO *NO, *YES
Service program . . . . . . . . *NONE Name, *NONE
Library . . . . . . . . . . . Name, *LIBL, *CURLIB
+ for more values
If your program updates or writes data to a file in a library that is defined as *PROD, you must change the "Update production files" option to *YES. Then, hit ENTER.
The debugger now displays the source code of the program. You MUST define a breakpoint where the debugger will actually start debugging. The easiest thing to do is to page down to the first executable statement of the program. Put the cursor on that line of source code and hit F6 to define that line as a breakpoint.
Now, hit F3 and you will return to the PDM menu.
Your session is now in "debug" mode. It will stay in "debug" mode until you end debug mode with the command ENDDBG.
Finally, it is time to start running your program. Call the program from the command line. In this case: CALL LXR001
134
The program will start running. The debug feature will display a listing of the program. The display is showing that the breakpoint is about to execute. You can scroll up or down, position the cursor on any field and hit F11. The debugger will display the value of the field.
Now hit F10 repeatedly to step through the source code. The line of code that is about to execute will be highlighted.
Note that the debugger has the annoying habit of stepping through every field in each file that is read or updated. To prevent this, add a "header" record as the first line of code in the program. "Header" records are not required and not usually used. Use an "H" as the record type with a value of "option(*nodebugio). That is, add this line to the beginning of your program:
H OPTION(*NODEBUGIO)
When you are finished debuggin, key ENDDBG to turn off the debugger.
To summarize:
1) Add this line to the beginning of your program: H OPTION(*NODEBUGIO)
2) Compile the program with Debug View set to *LIST
3) Start the debugger with the command: STRDBG pgmname (Update Production files *YES)
4) Put cursor on the first line that you want to see and hit F6. Exit with F3.
5) Call your program: CALL pgmname
6) Use F10 to step through the program. Use F11 to see values.
7) If you wish, set additional breakpoints and use F12 to run until the next breakpoint.
As before, try using F4 to prompt the fields. To turn off prompting, hit F12.
Also, as with all programs, compile the source code with option 14.
View your compile listing with the Work With Spool File command, WRKSPLF. Look for errors at the bottom of the listing.
To run the program, key CALL TUTR010 or CALL TUTR011.
Use any valid Customer #. 1002 is a valid #.
If you completed this topic, you are well on your way to becoming an RPG programmer.
Complete RPG Maintenance Program
Now that you have worked with RPG some, take a moment to review this maintenance program. It is written in both RPG III and RPG IV.
135
Writing an Add/Change/Delete/Inquiry maintenance programThis is the DDS for the Display Program named CUSTD01.
A REF(CUST)
A CA03(03 'F3=EXIT')
A R SCR1
A 1 2USER
A O 1 28'ADD/UPDATE/DELETE/INQUIRE'
A DSPATR(HI)
A 1 72DATE
A EDTCDE(Y)
A 2 2'CUSTR01'
A 2 72TIME
A O 6 8'(A)dd, (U)pdate, (D)elete'
A O 6 34'(I)nquire, (N)ext'
A ACTION 1 B 6 53DSPATR(HI)
A O 8 28'Cust#'
A CUS# R B 8 35DSPATR(HI) EDTCDE(4)
A ERRLIN 78 O 22 2
A 90 DSPATR(RI)
A O 23 14'F3=EXIT'
A*----------------------------------------------------------------
A R SCR2
A CA09(09 'F9=DELETE')
A 1 2USER
A 1 28'CUSTOMER FILE MAINTENANCE'
A 1 72DATE
A EDTCDE(Y)
136
A 2 2'CUSTR01'
A MODE 7 O 2 37
A 2 72TIME
A 3 28'Cust#'
A CUS# R O 3 37EDTCDE(4) DSPATR(RI)
A 8 28'Name'
A CUSNAM R B 8 42
A N80 DSPATR(HI)
A 80 DSPATR(PR)
A 9 28'Address 1'
A CUSAD1 R B 9 42
A N80 DSPATR(HI)
A 80 DSPATR(PR)
A 10 28'Address 2'
A CUSAD2 R B 10 42
A N80 DSPATR(HI)
A 80 DSPATR(PR)
A 11 28'City'
A CUSCTY R B 11 42
A N80 DSPATR(HI)
A 80 DSPATR(PR)
A 12 28'State'
A CUSSTA R B 12 42
A N80 DSPATR(HI)
A 80 DSPATR(PR)
A 13 28'Zip'
A CUSZIP R Y B 13 42
A N80 DSPATR(HI)
A 80 DSPATR(PR)
137
A ERRLIN 78 O 22 2
A 90 DSPATR(RI)
A O 23 14'F3=EXIT'
Writing an Add/Change/Delete/Inquiry maintenance program in RPG III
This is the RPG III source code for the Add/Change/Delete program named CUSTR01.
FCUSTD01 CF E WORKSTN
FCUST UF E K DISK A
*----------------------------------------------------------------
* Define error messages here
I 'RECORD ALREADY ON FI-C ERR1
I 'LE'
I 'RECORD IS NOT ON FIL-C ERR2
I 'E'
I 'NO MORE RECORDS' C ERR3
I 'ZIP CANNOT BE ZERO' C ERR6
I 'NAME MUST NOT BE BL-C ERR7
I 'ANK'
I 'STATE MUST NOT BE BL-C ERR8
I 'ANK'
I 'ACTION MUST BE A, U,-C ERR9
I ' D OR I'
I 'RECORD ADDED SUCCE- C MSG1
I 'SSFULLY'
I 'RECORD UPDATED SUC- C MSG2
I 'CESSFULLY'
I 'RECORD DELETED SUC- C MSG3
I 'CESSFULLY'
I 'HIT F9 TO DELETE' C MSG4
138
I 'NO ACTION TAKEN' C MSG9
*----------------------------------------------------------------
* Key List for customer file
* (a key list is not needed since this file has only 1 key
* field, but this makes the program easier to modify if
* the file has multiple key fields)
C KEYLST KLIST
C KFLD CUS#
*----------------------------------------------------------------
* Stay in Main DO LOOP until F3 is hit from SCR1
*----------------------------------------------------------------
C *IN03 DOWEQ*OFF
* Show main ADD/UPD/INQ/DLT screen
C EXFMTSCR1
C CLEARERRLIN
C MOVE *OFF *IN90
* If user didn't hit F3, process screen based on action
C *IN03 IFEQ *OFF
C SELEC
C ACTION WHEQ 'A'
C EXSR ADDREC
C ACTION WHEQ 'D'
C EXSR DLTREC
C ACTION WHEQ 'I'
C EXSR INQREC
C ACTION WHEQ 'N'
C EXSR NXTREC
C ACTION WHEQ 'U'
C EXSR UPDREC
139
C OTHER
C CLEARERRLIN
C MOVELERR9 ERRLIN
C MOVE *ON *IN90
C ENDSL
C ENDIF
C ENDDO
*
C MOVE *ON *INLR
C RETRN
*----------------------------------------------------------------
C ADDREC BEGSR
* Unprotect fields but setting *in80 off
C MOVE *OFF *IN80
C MOVE ' ADD ' MODE
* See if customer # is already in CUST file
C KEYLST CHAINCUST 91
C *IN91 IFEQ *OFF
* If customer # is already in cust file, load up ERR MSG
C CLEARERRLIN
C MOVELERR1 ERRLIN
C MOVE *ON *IN90
C ELSE
C EXSR ADDSCR
C ENDIF
C ENDSR
*----------------------------------------------------------------
* SHOW ADD SCREEN
*----------------------------------------------------------------
140
C ADDSCR BEGSR
* Clear customer record except for key field(s)
C *NOKEY CLEARCUSTR
C MOVE 'N' RECOK 1
* Keep showing screen until record passes edit or F3 is hit
C RECOK DOWEQ'N'
C *IN03 ANDEQ*OFF
C EXFMTSCR2
*
C *IN03 IFEQ *OFF
C EXSR EDTCUS
C RECOK IFEQ 'Y'
C WRITECUSTR
* Show messaage that ADD was successful
C CLEARERRLIN
C MOVELMSG1 ERRLIN
C ENDIF
C ELSE
* Show message that no action was taken because F3 was hit
C CLEARERRLIN
C MOVELMSG9 ERRLIN
C ENDIF
C ENDDO
*
C MOVE *OFF *IN03
*
C ENDSR
*----------------------------------------------------------------
C DLTREC BEGSR
141
* Disable fields for entry by setting *IN80 on
C MOVE *ON *IN80
C MOVE 'DELETE' MODE
C CLEARERRLIN
C MOVELMSG4 ERRLIN
C MOVE *ON *IN90
* See if customer # is in CUST file
C KEYLST CHAINCUST 91
C *IN91 IFEQ *ON
* If customer # is not in CUST file, show ERR MSG
C CLEARERRLIN
C MOVELERR2 ERRLIN
C MOVE *ON *IN90
C ELSE
C EXFMTSCR2
C MOVE *OFF *IN90
C *IN09 IFEQ *ON
C DELETCUSTR
C CLEARERRLIN
C MOVELMSG3 ERRLIN
C ELSE
C CLEARERRLIN
C MOVELMSG9 ERRLIN
C ENDIF
C ENDIF
*
C MOVE *OFF *IN03
*
C ENDSR
142
*----------------------------------------------------------------
C INQREC BEGSR
* Disable fields for entry by setting *IN80 on
C MOVE *ON *IN80
C MOVE 'INQUIRY' MODE
* See if customer # is in CUST file
C KEYLST CHAINCUST 91
C *IN91 IFEQ *ON
* If customer # is not in CUST file, show ERR MSG
C CLEARERRLIN
C MOVELERR2 ERRLIN
C MOVE *ON *IN90
C ELSE
* Show Inquiry Screen
C EXFMTSCR2
C ENDIF
*
C MOVE *OFF *IN03
*
C ENDSR
*----------------------------------------------------------------
C NXTREC BEGSR
*
C MOVE *ON *IN80
C MOVE 'INQUIRY' MODE
C CLEARERRLIN
* Go forward in the file to the next record
C KEYLST SETLLCUST 92 93
* If *in92 is on, we have reached end of file
143
C *IN92 IFEQ *ON
C MOVELERR3 ERRLIN
C MOVE *ON *IN90
C ENDIF
* Read next record
C ERRLIN IFEQ *BLANKS
C READ CUST 90
* If *in90 is on, we have reached end of file
C *IN92 IFEQ *ON
C MOVELERR3 ERRLIN
C MOVE *ON *IN90
C ENDIF
C ENDIF
* If *in93 is on, we are at an existing record and we need
* to read past it
C ERRLIN IFEQ *BLANKS
C *IN93 IFEQ *ON
C READ CUST 90
* If *in90 is on, we have reached end of file
C *IN90 IFEQ *ON
C MOVELERR3 ERRLIN
C MOVE *ON *IN90
C ENDIF
C ENDIF
C ENDIF
*
C ERRLIN IFEQ *BLANKS
C EXFMTSCR2
C ENDIF
144
*
C MOVE *OFF *IN03
*
C ENDSR
*----------------------------------------------------------------
C UPDREC BEGSR
* Unprotect fields but setting *in80 off
C MOVE *OFF *IN80
C MOVE 'UPDATE ' MODE
* See if customer # is already in CUST file
C KEYLST CHAINCUST 91
C *IN91 IFEQ *ON
* If customer # is not in cust file, load up ERR MSG
C CLEARERRLIN
C MOVELERR2 ERRLIN
C MOVE *ON *IN90
C ELSE
C EXSR UPDSCR
C ENDIF
C ENDSR
*----------------------------------------------------------------
* SHOW UPDATE SCREEN
*----------------------------------------------------------------
C UPDSCR BEGSR
C MOVE 'N' RECOK 1
* Keep showing screen until record passes edit or F3 is hit
C RECOK DOWEQ'N'
C *IN03 ANDEQ*OFF
C EXFMTSCR2
145
*
C *IN03 IFEQ *OFF
C EXSR EDTCUS
C RECOK IFEQ 'Y'
C UPDATCUSTR
* Show messaage that UPDATE was successful
C CLEARERRLIN
C MOVELMSG2 ERRLIN
C ENDIF
C ELSE
* Show message that no action was taken because F3 was hit
C CLEARERRLIN
C MOVELMSG9 ERRLIN
C ENDIF
C ENDDO
*
C MOVE *OFF *IN03
*
C ENDSR
*----------------------------------------------------------------
C EDTCUS BEGSR
* First, set error switch that record is OK
C MOVE 'Y' RECOK
* Now, perform each edit
C CUSNAM IFEQ *BLANKS
C MOVE 'N' RECOK
C CLEARERRLIN
C MOVELERR7 ERRLIN
C MOVE *ON *IN90
146
C ENDIF
*
C CUSSTA IFEQ *BLANKS
C MOVE 'N' RECOK
C CLEARERRLIN
C MOVELERR8 ERRLIN
C MOVE *ON *IN90
C ENDIF
*
C CUSZIP IFEQ *ZERO
C MOVE 'N' RECOK
C CLEARERRLIN
C MOVELERR6 ERRLIN
C MOVE *ON *IN90
C ENDIF
*
C ENDSR
*----------------------------------------------------------------
Writing an Add/Change/Delete/Inquiry maintenance program in RPG IV
This is the RPG IV source code for the Add/Change/Delete program named CUSTR01.
FCUSTD01 CF E WORKSTN
FCUST UF A E K DISK
*---------------------------------------------------------------------
D RecOK S 1a
*---------------------------------------------------------------------
D Err1 C CONST('RECORD ALREADY ON FI-
D LE')
D Err2 C CONST('RECORD IS NOT ON FI-
147
D LE')
D Err3 C CONST('NO MORE RECORDS')
D Err4 C CONST('ZIP CAN NOT BE BLANK')
D Err5 C CONST('NAME IS MANDATORY')
D Err6 C CONST('STATE IS MANDATORY')
D Err7 C CONST('INVALID ACTION')
D Err8 C CONST('NO MORE RECORDS')
D Msg1 C CONST('RECORD ADDED')
D Msg2 C CONST('RECORD UPDATED')
D Msg3 C CONST('RECORD DELETED')
D Msg4 C CONST('HIT F9 TO DELETE')
D Msg9 C CONST('NO ACTION TAKEN')
*---------------------------------------------------------------------
C KEYLST KLIST
C KFLD CSNBR
C*---------------------------------------------------------------------
C* Display the add, delete, inquire, next, or update screen
C* and process unless user hit F3 (indicator 03)
C
C DoW *in03 = *off
C ExFmt SCR1
C Eval ERRLIN = *blanks
C Eval *in90 = *off
C If *in03 = *off
C Select
C When Action = 'A'
C ExSr AddRecord
C When Action = 'D'
C ExSr DltRecord
148
C When Action = 'I'
C ExSr InqRecord
C When Action = 'N'
C ExSr NextRecord
C When Action = 'U'
C ExSr UpdRecord
C Other
C Eval ERRLIN = Err7
C Eval *in90 = *on
C EndSl
C EndIf
C EndDo
C
C Eval *inlr = *on
C Return
C*---------------------------------------------------------------------
C AddRecord BegSr
C
C* Indicator 80 is used by the display file to protect most fields
C* since we are in ADD mode, set the indicator off to allow field entry
C Eval *IN80 = *off
C Eval MODE = ' ADD'
C* See if customer is already on file. If so, display error
C KEYLST Chain CUST 91
C If *in91 = *off
C Eval ERRLIN = Err1
C* Indicator 90 draws attention to the error line with reverse display
C Eval *in90 = *on
C Else
149
C ExSr AddScreen
C EndIf
C
C EndSr
C*---------------------------------------------------------------------
C AddScreen BegSr
C
C* Clear all fields except the key field
C *NOKEY Clear CSREC
C Eval RecOK = 'n'
C* Stay on this screen until user gets it right or hits F3
C Dow RecOK = 'n' and
C *in03 = *off
C ExFmt SCR2
C If *in03 = *off
C ExSr EditRecord
C If recOK = 'y'
C Write CSREC
C Eval ERRLIN = Msg9
C EndIf
C Else
C Eval ERRLIN = Msg9
C EndIf
C EndDo
C
C Eval *in03 = *off
C
C EndSr
C*---------------------------------------------------------------------
150
C DltRecord BegSr
C
C* Indicator 80 is used by the display file to protect most fields
C* since we are in DLT mode, set the indicator on for no field entry
C Eval *in80 = *on
C Eval MODE = 'DELETE'
C* Display "Hit F9 to DELETE" in ERRLIN
C Eval ERRLIN = Msg4
C Eval *in90 = *on
C* See if customer is on file. If not, show error Msg
C KEYLST Chain CUST 91
C If *in91 = *on
C Eval ERRLIN = Err2
C Else
C* If customer is on file, show screen again and see if user hit F9
C* to confirm delete
C ExFmt SCR2
C Eval *in90 = *off
C If *in09 = *on
C Delete CSREC
C Eval ERRLIN = Msg3
C Else
C Eval ERRLIN = Msg9
C EndIf
C EndIf
C
C Eval *in03 = *off
C EndSr
C*---------------------------------------------------------------------
151
C InqRecord BegSr
C
C* Indicator 80 is used by the display file to protect most fields
C* since we are in DLT mode, set the indicator on for no field entry
C Eval *in80 = *on
C Eval MODE = 'INQUIRY'
C
C KEYLST Chain CUST 91
C If *in91 = *on
C Eval ERRLIN = Err2
C Eval *In90 = *on
C Else
C ExFmt SCR2
C EndIf
C Eval *in03 = *off
C
C EndSr
C*---------------------------------------------------------------------
C NextRecord BegSr
C
C Eval *in80 = *on
C Eval MODE = 'INQUIRY'
C Eval ERRLIN = *blanks
C
C* Set file cursor at cust from screen
C KEYLST SetLL CUST 92 93
C If *in92 = *on
C Eval ERRLIN = Err3
C Eval *in90 = *on
152
C EndIf
C
C* Read file to get next customer
C If ERRLIN = *BLANKS
C Read CUST 90
C If *in92 = *on
C Eval ERRLIN = Err3
C Eval *in90 = *on
C EndIf
C EndIf
C* If *in93 is on, we are at an existing record and need to read past it
C If *in93 = *on and
C ERRLIN = *blanks
C Read CUST 90
C If *in90 = *on
C Eval ERRLIN = Err3
C Eval *in90 = *on
C EndIf
C EndIf
C
C If ERRLIN = *blanks
C ExFmt SCR2
C EndIf
C Eval *in03 = *off
C
C EndSr
C*---------------------------------------------------------------------
C UpdRecord BegSr
C
153
C Eval *IN80 = *off
C Eval MODE = ' UPDATE '
C KEYLST Chain CUST 91
C If *in91 = *on
C Eval ERRLIN = Err2
C Eval *in90 = *on
C Else
C ExSr UpdScreen
C EndIf
C
C EndSr
C*---------------------------------------------------------------------
C UpdScreen BegSr
C Eval RecOK = 'n'
C DoW RecOK = 'n' and
C *in03 = *off
C ExFmt SCR2
C If *in03 = *off
C ExSr EditRecord
C If RecOK = 'y'
C Update CSREC
C Eval ERRLIN = Msg2
C EndIf
C Else
C Eval ERRLIN = Msg9
C EndIf
C EndDo
C Eval *in03 = *off
C EndSr
154
C*---------------------------------------------------------------------
C EditRecord BegSr
C Eval RecOK = 'y'
C
C If CSNAME = *blanks
C Eval RecOK = 'n'
C Eval ERRLIN = Err5
C Eval *in90 = *on
C EndIf
C
C If CSSTE = *blanks
C Eval RecOK = 'n'
C Eval ERRLIN = Err6
C Eval *in90 = *on
C EndIf
C
C If CSZIP = *zero
C Eval RecOK = 'n'
C Eval ERRLIN = Err4
C Eval *in90 = *on
C EndIf
C
C EndSr
*----------------------------------------------------------------
Showcase Article - Report Layout Utility (RLU)
Learning to use the tools on the AS/400 is one of the best ways to leverage your expertise. Managers may be surprised to learn how easy it is to provide users with sample report layouts that can be designed with an on-line tool. This on-line tool is RLU, Report Layout Utility.
155
Because many programmers find its interface to be confusing, not many have become proficient RLU users. Read on and you will learn to create report layouts quickly and easily.
In the early days of RPG, reports were always printed using OUTPUT specifications. With the advent of DDS, it became possible to make print files using DDS. This is similar to the way DDS is used to make display files. The AS/400 provides SDA, Screen Design Aid, as an on-line tool to design display files. Similarly, RLU, is an on-line tool to design reports.
Suppose a user needs a report showing:
1. Customer number
2. Customer name
3. Customer city
4. Annual purchase amount
These fields are in the customer master file, CUST. We will write an RPG program, CUSR005 to read the CUST file and write a print file, CUSW005.
Figure 1 shows the finished report that we will design with RLU. To start RLU, enter the command STRRLU and hit F4. Enter QDDSSRC as the source file. Enter the library name and CUSW005 as the source member. Since this is a narrow report, enter 65 for the page width. For a standard width report, you would use 132 for the page width.
RLU now displays its DESIGN REPORT screen. RLU uses so many function keys that there is a base set of function keys and an alternate set of keys. F22 is used to toggle between the base keys and the alternate keys. Right now RLU shows the word, BASE in the upper left portion of the screen to indicate that the base set of function keys is in use. F22 changes to the alternate keys and the changes the display from BASE to ALT.
The simplest way to use RLU is to define each line as a separate record. To start working with a line of the report, key DR for DEFINE RECORD in the command area on a blank line. When you hit the enter key, RLU names the record with the default name RCD001. After defining a record, enter VF for VIEW FIELDS in the command area of the same line. RLU then adds a line above the record to show the field information.
The heading for the report will be CUSTOMER ANNUAL PURCHASES. On the line with RCD001, key in the heading. Then, convert this string of characters to a constant. Do this by placing the cursor on the first character of the heading and hitting F11 for DEFINE FIELD. Hit F11 again and then ENTER to convert the string of characters to a constant. Finally, center the heading by keying CF for CENTER FIELD on the command portion of the RCD001 line. When you hit ENTER, the heading will center.
Now, create a second record. This will be used to print the customer fields. First insert a line to work with. Key I for INSERT in the command area of the RCD001 line and hit ENTER. Then, as before, key DR to define this as a record and then VF for VIEW FIELDS.
Next, use RLU to retrieve the field definitions from the master file. Hit F10 for DATABASE FIELDS. Key 1 for the option to ADD FIELD. Leave the FIELD value blank. Enter the library name and CUST for the File. Enter the record name of the CUST file. RLU will then retrieve all
156
the fields in the CUST file and list them. Select the fields for the report. Hit ENTER until you return to the DESIGN REPORT screen.
The names of the fields you selected are at the bottom of the screen. Each field is sequentially numbered. To insert the first field in the report, key 1 in the text area of the FLD record above the detail record line. When you hit ENTER, RLU puts that field in the layout. RLU has re-sequenced the remaining fields. Place the remaining fields in the report.
If you overlap fields, RLU can get confusing. The simplest way to recover is to delete the record by keying a D in the command area of the record. Then start the record over. If you want to remove a field, put the cursor on the field and hit F16. If you need to move a field, use F13 to mark where the cursor is positioned and then F15 to move the field to a new location.
Now that you have placed the fields in a detail record, create headings for the detail line. Insert a line above the detail line. As always, key DR for DEFINE RECORD and then VF to VIEW FIELDS. Simply key the headings in the text area of the blank record that you inserted. Then convert each field to a constant by putting the cursor on the first character of each literal and hitting F11 twice.
To help visualize the report, create some sample data lines. Make 5 copies of the detail line by keying SD5 on the command line of the detail line.
Now, add a line at the bottom of the report for the total annual purchases. Do this by keying I in the command line of the last record on the screen. As always, key DR and then VF in the command area of the record.
Key the word TOTAL in the text area of the record. Convert the word to a constant by placing the cursor on the first letter of the word and hitting F11 twice. Now, add a new field for the accumulated total. This can get confusing.
Place the cursor where you want the total amount to print. Hit F11 to DEFINE FIELD. On the DEFINE FIELD INFORMATION screen, change the name of the field from the default FLD001 to TOTPUR. Change the length of data to 9. Hit PAGE DOWN. Change the data type to 2 for ZONED and enter 2 for decimal positions. Then hit F10 to WORK WITH KEYWORDS. Select EDTCDE by keying 2 next to it. Hit ENTER and key 1 for the EDTCDE value. Hit ENTER a few times and you will see that you have added a field for the total purchases.
Finally, add the date and page counter to the first heading line. Do this by adding a field of the appropriate length, converting it to a constant and then selecting the appropriate keyword. Also, rename the records by using F18 for RECORD KEYWORDS and then F10 to rename the record.
Exit RLU with F3. You can save the DDS, compile it and generate a prototype report all from the exit screen.
Figure 2 shows the complete RPG program to print the report.
Figure 1 - This is the finished report designed by RLU.
157
FLD1 <........> <.......................> <..> <...>
HDG1 01/04/2001 CUSTOMER ANNUAL PURCHASES Page 9,999
FLD1 <..> <...........> <..> <..........>
HDG2 CUS# CUSTOMER NAME CITY ANNUAL PURCH
00004 +
FLD1 <....> <.......................> <.............> <.......>
DTL 999999 XXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXX 99,999.99
00006 S 999999 XXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXX 99,999.99
00007 S 999999 XXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXX 99,999.99
00008 S 999999 XXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXX 99,999.99
00009 S 999999 XXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXX 99,999.99
00010 S 999999 XXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXX 99,999.99
FLD1 <...> <..........>
TOTL TOTAL 9,999,999.99
158
Figure 2 - This is the complete RPG program to print the report.
FCUST IF E K DISK
FCUSW005 O E PRINTER OFLIND(*In99)
C Move *On *In99
C Read CUST 90
C *In90 DoWEq *Off
C *In99 IfEq *ON
C Write HDG1
C Write HDG2
C Move *Off *In99
C EndIf
C Add CUSAP TOTPUR
C Write DTL
C Read CUST 90
C EndDo
C Write TOTL
C Eval *INLR = *On
C Return
159