Sie sind auf Seite 1von 45

AS/400 Chapter 1: Introduction

This tutorial is an introduction to the AS/400 (System i5) system and to the RPG and
DDS programming languages. This is the first from a series of nine articles covering
several aspects of the system.
AS/400 is a computational platform launched in 1988 by IBM. Currently it is officially
named System i5, although the term AS/400 is still widely used, because of that we will
be using the term AS/400 throughout the tutorial, just be aware it's not its official name
anymore.
The machine's operating system is usually OS400. This system has several application
from database managers to compilers, editors, etc. AS/400 supports several
programming languages like Java, C, SQL, Assembly, COBOL,PHP, etc.
Minimum requirements to complete the tutorial:
Basic programming knowledge.
Basic database knowledge (relational model, SQL).
Access to an AS/400 server.
Access terminal to the AS/400 server (in this tutorial the examples are given
using Moshasoft).

A small application will be built through each chapter. After the last chapter the
application will be able to manage a set of shops and their clients. At the end of each
chapter you will be given the source code to the complete application.

This is the application's data model


AS/400 Chapter 2: Commands
To navigate through the AS/400 system you must know some commands and how to
use them. There is also a simple syntax that can help you remember some forgotten
command.
In AS/400 the commands can be executed from the system prompt. You can find it on
the lower part of the screen. It looks like this:
==> ________________________________________________________________
Underneath the system prompt there is usually a list of function keys with tasks specific
to the menu you are currently in.
Place the cursor at the prompt line,type GO and then press F4. A new screen will
appear, specific to the GO command, where you can define all the options for this
command.The F4 key can help you complete the syntax of most AS/400 commands.
Type MAJOR on the “Menu” option and press Enter. This shows the same result as
typing GO MAJOR in the command line. This command shows you a list with the most
important commands in AS/400.
The word “More...” on the bottom-right side of the list shows that there are lines that
aren't visible. You can see these lines by pushing Page Down or using the mouse scroll.
Place the cursor on top of any of the options on the list and press F1. A window will
appear with help about the option you chose. You can use this feature in most of the
menus and applications. To close the help window press F3.
You can choose an option by typing its number on the prompt and pressing Enter.
Let's go back to the start screen. Press F3.
Command Syntax
AS/400 commands usually have two parts (often with three letters each):a verb and a
noun. For instance, CTRLIB is the create library command and it has a verb CRT
(create) and a noun LIB (library). There are some exceptions, like the GO command we
saw earlier. In the following list you can see frequently used command verbs and nouns.
Verb Meaning Noun Meaning

CPY Copy DEV Device

DSP Dysplay F File

DLT Delete MSG Message

WRK Work SPLF Spool File

