Beruflich Dokumente
Kultur Dokumente
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.
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).
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).
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.
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;
*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.
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.
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.
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:
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:
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:
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:
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.
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: