Top Banner
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
45
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: As/400

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

Page 2: As/400

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

CPY Copy

DSP Dysplay

DLT Delete

WRK Work

Noun Meaning

DEV Device

F File

MSG Message

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

Page 3: As/400

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

Page 4: As/400

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')

Page 5: As/400

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.

Page 6: As/400

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)

TAN(A) / ATAN(A)

Basic trigonometric functions.

CEILING(N)

FLOOR(N) Returns the rounding of N to the unit above/below.

DEGREES(R) Converts a value in radians to degrees.

RADIANS(D) Converts a value in degrees to radians.

LN(N)

LOG10(N)

Returns the natural logarithm / base 10

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()

CURTIME() Returns the system's current date/time.

DATE(D)

DATE(T)

Converts a string representation of a date/time into into a

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.

Page 7: As/400

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

Page 8: As/400

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.

Page 9: As/400

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:

Page 10: As/400

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.

Page 11: As/400

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.

Page 12: As/400

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)

Page 13: As/400

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.

Page 14: As/400

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):

Page 15: As/400

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

Page 16: As/400

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.

Page 17: As/400

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

Page 18: As/400

*------------------------------------------------*

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;

Page 19: As/400

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

Page 20: As/400

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

Page 21: As/400

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;

Page 22: As/400

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

Page 23: As/400

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:

Page 24: As/400

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.

Page 25: As/400

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:

Page 26: As/400

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

Page 27: As/400

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.

Page 28: As/400

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:

Page 29: As/400

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:

Page 30: As/400

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:

Page 31: As/400

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:

Page 32: As/400

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.

Page 33: As/400

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:

Page 34: As/400

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:

Page 35: As/400

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:

Page 36: As/400

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:

Page 37: As/400

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.

Page 38: As/400

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:

Page 39: As/400

Select Overlay without erasing:

Press Enter until you're back on this screen:

Page 40: As/400

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:

Page 41: As/400

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:

Page 42: As/400

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.

Page 43: As/400

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:

Page 44: As/400

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

(...)

Page 45: As/400

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.