If you can't remember command syntax, use the command GO VERB, which will show
you a list of commands ordered by their functions.
AS/400 Chapter 3: Libraries
You can use a library in AS/400 just as you would use a folder in Windows to organize
your files; there are some differences, of course. Let's see how a library works in
AS400. A library is similar to a folder in Windows. In AS/400 a library is another object
that can contain other objects (executable objects, source files, etc).
Libraries can't contain other libraries. AS/400 is structured as a list, the opposite of
Windows which has a tree-like structure.
Creating a library
We're now going to create a library, called DEMO, where we'll place all the files from
this tutorial. Type the command:
CRTLIB DEMO
Your library is now created.
Changing the current library (CURLIB)
You can change the current library towork more easily with objects.This way you don't
have to specify the library name each time youwant to work with a file.
To change the library you are currently in type:
CHGCURLIB DEMO
All the objects you create will be placed on your CURLIB (if you don't explicitly specify
the library name). If you want to refer to the library you are currently in you can use it's
name or the keyword CURLIB. You can change your default library (the library where
you are when you enter the system) so that you don't have to change your current
library each time you enter the system:CHGPRF CURLIB DEMO Be aware that if you
don't change your opening or your current library, you can get some compilation errors.
If you have a reference to a file (without it's library name) in your source code the
compiler won't find it if it is placed on another library.
Libray Lists
Every command we use is stored in a specific system library. When a command library
isn't explicitly identified, the system will search for the command in every library in its
library list until the command if found. So, if you have 2 commands with the same name
on different libraries, the system will execute the one that is placed on the up most
library on the list. You can only have files with the same name in the same library if they
are of different types. You can see the library list with the command:DSPLIBL
You can see in the listing that there are different types of libraries:
SYS: System libraries. All the essential objects to the system (commands,
applications, compilers, etc).
CUR: The library you're currently in.
USR: User libraries (can be created by the user or the system manufacturer).

Press F3 to go back to the previous screen.


AS/400 Chapter 4: SQL
In AS/400 you can use SQL to work with tables and table data. There are also some
very useful built-in functions you should know about. Now that we've created a library
and saw some basic AS/400 features let's have a look at how we can create and
manipulate tables using SQL. You must create the DEMO library and define it has your
current library to proceed with this chapter. Type the following Start SQL command on the
system prompt:
STRSQL

This way you begin a SQL session in AS/400. This application accepts most of the
common SQL syntax (CREATE,INSERT, DELETE, SELECT, DROP, etc).

Creating a table with SQL


From the SQL command line we're going to create the CLIENTS table and then insert
some rows. For this tutorial let's assume that all phone numbers have, at most, 9 digits.
Press F3 to leave the table view and type the following commands. Type:
CREATE LIBRARY DEMO/CLIENTS( id_cli numeric(10) PRIMARY KEY, name_cli
char(50), birth_cli date, phone_cli numeric(9) )
Note: You can place the code in separate lines (like in the example) or in a continued
fashion (without indentation) as long as you don't press the Enter key before you finish
the command. A message will appear saying that the table was created. If you want to
see more empty command lines just press Page Down or move the mouse scroll down.
Now Type: SELECT * FROM CLIENTS, This way you can see that the table was
created and it has no information in it. So let's insert some new rows. Press F3 to leave
the table view and type the following commands.
INSERT INTO CLIENTS (ID_CLI, NAME_CLI, BIRTH_CLI, PHONE_CLI) VALUES (1,
'Mary', '12/09/1967', '999999999')
INSERT INTO CLIENTS (ID_CLI, NAME_CLI, BIRTH_CLI, PHONE_CLI) VALUES (2,
'Tom', '09/01/1979', '123456789')
Do the SELECT command again to check if the rows were correctly inserted.

Press F3 to leave the SQL command line. A set of options will appear. On the field you
should write the option number. Try typing a number outside the option range (for
instance 5) and then press Enter. As one would expect, an error message appears on
the bottom of the screen. Try pressing F3 or inserting another value. It won't work
because the screen is blocked. You will probably find some blocking errors and when
you do press Esc the screen will go back to normal. Now select the option 1 to exit the
application, saving the session.
SQL Built-In Functions
There are some very useful SQL built-in functions on the AS/400 system.
Basic Functions
If you know SQL you may already be familiar with these functions.
Function Description
MAX Returns the maximum value from a set of pre-defined values.
MIN Returns the minimum value from a set of pre-defined values.
AVG Returns the average value of a set of pre-defined values.
SUM Returns the sum of a set of pre-defined values.
COUNT Returns the number of elements in a set of pre-defined values.
Example (returns the maximum ID_CLI value from all the rows in the table CLIENTS):
SELECT MAX(ID_CLI) FROM CLIENTS
Numeric Functions
Function Description
ABS(N) Returns the absolute value of N.
COS(A) / ACOS(A)
SIN(A) / ASIN(A) Basic trigonometric functions.
TAN(A) / ATAN(A)
CEILING(N)
Returns the rounding of N to the unit above/below.
FLOOR(N)
DEGREES(R) Converts a value in radians to degrees.
RADIANS(D) Converts a value in degrees to radians.
LN(N) Returns the natural logarithm / base 10
LOG10(N) logarithm of N.
String Functions
Function Description
CHAR(N) Returns the the string representation of the number N.
CHAR_LENGTH(S) Returns the length of a string.
CONCAT(S1, S2) Concatenates S1 with S2.
SUBSTR(S, I, L) Returns a substring of S, starting at index I of lenght L.
LOWER(S) Returns the lowercase representation of S.
UPPER(S) Returns the uppercase representation of S.
TRIM(S) Removes spaces from the beggining and and of S.
RTRIM(S) LTRIM(S) Removes spaces at the begging (right) or end (left) of S.
Date and Time Functions
Function Description
CURDATE()
Returns the system's current date/time.
CURTIME()
DATE(D) Converts a string representation of a date/time into into a
DATE(T) date/time value.
DAY(D) Returns the day(1-31) from the date D.
WEEK(D) Returns the week (1-54) from the date D.
MONTH(D) Returns the month (1-12) from the date D.
Function Description
YEAR(D) Returns the year from the date D.
DAYOFWEEK(D) Returns the week day (1-7) from the date D where 1 is Sunday.
DAYOFWEEK_ISO(D) Returns the week day (1-7) from the date D where 1 is Monday.
DAYOFYEAR(D) Returns the number of the day, in a year (1-366).
HOUR(T) Returns the hour (0-24) from the time T.
MINUTE(T) Returns the minute from the time T.
SECOND(T) Returns the second from the time T.
MICROSECOND(T) Returns the microsecond from the time
AS/400 Chapter 5: Physical Files
You can use files to define tables, executable code, etc. In this chapter we'll try to
explain some basic concepts of working with files.
We've created a table using SQL, now we'll create the remaining tables with DDS.
Source files are files that can have several members. Each member represents the
source code from an executable object or an executable object. A source file is similar
to a folder where you can organize its members. The source file naming follows an
established convention:
QRPGLESRC – file that holds the members written in RPG-ILE language.
QDDSSRC – holds the members written in DDS.
QRPGSRC – holds the members written in the traditional RPG language.
As you can see, all the names start with a Q and end with SRC. You don't need to
follow this convention and there isn't any problem at the system level if you don't. But
since it's a well established convention and it really helps with the code organization,
you should follow it. Let's create our first source file where we will later add our DDS
tables. CRTSRCPF FILE(DEMO/QDDSSRC)
If you're currently in the DEMO library you don't need to specify it in the command.
PDM (Programming Development Manager)
We're going to use the PDM application that enables the user to write the source code
and compile it, among other things. PDM uses the SEU (Source Entry Utility) text editor,
we will see how to use it in this chapter. To start the PDM type the command: STRPDM
A screen similar to this will appear:

Choose the option '3. Work with members'. We are going to create some members in
the QDDSSRC source file. With the option 2 you can work with compiled objects and
with option 1 work with libraries. On the next screen you will be asked for the filename
and the library where it's stored. Insert the information you see in the image below:

Note: Your current library and the library you are working with in PDM are two different
things. You can be working with members from DEMO and your current library can be
DEMO2, for example. Now you should see the screen bellow. You will find all the
options for working with file members.
Press F6 so you can create your first member (you can see in the options bellow the
prompt: “F6=Create”). Insert the information as you see below:
Working with SEU (Source Entry Utility)
SEU screen:

RPG and DDS are positional languages, wich means that each element has a specific
line and column were it should be placed in the source code. SEU gives us a little help
to position each element in its place. If you put the cursor in any of the SEU's lines and
press F4 a prompt will appear, like the one in the next image, where you can write each
element and the SEU will place it its right position. To close the prompt press F12.

Insert a new line


Write an “i” (without quotes) on any position of the numbered column on the left. Press
Enter, and a new line will be added bellow.
Delete a line
Write a “d” (without quotes) on any position of the numbered column on the left and
press Enter.
Delete several lines
Place “dd” (without quotes) on the numbered column of the first line you want to delete
and another set of “dd” on the last line to delete, press Enter.
DDS Syntax
Let's start by defining the member SHOPS as it's written bellow. After the code you'll
find the explanation of what each line means.
UNIQUE
R SHOPR
ID_SHP 10P
NAME_SHP 25A
MANAGER_SH 50A
K ID_SHP
Line 1
To ensure that the primary key has an unique value for each record you must specify
the keyword UNIQUE in the first line of the table definition. Press F4 and write unique in
the functions field.
Line 2
Here you define the table record name. The record identifies all the fields in a table. We
will see an example of its use in the Display Files chapter. Insert a new line bellow the
first, as we explained previously and press F4. Place an “R” in the Name Type field and
SHOPR in the Name field.
Line 3, 4 e 5
Definition of the table fields. In the third line, for instance, in the F4 prompt you should
place “ID_SHP” in the Name field, 10 in the Length (must be right justified in the field),
“P” in the Data Type (because it's a numeric value).

Most common data types :


A - Alphanumeric
S – Numeric (Zoned Decimal)
P – Numeric (Packed Decimal)
L - Date
For more information on data types press F1 after you placed the cursor on the Data
Type field. Or visit ILE RPG Reference.
Line 6
Definition of the primary key field. “K” is the Name Type and in the Name you should
write the name of the field exactly as it is written above. For more than one primary key
you should have a different “K” starting line for each primary key field.
When you finish writing the code press F3 to leave the editor and save the changes
you've made.
Useful DDS Functions
If you want to use any of these functions place it in the Functions field.
CHECK
CHECK(AB): Allows the field to be blank
CHECK(ME): Mandatory Enter. The field must have a value (not blank).
CHECK(MF): Mandatory Fill. For example, if you have a string of size 50 all the 50
characters must be filled.
COMP
Compares values. The syntax is COMP(relational-operator value), where relational-
operator can be one of these values:
EQ (equal)
NE (not equal)
LT (less than)
NL (not less than)
GT (greater than)
NG (not greater than)
LE (less than or equal to)
GE (greater than or equal to)
DATFMT
Specifies the format of a Date field. Some of the possible formats are:
*ISO: yyyy-mm-dd
*EUR: dd.mm.yyyy
*USA: mm/dd/yyyy
*MDY: mm/dd/yy
*DMY: dd/mm/yy
*YMD: yy/mm/dd
TIMFMT
Specifies the format of a Time field. Some of the possible formats are:
*ISO: hh.mm.ss
*EUR: hh.mm.ss
*USA: hh:mm AM/PM
*HMS: hh:mm:ss
RANGE
Defines the maximum and minimum value a field can have.

Examples:
For a numeric field: RANGE(4 9)
For a non-numeric field: RANGE('4' '9')
VALUES
Specifies all the valid values on a field.

Examples:
For a numeric field: VALUES(4 5 6 7 8 9)
For a non-numeric field: VALUES('a' 'b' 'c' 'd')
DFT
Specifies a default value.
REFFLD
Specifies that a field refers to a field in another table (foreign key). In this case you don't
specify the Data Type or the Length of the field, but you must place an “R” in the Ref
field in the F4 prompt. Example:
CARD_MOV R REFFLD(ID_CRD DEMO/CARDS)
Compiling Files
To create the object that will save the data (the file you've just created only stores the
source code) choose option '14- Compile' in the file you've created.

This tutorial won't teach you to analyse the resulting files from a compilation, but if you
want to give it a go write the command WRKSPLF (Work spool file) in the system
prompt. The most important messages from the compilation usually appear on the file
with the same name as the one you compiled (the most recent compilation appears on
the bottom of the list). A quick way to check if a file's compilation was successful is to
see if the new object was created. To do so you must go to the opening screen in the
PDM choose option '2 – Work with objects' and put the options as you see in the image
bellow and press Enter.
Now check to see if there's a member named SHOPS (the same name you gave to the
source code member). If you do this you need to be careful because this only works
correctly for the first compilation, because an object always keeps the data from the last
successful compilation. So, if after a successful compilation you alter the source code
and compile it again, even if this compilation ends in error, the object will still be in the
system with the definitions of a previous compilation. You can however delete the
compiled object before a new compilation (in the same menu where you checked if the
file exists) - this way you can be sure that the compilation was successful. You have
now all the information you need to create DDS tables. Create the CARDS and
MOVEMENTS tables, using the same field’s names as in the data model, because we
will be using those later on. When you're finished, or if you have any doubt, check the
files with the final results.
AS/400 Chapter 6: RPG
RPG is one of the AS400 platform pillars. Originally designed as a query tool
it has been substantially enlarged, it is currently a very powerful language. Let's see
how you can use it. RPG is a programming language best suited for business
applications. Originally the acronym meant Report Program Generator, but currently it
has no officially meaning. For the purpose of this tutorial we will use the latest RPG
version: RPG IV. RPG, like DDS, is a positional language despite its last version allowing
a free format where you can place the code in mostly any column or line. In the RPG code
there are several different types of specifications. Each has a different function and they
all appear in the file in a specific order. The letter that represents the specification must
be placed in the initial position of the source code line. Next we have a description of
each specification in the order they appear in a file.
H Specification (header)
Compile/execution options.
F Specification (file)
Files definition and how they are used in the program. Options in an F specification (for
more info on any option place the cursor on it and press F1):
D Specification (definition)
Here you can define variables and data structures, for instance:

C Specification
Here you define the source code. There is a free format for this specification but to do
so instead of placing a C at the beginning of a line you should place free in the
beginning of the code block and end-free in the end. These keywords must start in the
the second position from the beginning of the line (in SEU).
Basic RPG Syntax
Valid operators
= (compare and attribute), +, -, *, /, >, >=, <, <=, <>, NOT, AND, OR
Conditional Expressions
if condition;
//code
else;
if other-condition;
...
endif;
endif;
Ciclo do-while
doW condition;
//code
endDo;
Creating and defining an RPG member

In this chapter you're going to create a program that shows the number of cards the
client with ID 1 has. You must first insert some records in the CARDS table associated
with client 1. Do this from STRSQL. Create the source file DEMO/QRPGLESRC. Inside
this source file create a member named COUNTCARDS. The member type must be
SQLRPGLE. Since we're not going to explicitly open any file, there won't be any lines
with F specification. You must define a variable (count) that will store the number of
cards from the client. Place the letter “D” in the first column of the SEU editor and press
F4. This variable will be simple (place an “s” in the Declaration Type), numeric, with
length 5 and 0 decimal places. Initiate the variable to zero with the function INZ(initial-
value) in the Keywords field. Were you able to declare the variable with the F4 prompt
help? If not, check the final result further ahead. Try to create the code for the next three
points. Keep in mind that in the free format RPG you can write your code in whatever
column you like (but it must at least start in column 3 in the SEU) and that each code
line must end with a semi column (;).
Initiate (/free) and finalize (/end-free) the code block in separate lines, starting
from the second column in SEU.
Print the value of the count variable. To print values on the screen you can use
the dsply function. Dsply syntax: dsply value.
In the last line, before /end-free, you must activate the end of code indicator *inlr
(in last row). You activate it like this: *inlr = *on;
If you completed the three points and declared the variable you should have something
like this:
* this is a comment
* variable definition
Dcount s 5P 0 INZ(0)

/free
dsply count; * displays the count value on the screen
*inlr = *on; * tells the compiler that this is the last line.
/end-free
Try to compile the source code now (option 14 of PDM). If the compilation was
successful execute the program typing the following line in the system prompt:
call DEMO/COUNTCARDS The following information should appear:
dsply 0
A list of values may appear (from previous events), but the one from the current
execution is the last one on the list. For instance if you call the COUNTCARDS twice on
the list you'll see:
dsply 0
dsply 0
We still need to count the number of cards client 1 has.
Embedded SQL and Subroutines

To view and alter tables we can use SQL code embedded in RPG code (RPG provides
a way to manipulate tables, but since you should already know SQL we'll use it instead).
This is how we embed SQL in RPG:
c/EXEC SQL
c+ SQL-instruction
c/END-EXEC
In each EXEC block you can only have one SQL statement. We will see a better
example of this in the next chapter. So, to retrieve the number of cards we can do this
query (write this code at the end of the source code, after the end-free):
c/EXEC SQL
c+ SELECT COUNT(*) INTO :count FROM DEMO/CARDS
c+ WHERE CLIENT_CRD = 1
c/END-EXEC
To better organize your code we will place this EXEC block in a subroutine. A
subroutine is kind of like a function but it doesn't allow parameter passing or returning
values although you can change globally defined variables. Inside a subroutine you can
have free-format RPG, fixed-format RPG or EXEC instructions. The EXEC block you
just created should be placed in a subroutine called getNrCards. This is how you do it
(you can use the F4 prompt to place the keywords correctly):
c getNrCards begsr
c/EXEC SQL
c+ SELECT COUNT(*) INTO :count FROM DEMO/CARDS
c+ WHERE CLIENT_CRD = 1
c endsr
To run the subroutine you must call it in the main /free block. Place this line before
displaying the count variable.
exSr getNrCards; *execute sub-routine getNrCards
Compile and run the code again. Did you get the same result? If so, check to see if
client 1 exists and that there are cards associated with him. And, of course, the tutorial
must be correctly completed until this point. If even that doesn't work compare your
code with this one:
Dcount s 5P 0 INZ(0)
*------------------------------------------------*
/free
exSr getNrCards;
dsply count;
*inlr = *on;
/end-free
*------------------------------------------------*
c getNrCards begsr
c/EXEC SQL
c+ SELECT COUNT(*) INTO :count FROM DEMO/CARDS
c+ WHERE CLIENT_CRD = 1
c/END-EXEC
c endsr
AS/400 Chapter 7: Modules and Procedures
Implementing modules can be extremely useful, especially in big applications because it
allows the reuse of code in a fairly simple manner.
A module is an executable program's component. When we compile a module's source
code we don't get an executable file, but a unit that when connected to other units
results in the executable object. A module can have on or more procedures. A
procedure is like a function. You can pass parameters to it and return values. One of the
advantages of modules is the possibility of reusing the code, since you can use a
module as a component of several different executable objects.
Creating modules
We're going to create two modules and then connect them into an executable object.
What the modules will do: the main module sends a client's birth date to a procedure in
the other module and this procedure will return the age of the client. We're going to
calculate the age of all the clients. Let's start with the main module. Create an
SQLRPGLE member called MAIN_MOD. Define a date variable to store the birth date
(name it birth) and a numeric one to store the age (name it age). Let's build a cursor to
go through all the records in the CLIENTS table. For the cursor we need 4 subroutines:
Declaring the cursor (subroutine name: declareCursor)
DECLARE CURSOR1 CURSOR FOR SELECT BIRTH_CLI
FROM DEMO/CLIENTS
Opening the cursor (openCursor)
OPEN CURSOR1
Fetching values from the cursor (fetchCursor)
FETCH CURSOR1 INTO :birth
Closing the cursor (closeCursor)
CLOSE CURSOR1
Now for the main block of the code, call the subroutine to declare the cursor and to
open it. Then, inside a cycle, fetch values from the cursor like this:
exSr fetchCursor;
dow sqlcod <> 100;
...
exSr fetchCursor;
enddo;
or
dow sqlstt = '00000';
exSr fetchCursor;
...
enddo;
sqlcod and sqlstt variables store the state from the last SQL instruction performed.
Sqlstt = '00000' means success, while sqlcod = 100 means the last instruction didn't
retrieve any data. Let's close this module and create the second module with the
procedure that calculates the age. Create a new RPGLE type member named
CALC_AGE.On the first line of this member should be HNOMAIN, starting at the first
SEU column. This means that this module won't be a main module.
Procedures
Now we're going to see how to declare a procedure and its parameters. A procedure is
delimited by:
1. Pnome_proc B EXPORT
2. Dnome_proc PI 3i 0
3. Dparametro1 D
4.
5. ...declarações de código
6.
7. P E
Line 1
Beginning of the procedure, with a P starting the line. The B (begin) defines the
beginning of the procedure and the E (end) at line 4 defines its end. The EXPORT
keyword makes this procedure public to other modules. If it didn't have this keyword it
could only be used inside this module.
Line 2
The name of the procedure is repeated this time in a D specification. In this line the
return type is declared. The return type of this procedure is “3i 0” - an integer of length 3
with 0 decimal places. If the procedure doesn't return any value, declare this line without
the return type. In this case you wouldn't declare '3i 0'.
Line 3
Defines a parameter. A procedure can have more than one parameter and each one
should be declared in a different line. By default the parameter is passed by reference.
To pass a parameter by value we use the VALUE keyword in the functions field. With
the CONST keyword the parameter is passed by reference and its value can't be altered
in the procedure.
Linha 7
End of procedure. Now you can define the beginning and end of the CALC_AGE
procedure (it has the same name as the file but it could have another name). The
procedure will receive a date by parameter and return an integer - define them. Outside
the parameter definition declare an auxiliary variable to store the age (name it age).
When you're through with this, check if it looks like what we have bellowed, and add line
6 to your code:
1. Dage S 3P 0
2. PCALC_AGE B EXPORT
3. dCALC_AGE PI 3i 0
4. Db_date D
5. /free
6. age = %diff (%date() : b_date : *years);
7. return age;
8. /end-free
9. P E
Linha 6
The %date() function returns the system date. The %diff function calculates the
difference between two dates (%date() and bdate) in years (*years). Notice how the
values are separated by a colon (:). This is the parameter separator used in RPG. It's
just like the comma used in C++ or Java. For more information on manipulating dates in
RPG check this site.
Linha 7
Returns the value.

There is still one detail missing in the declaration of procedures. Every time we declare
a procedure or we need to call it from another module we must place the procedure's
prototype in the D specification of the file. This procedure's prototype:
DCALC_AGE PR 3i 0
Db_date D
So, you must put these lines in the CALC_AGE file (before or after the declaration of the
age variable). You declare it there and on the MAIN_MOD file, because you need to call
this procedure there. Notice de declaration of the return type and the parameters on the
prototype. These values must match those on the beginning of the procedure.
*
HNOMAIN
*
Dage S 3P 0

DCALC_AGE PR 3i 0
Db_date D
*
PCALC_AGE B EXPORT
dCALC_AGE PI 3i 0
Db_date D
/free
age = %diff (%date() : b_date : *years);
return age;
/end-free
P E
Back to MAIN_MOD, we're going to declare the procedure's prototype and call it. You
should have something like this:
Dbirth s d
Dage s 3i 0
/free
exsr declareCursor;
exsr openCursor;
exsr fetchCursor;

dow sqlcod <> 100;


exsr fetchCursor;
enddo;
exsr closeCursor;

*inlr = *on;
return;
/end-free

*
* declaração das sub-rotinas
*
Declare the prototype exactly the same way as you declared it on the CALC_AGE
file.Inside the cycle you must call the procedure:
age = CALC_AGE(birth);
The cycle should look like this:
dow sqlcod <> 100;
age = CALC_AGE(birth);
dsply age;
exsr fetchCursor;
enddo;
Compiling modules
Compile the two members (MAIN_MOD and CALC_AGE) with PDM's option “15-Create
module” (this is the one you should always use to compile modules). After compiling the
modules, connect them into an executable file, as we show you next.
Criação de um programa a partir de módulos
You connect modules with the command:
CRTPGM(PGM_NAME) MODULE(MAIN_MOD MOD1 MOD2...)
The first module on the modules' list is always assumed to be the main one. In this
case, MAIN_MOD is the program's main module. To call the program from the system
prompt: CALL PGM_NAME
AS/400 Chapter 8: Display Files
In this chapter you will see how to create menus and screens in AS400.
Display files are DDS files that enable us to create AS/400 menus and screens to
interact with the user. Display files can have several records. Each record defines part
of the screen's appearance. These records may or may not overlap each other.

The SDA application allows us to “draw” what should show up on the screen and
creates the DDS code from our “drawing”. Next we'll create a screen with DDS and
afterward we'll look at some code excerpts, because sometimes it's easier to alter the
screen through its code. In this chapter we'll create a screen to show a clients data.
To open SDA type STRSDA on the system prompt. This screen should appear:

Choose option 1 and type the options as you see them on the image below. Source file
is the file where the code will be stored. Member is the name of member we're creating.

Press Enter. A new screen appears. Add a new record, named TOP, typing what you
see on the image bellow.

Now specify the record type, in this case it's RECORD:


After the Enter an empty screen appears. In this screen you can “draw” the top record.
Add the content you see on the image bellow. When you type a string you should place
it between apostrophes. If you don't each word will be handled like a different field.
Placing the apostrophes allows you to manipulate all the words as a single field. The
*USER function shows the username on the screen. There are other functions that
retrieve information from the system: *DATE (shows the system current date),
*TIME(shows the system current time), *SYSNAME (shows the system name).

After typing what you see on the image press Enter. Always check what you've done
before pressing Enter, because after that you can only alter the screen by manipulating
its code. You can also exit the record editing without saving your work, but then you'll
lose all you've done since you last opened the record for editing.
Moving a field
You can move a field to the right placing “>” characters to the right of the field. The
number of > you type will be the number of columns the field will move. To move the
field to the left place < signs on the left side of the field.

Centering a field
To center a field on the screen place an 'ac' at the left of the field and the 'c' must be
overlapping the first character of the field. Then press Enter. Press F3 to finish editing
this record. Choose option 1 to save your work:

Create another record named BOTTOM, the same way you've created the TOP record.
When you open the new record for editing press F9. This menu will appear:
So that you don't overlap the records you can choose to visualize other records in the
menu. You can see that the status of the BOTTOM record is “In Use” wich means it is
the one currently being edited. You can select at most 3 records to visualize. To do so
place numbers 1 to 3 on the records you want. Select the TOP record and press Enter.

The names of the selected fields appear on the bottom of the screen. Don't forget you
are only “drawing” on the record in use. The other records only help you place your
elements on the right place. “Draw” something similar to what you see in the next
image.Use the underscore to make the line.

Changing field proprieties


We're going to edit the proprieties of the “F3=Exit” field. Place an '*' at the left of the field
and press Enter:

This screen appears. Place an 'Y' in the Colors option. We're going to change the color
of the characters.
Place an 1 in the Blue field:

Press Enter until you're back in the editing screen. The field is now blue. Exit the editing
screen (F3) and save your work. Create a new record, MIDDLE; the same way you've
created the previous records.
Press F9 to visualize the records you already created:
Draw what you can see in the following image. Press Enter when you're done.

Using table records


We're going to select the fields from the Clients table to show them on the screen. Press
F10. On that menu select the Database File Clients for output (option 3). You can also
select fields for input or input/output choosing one of the other options. You should write
this on the menu and press Enter:
On the bottom of the screen there's a message with all the Client's field names
preceded by a number. To use a field on the screen you should write its correspondent
number preceded with an '&'. You can see it in the next image. Be careful, because if
you write a number and press Enter the order of the list on the bottom will change.

The final result:


Exit the record editing. We now need to make a few adjustments to the file options.
Record level options (overlay)
Choose option 8 to the TOP record:

Select option Overlay Keywords:


Place an Y at the option Overlay without erasing. This option allows to display this
record on the screen together with the others. Press Enter until you reach the menu with
the record listing. Activate this option on the other records.

File level options (indicadores)


We need to declare the indicator 03 (so that “F3=Exit” works) at the file level. On the
menu with the record listing press F14 (F13=shift+F1; F14=shift+F2; F15=shift+F3,
etc.). On the following screen choose the option Indicator Keywords.
Insert the data you see on the image below:

Press Enter until you've reached the starting menu. Press F3 and save the file.
Display Files DDS code

You can check out the code from this display at QDDSSRC, the member is SHW_CLI.
At the beginning of the file should be something like this:
A DSPSIZ(24 80 *DS3)
A CF03(03 'Exit')
These are the file-level options. You should add a line to this area that later will allow
you to rename the indicators used. Add this line after the DSPSIZ line:
A INDARA
You should also have some lines like these:
A R TOP
A OVERLAY
A 1 65USER
A 3 27'Client Details:'
In these four lines are the definitions to the TOP record. Notice the OVERLAY option we
had defined in SDA. The keyword USER is placed on the 1st line, column 65.
Look at this line from MIDDLE record:
A ID_CLI R O 8 23REFFLD(CLIENTS/ID_CLI DEMO/CLIENTS)
Here you have a reference to the ID_CLI field on the CLIENTS table and this reference
is positioned at line 8 column 23, an can only be accessed for reading (O).
Compile the file (option 14) after you've closed the member.
Executing display files
To run the screen you must create an RPGLE member wich will handle all the possible
events (pressing F3 for example). Check out the file QRPGLESRC.SHW_CLI to see
how this member should be defined. Create a file like QRPGLESRC.SHW_CLI and run
it. The result should be something like this:

If you press Enter:


AS/400 Chapter 9: Subfiles
With subfiles you can create a display file with lists of items. Let's see how that's done.
A subfile is a display file where you can place a listing of values and process changes
on the list. The list of members that you can see in the PDM is an example of a subfile.
In this chapter we'll create a subfile wich will show all the cards from a client given its ID.
To make the manipulation of several tables easier, we'll create a view with the fields
we'll use on the subfile. In STRSQL insert this code:
CREATE VIEW CLICARD AS SELECT CL.ID_CLI, CR.ID_CRD, SH.NAME_SHP,
CR.SHOP_CRD
FROM DEMO/CLIENTS CL, DEMO/SHOP SH, DEMO/CARDS CR
WHERE CL.ID_CLI = CR.CLIENT_CRD AND CR.SHOP_CRD = SH.ID_SHP
Open SDA (STRSDA) and create a new member:

Create a BOTTOM record that should look like this:


And the TOP record like this:

Let's create the subfile now. Create a new record, name it LIST, the record type is SFL:

When you press Enter a new record appears. Write SFLCTL on it:

This field creates a subfile control record, wich works like the heading on the list.
You have to activate some options now:
On the General Keywords menu insert the data you see below:

These indicators allow us to manipulate the status of the subfile from the RPG code.
Press Enter to go back to the previous screen. Select Subfile display layout.
On subfile maximum size type 9999 and on the number of records for page type 9:

Press enter to go back. Select the option Select Record Keyword:

Choose Overlay keywords:


Select Overlay without erasing:

Press Enter until you're back on this screen:


Open the SFLCTL record. By default the record list is already visible on the design
screen. Select to visualize the other 2 records, TOM and BOTTOM (F9).

Back to the design screen, write at the top “Client Nr.”. Select the fields from CLICARD
view for input/output (F10) and select the ID_CLI field:

Type the titles of the subfile's columns and a separating line:


Let's add some proprieties to the Client ID field. Place an * before to the left of the field.

We're going to add an indicator to this field, wich will be activated when no record is
found for an ID inserted (either the ID doesn't exist or it doesn't have any associated
cards). Option Error Messages:

Insert the following information:


Close this record and open the LIST record. Select the TOP and BOTTOM records for
display (F9):

To create an input field, where the user will type the options, type '+i' on the same
position as in the following image and press Enter.

Notice how the field spread across the 9 line you previously defined as the subfile page
size.
Select the records from CLICARD view for output.

The fields will probably be listed twice, because the SDA will show you the field that had
been previously loaded from I/O in the SFLCTL record. You should select the fields
further to the right, because they are the last ones loaded. You must be careful
selecting the fields.If there are more fields than the ones that can fit the message line, a
plus (+) sign will appear at the end of the line. Press Page Down to see the remaining
fields.

Place the fields on their positions:


The final result:

Don't forget to activate the indicator 03 at file-level so that “F3=Exit” can work and add
the keyword INDARA to the code. Check out the Display file chapter if you don't
remember how to do this.
You must add the red line to the SFLCTL record:
A R SFLCTL SFLCTL(LIST)
A SFLSIZ(9999)
A SFLPAG(0009)
A OVERLAY
A 30 SFLDSP
A 31 SFLDSPCTL
A 35 SFLCLR
A 33 SFLEND(*MORE)
A 4 8'Client Nr.'
A ID_CLI R B 4 19REFFLD(CLICARD/ID_CLI DEMO/CLICARD)
A 90 ERRMSG('No Data Found')
A 6 4'Op.'
A 6 12'Card Nr.'
A 6 27'Shop Nr.'
A 6 42'Shop Name'
A 7 2'__________________________________-
A ___________________________________-
A __________'
A RRN 4S 0H SFLRCDNBR(CURSOR)
In the LIST record change the name of the input field to OPTION. By default it must be
named FLD001, or something like it.
A R LIST SFL
A OPTION 1A I 9 5
(...)
Executing the subfile
To run the subfile you must create an RPGLE member. Check out the file
QRPGLESRC.SHW_SFL for more details on how to write this member.
When you run the RPGLE code:

And so we finish this series on AS/400.

Das könnte Ihnen auch gefallen