Professional Documents
Culture Documents
Ile
Ile
Ile
ARRAYS
BUILT IN DATA Q
FUNCTIONS PROGRAMMING MISC
1
RPG-ILE LABS
DATABASE
PROCESSING
2
RPG-ILE LABS
SIX
DAYS
BREAKUP
Day Remarks
Coverage
1 COMPARISON CHART FEATURES CHEAT SHEETS OPERATION EXTENDERS
BASICS ARRAYS BUILT IN FUNCTIONS DATE TIME PROGRAMMING DATA
STRUCTURES
2 DATA AREA STRING OPERATION VALIDATION SUBFILES API RLU
3 DISPLAY FILES COMPILER DIRECTIVE Data Type Conversion
4 ADVANCED DATABASE PROCESSINGERROR HANDLING ODP PROCEDURES and
MODULES. Bind by COPY and REFERENCE SERVICE PROGRAM BINDER
LANGUAGE ACTIVATION GROUP
5 DATA Q PROGRAMMING MESSAGING EMBEDDED SQL LOGIC CYCLE MONITOR
TESTING POINTERS FREE SMALL UTILITY PROJECT (imp !!!)
6
Assignments
3
RPG-ILE LABS
1. Utility to accept object name from user and display locations where the sources of the object are present.
2. Compare utility : Compare contents of 2 members of a source physical file and produce a report.
3. Utility to locate all libraries where specified object is present and write the libraries to a physical file.
4. Utility to locate source member and source physical file of the specified object and store it to a database
file. Following report should be created :-
5. Utility to display all members of a source PF. User selects a few members. Combine all members and store
them to a new member (name specified by user). The data for each member should be easily identifiable.
6. Write a utility to accept member name and type from user and set of libraries to search. After user
finishes entering the libraries (or asks you to refer to the library list), search each for presence of that
member (search all source physical files in the library) for presence of that member.
7. RPGLE editor : Create a simple multi-Document Editor, which behaves like Notepad. (Notepad /400 ! )
8. A utility to display all physical and logical files containing XXXX entered by user ( eg. : User enters
“FSTS” as a search string. The utility scans the library list / list of libraries specified by user and displays
names and libraies of all Physical files and logical files containing the specified field name.)
9. Utility to display all source physical files present in all libraries in the library list and write the list to a
database.
1. A Physical file P1 may have several logical files (say L1,L2,L3,L4 … ) based on it. Programmer makes a
change to DDS of the Physical file and updates the PF object using CHGPF. This does not automatically
update the LFs sicne they all use old definition. To update all Logical files, you need to compile all of
them. This can get quite tedious. Build a utility to automatically determine and compile all the logical
files.
2. Write a Utility to read source code of a program (member name will be specified by user) and write it to a
spool file after indenting it. Indentation will be provided to IF statements and Do loops.
** *
4
RPG-ILE LABS
1.
P ROJ ECT S
1. A new module is to be developed for a bank. The module is for Calculation of interest on Saving A/c. It
should allow inputing new customer, and saving any transactions done by the customer. For formula of
calculating interest , see EPM.
2.
5
RPG-ILE LABS
RPG - IL E LA BS
LAB : Source Physical file : QRPGLESRC
LAB : Study of new Specs : HFDICOP. Structure and purpose of each. New Spec : CX.
F : SPEC :
6
RPG-ILE LABS
A : Character
B : fixed Binary
D : date Field
F : Floating point
G : Graphics character set
I : Signed Integer
P : Packed Decimal
S : Zoned Field
T : Time field
U : Unsigned Integer Field
Z : Timestamp Field
* : Pointer Field
DA01 S 2P 0 Inz(-1)
C*
7
RPG-ILE LABS
C A01 DSPLY
C*
C EVAL *INLR = *ON
DCON1 C CONST('ABCDEFGHIJKLMNOPQRSTUVWXYZ+
D cdefghijklmnopqrstuvwxyz')
C CON1 DSPLY
C EVAL *INLR = *ON
LAB : RPG Constructs IF, DOW, DO, DOU,LEAVE ,ITER.
LAB : DO WHILE
Output : 1 2 3 4 5
LOGIC :
1.124
+ 0.001
-----
1.13 (ROUNDED)
1.12 (NOT ROUNDED)
8
RPG-ILE LABS
RPGLE PROGRAM :
FDSRND CF E WORKSTN
DCRS S 5S 3 INZ(1.121)
DRATE S 5S 3 INZ(0.001)
DTOTAMT1 S 5S 2 INZ(0)
DTOTAMT2 S 5S 2 INZ(0)
C DO 5
C EVAL TOTAMT1 = RATE + CRS
C* now try with (H) for Rounding.
C EVAL(H) TOTAMT2 = RATE + CRS
C EVAL DTOTAMT1 = TOTAMT1
C EVAL DTOTAMT2 = TOTAMT2
C EXFMT R1
C EVAL RATE = RATE + 0.001
C ENDDO
C SETON LR
Step 1 : Compile the program with Debugging Views set to *SOURCE. This allows the
Debugger to access the source code of the program and display it.
Step 2 : Use STRDBG and press F4. Specify “Display Module Source “ parameter as
*YES. Press Enter.
Step 3 : The Source code will be displayed. Take the cursor to the line that needs a
break point and press F6.
9
RPG-ILE LABS
To Display the current value of a variable : Bring the cursor under the variable and
press F11.
Press F3 to exit Debugger. Issue the ENDSBG command to end the Debug mode.
Linkage : RPLEAVE
CODE :
da s 4s 0 inz(4)
d
c 'BEfore SR' dsply
c ExSR SR001
c 'After SR' Dsply
c Eval *inlr = *on
c Return
c*
c SR001 BegSR
c 'SR starting' Dsply
c if a = 4
c LeaveSR
c EndIf
C* ----------------------------------------
C* The following line never gets executed !
C* ----------------------------------------
c 'Ending SR' Dsply
c EndSR
PF contents :
---
OUTPUT :
DSPLY BEfore SR
DSPLY SR starting
DSPLY After SR
REMARKS :
dn1 s 4s 0 inz(0)
d
d
d
d
c For n1= 10 DOWNTO 1 by 2
c n1 dsply
c EndFOr
c Eval *inlr = *on
c Return
10
RPG-ILE LABS
If n1 increments :
c For n1= 1 TO 10 by 2
If n1 decrements :
11
RPG-ILE LABS
Lab : H-SPECS
H DATFMT(*YMD)
DJSRDT1 S D INZ(D'04/12/10')
C JSRDT1 DSPLY
C SETON LR
H DATFMT(*YMD) CURSYM('£')
H* ALT 156 FOR POUND SIGN
H*
DJSRDT1 S D INZ(D'04/12/10')
DCIH S 7P 2 INZ(120.25)
C JSRDT1 DSPLY
C CIH DSPLY
C SETON LR
DDT1 DS
DDAT1 D DATFMT(*ISO-) INZ(D'1994-06-16')
DDATY 4 OVERLAY(DAT1:1)
DDATM 2 OVERLAY(DAT1:6)
DDATD 2 OVERLAY(DAT1:9)
C DT1 DSPLY
C DAT1 DSPLY
C DATY DSPLY
C DATM DSPLY
C DATD DSPLY
C SETON LR
HDATFMT(*DMY)
ddt1 s 8D inz(D'01/04/04')
c adddur 3:*days dt1
c adddur 3:*months dt1
c adddur 3:*Years dt1
c dt1 dsply
c* output is 04/07/07
c eval *inlr=*on
HDATFMT(*DMY)
12
RPG-ILE LABS
ddt1 s 8D inz(D'01/04/04')
ddt2 s 8D inz(D'01/03/03')
c dt1 adddur 3:*days dt2
c dt2 dsply
c*
c eval *inlr=*on
HDATFMT(*DMY)
ddt1 s 8D inz(D'01/04/04')
ddt2 s 8D inz(D'01/03/03')
c dt1 subdur 3:*days dt2
c dt2 dsply
c* Output : 29/03/04
c eval *inlr=*on
HDATFMT(*DMY)
ddt1 s 8D inz(D'01/01/04')
ddt2 s 8D
dn s 2s 0 inz(31)
c dt1 adddur n:*days dt2
c dt2 dsply
c* Output : 01/02/04
c dt2 adddur n:*days dt2
c dt2 dsply
c* Output : 03/03/04
c eval *inlr=*on
HDATFMT(*DMY)
dds1 ds
dd 2s 0
dsep1 1a
dm 2s 0
dsep2 1a
dy 2s 0
ddt1 s 8D inz(D'15/02/04')
c movel dt1 ds1
c d dsply
c m dsply
c y dsply
c eval *inlr=*on
LAB : SUBDUR
H TIMFMT(*HMS:)
DDS1 DS
DSTARTTM T INZ(T'07:00:00')
DENDTM T INZ(T'10:21:00')
DH1 2S 0 OVERLAY(STARTTM:1)
DH2 2S 0 OVERLAY(ENDTM:1)
DM1 2S 0 OVERLAY(STARTTM:4)
DM2 2S 0 OVERLAY(ENDTM:4)
DTOTTIME S T INZ(T'00:00:00')
C STARTTM DSPLY
C ENDTM DSPLY
C H1 DSPLY
C H2 DSPLY
13
RPG-ILE LABS
C M1 DSPLY
C M2 DSPLY
C ENDTM SUBDUR H1:*H TOTTIME
C SUBDUR M1:*MN TOTTIME
C TOTTIME DSPLY
C SETON LR
OUTPUT : 03:21:00
LAB : SUBDUR
H TIMFMT(*HMS:)
DSTARTTM S T INZ(T'07:00:00')
DENDTM S T INZ(T'10:50:00')
DH1 S 3S 0
DM1 S 3S 0
C STARTTM DSPLY
C ENDTM DSPLY
C ENDTM SUBDUR STARTTM H1:*H
C ENDTM SUBDUR STARTTM M1:*MN
C H1 DSPLY
C M1 DSPLY
C SETON LR
OUTPUT :
DSPLY 07:00:00
DSPLY 10:50:00
DSPLY 3
DSPLY 230
LAB : SUBDUR
H DATFMT(*DMY/)
DSTARTDT S D INZ(D'10/12/04')
DENDDT S D INZ(D'15/12/04')
DDAYS S 3S 0
C ENDDT SUBDUR STARTDT DAYS:*D
C DAYS DSPLY
C SETON LR
OUTPUT :
5
LAB : ADDDUR
H DATFMT(*DMY/)
DSTARTDT S D INZ(D'10/12/04')
DENDDT S D
DDAYS S 3S 0 INZ(25)
C STARTDT ADDDUR DAYS:*D ENDDT
C ENDDT DSPLY
C SETON LR
OUTPUT :
04/01/05
H DATFMT(*DMY/)
14
RPG-ILE LABS
DENDDT S D DATFMT(*DMY)
C MOVE *DATE ENDDT
C ENDDT DSPLY
C SETON LR
H DATFMT(*ISO)
DDT1 S D INZ(D'2004-12-10')
DTR S 4S 0 INZ(0)
C EXTRCT DT1:*Y TR
C TR DSPLY
C EVAL *INLR = *ON
H DATFMT(*ISO)
DDT1 S D INZ(D'2004-12-10')
DDT2 S 6S 0 INZ(041312)
DTR S 4S 0 INZ(0)
C TEST DT1 55
C* ____________________________
C* If date is not a valid date
C* with *ISO format,
C* IND 55 is TURNED ON.
C* ____________________________
C IF *IN55 = *OFF
C 'dt1 valid' DSPLY
C ENDIF
C* OUTPUT : DT1 VALID
C* Repeat this test for
C* DT2
C* ---------------------
C *YMD TEST(D) DT2 55
C* -----------------------
C* This date is not valid.
C* -----------------------
C IF *IN55 = *OFF
C 'DT2 valid' DSPLY
C ENDIF
C EVAL *INLR = *ON
Notes :
15
RPG-ILE LABS
H TIMFMT(*ISO)
DTM1 S T INZ(T'10.12.14')
DTM2 S 6S 0 INZ(101214)
C TEST TM1 55
C IF *IN55 = *OFF
C 'TM1 valid' DSPLY
C ENDIF
C* OUTPUT : TM1 VALID
C* Repeat this test for
C* TM2
C* ---------------------
C *HMS TEST(T) TM2 55
C* -----------------------
C* This TIME is not valid.
C* -----------------------
C IF *IN55 = *OFF
C 'TM2 valid' DSPLY
C ENDIF
c TM1 dsply
c TM2 dsply
C EVAL *INLR = *ON
H TIMFMT(*ISO)
DTS1 S Z INZ(Z'2004-12-10-10.12.20.000000')
C TEST TS1 55
C IF *IN55 = *OFF
C 'TS1 valid' DSPLY
C ENDIF
C* OUTPUT : TS1 VALID
c TS1 dsply
C EVAL *INLR = *ON
Program accepts date values into fields with edit code of Y. If a wrong date is unput
by the user, control directly enters PSSR.
Better approach of accepting dates is previous lab.
H DATFMT(*DMY)
H* PROGRAM TO CALCULATE PENALTY. ISSUES DATE AND RECPT DATE ARE
H* ARE ACCEPTED. IF THE RECPT DATE IS 7 DAYS OR LESS, NO PENALTY.
H* FOR EVERY ADDITIONAL DAY, PENALTY IS Rs 5/- PER DAY.
H* ----------------------------------------------------------------
H*
FDSPENAL CF E WORKSTN
F*
DNODATE S 6S 0 INZ(0)
DNOTIME S 6S 0 INZ(0)
DDELTA S 4S 0 INZ(0)
DISDAT S D INZ(D'01/01/01')
DRCDAT S D INZ(D'01/01/01')
C DOW *IN03 = *OFF
C IF *IN03 = *ON
C EVAL *INLR = *ON
16
RPG-ILE LABS
C RETURN
C ENDIF
C*
C MOVE NODATE DISDAT
C MOVE NODATE DRCDAT
C EXFMT RDATE
C SETOFF 7778
C MOVE DISDAT ISDAT
C MOVE DRCDAT RCDAT
C RCDAT SUBDUR ISDAT DELTA:*D
C EVAL DELTA = DELTA - 7
C IF DELTA<0
C EVAL DPENAL = 0
C ITER
C ENDIF
C*
C DELTA MULT 5 DPENAL
C GONXT TAG
C ENDDO
C EVAL *INLR = *ON
C RETURN
C* ---------------------------------------------------
C *PSSR BEGSR
C SETON 7778
C GOTO GONXT
C ENDSR
A DSPSIZ(24 80 *DS3)
A CA03(03)
A R RDATE
A 6 4'ISSUE DATE :'
A 8 4'RECPT DATE : '
A DISDAT 6Y 0B 6 19EDTWRD(' / / ')
A EDTMSK(' & & ')
A COLOR(WHT)
A 77 ERRMSG('INVALID DATA')
A DRCDAT 6Y 0B 8 19EDTWRD(' / / ')
A EDTMSK(' & & ')
A COLOR(WHT)
A 78 ERRMSG('INVALID DATA')
A 12 4'PENALTY AMOUNT : '
A DPENAL 4Y 0O 12 23EDTCDE(3)
A COLOR(RED)
A 12 29'Rs'
RPDATE Listing :
H DATFMT(*DMY)
17
RPG-ILE LABS
H* PROGRAM LOADS DATA INTO THE PFDATE PF. IT ACCEPTS 2 DATE VALUES
H* AND 2 TIME VALUES. THE VALIDATION OF THE VALUES IS DEFAULT BY
H* VIRTUE OF THEIR TYPE. NO VALIDATION SPECIFIED IN THE DISPLAY
H* FILE. IF WRONG DATA ENTERED, THE CONTROL GOES INTO PSSR.
H* CONTROL GOES INTO PSSR DURING A MOVE OPERATION, WHEN DDATE
H* IS BEING MOVED INTO DATE FIELD.
H* PSSR CAN DO OUTRAGEOUS THINGS LIKE ENTERING DOW LOOP USING A GOTO
H* Program also performs auto generation of CODE value so that next
H* record gets a code higher by 1 as comared to the previos rec code.
H* -----------------------------------------------------------------
FPFDATE UF A E DISK
FDSDATE CF E WORKSTN
F*
DNODATE S 6S 0 INZ(0)
DNOTIME S 6S 0 INZ(0)
DCD S 4S 0 INZ(0)
C EXSR AUTOGENCODE
C READ BTIME 44
C DOW *IN03 = *OFF
C MOVE NODATE DDATE1
C MOVE NODATE DDATE2
C MOVE NOTIME DTIME1
C MOVE NOTIME DTIME2
C EXFMT RDATE
C MOVE DDATE1 DATE1
C MOVE DDATE2 DATE2
C MOVE DTIME1 TIME1
C MOVE DTIME2 TIME2
C ADD 1 CD
C Z-ADD CD CODE
C WRITE BTIME 77
C UNLOCK PFDATE
C END1 TAG
C ENDDO
C* ---------------------------------------------------
C EVAL *INLR=*ON
C RETURN
C AUTOGENCODE BEGSR
C *HIVAL SETLL BTIME
C READP(N) BTIME 44
C Z-ADD CODE CD
C 1 SETLL BTIME
C ENDSR
C*
C *PSSR BEGSR
C 'PSSR' DSPLY
C DSP_MAJOR DSPLY
C DSP_MINOR DSPLY
C GOTO END1
C ENDSR
A DSPSIZ(24 80 *DS3)
A CA03(03)
A R RDATE
A 3 14'BOTH DATES AS FOLLOWS :'
A COLOR(WHT)
A DSPATR(UL)
18
RPG-ILE LABS
A 5 14'DATE 1 :'
A 7 14'DATE 2 :'
A 10 14'BOTH TIME VALUES AS FOLLOW
A COLOR(WHT)
A DSPATR(UL)
A 12 15'TIME 1 : '
A 14 15'TIME 2 : '
A DDATE1 6Y 0B 5 25EDTWRD(' - - ')
A EDTMSK(' & & ')
A DDATE2 6Y 0B 7 25EDTWRD(' - - ')
A EDTMSK(' & & ')
A DTIME1 6Y 0B 12 25EDTWRD(' : : ')
A EDTMSK(' & & ')
A DTIME2 6Y 0B 14 25EDTWRD(' : : ')
A EDTMSK(' & & ')
Lisiting if PFDATE :
A R BTIME
A CODE 4S 0
A DATE1 L
A DATE2 L
A TIME1 T
A TIME2 T
Only program is that of control goes into PSSR , I cannot say exactly which MOVE
operation forced it into the PSSR. This way, you canot tell which field to high
light.
H TIMFMT(*HMS)
H* -------------------------------------------------------
FDSTIME CF E WORKSTN
DTM1 S T INZ(T'00:00:00')
C* DISPLAY TIME DISPLAY FILE AND INPUT TIME FROM THE USER
C* CHECK IF THIS TIME IS VALID.
C* -------------------------------------------------------
C DOW *IN03 = *OFF
C MOVE *ZEROS DTIMEFLD
C EXFMT RTIME
C *HMS TEST(T) DTIMEFLD 77
C IF *IN77 = *ON
C EVAL *IN77 = *OFF
C 'INCORRECT' DSPLY
C ITER
C ENDIF
C *HMS MOVE DTIMEFLD TM1
C TM1 DSPLY
C ENDDO
C EVAL *INLR = *ON
A DSPSIZ(24 80 *DS3)
A CA03(03)
A R RTIME
19
RPG-ILE LABS
LAB : Read date and time data from PF which stores data as date and time.
Use INSERT SQL stmt to insert some sample values into PFDAT.
Create a display file DSDAT with fields : DDISSUE,DDRETURN,DTISSUE, DTRETURN with ‘Y’
as edit code. (created as +9(8) and then edit code Y is applied).
Write following RPDAT program to load the data into RPGLE and display it.
H Datfmt(*DMY/) TimFmt(*HMS:)
FPFdat If E Disk
FDSdat CF E Workstn Display file
c Do 1 fields
20
RPG-ILE LABS
c Read RDate
c DIssue dsply
c* DReturn dsply
c TIssue dsply
c* TReturn dsply
c Movel DIssue DDIssue
c Movel DReturn DDreturn // dont
use EVAL !
c Movel TIssue DTIssue
c Movel TReturn DTReturn
c Exfmt R1
c EndDo
c Eval *inlr = *on
OUTPUT :
DSPLY 24/12/05
DSPLY 09:45:00
Date of issue : 24/12/0500 ___ Display file output
Time of issue : 9/45/0000 ⌡
H Datfmt(*DMY/) TimFmt(*HMS:)
FPFdat If E Disk
c Do 1
c Read RDate
c DIssue dsply
c TIssue dsply
c If DIssue = d'24/12/05'
c '24 DEC 2005' Dsply
c Endif
c EndDo
c Eval *inlr = *on
c Return
21
RPG-ILE LABS
dn1 s 4s 0 inz(1)
c Dow n1 < 100
c Eval *in(n1) = *off
c Eval n1 = n1 + 1
c Enddo
c Exsr TestSR
c Eval *inlr = *on
c Return
c* ----------------------------------------
c*
c TestSR Begsr
c Eval *in(45) = *ON
c If *in45 = *on
22
RPG-ILE LABS
OUTPUT :
Dsply '45 on'
DT1 T
DT2 T
DRslt T options(*nopass)
DTempTime S T INZ(T'00:00:00')
DSec S 10s 0 inz(0)
C T2 SUBDUR T1 SEC:*S
C TempTime Adddur sec:*S TempTime
C If %Parms = 3
C MOVE TempTime Rslt
C Return
C Else
C 'No param!' Dsply
c TempTime Dsply
c Endif
PFind_Difference E
23
RPG-ILE LABS
C Return
C* -------------------------------------------------------
PFind_Difference B
DFind_Difference PI
DD1 d
DD2 d
C D2 SUBDUR D1 Yrs:*Y
C D1 addDUR Yrs:*Y D1
C D2 SUBDUR D1 Mnt:*M
C D1 addDUR Mnt:*M D1
C D2 SUBDUR D1 Dys:*D
C* ====================================================
c Ds001 dsply
C Return
PFind_Difference E
24
RPG-ILE LABS
%ABS
DA01 S 2P 0 Inz(-1)
DA02 S 10P 3 Inz(-14.567)
C*
C EVAL A01 = %ABS(A01)
C A01 DSPLY
C*
C EVAL A02 = %ABS(A02)
C A02 DSPLY
C*
C EVAL A02 = %ABS(A01 - -2)
C A02 DSPLY
C*
C EVAL *INLR = *ON
%TRIM %EDITC
DNAME S 20A
DDATE S D INZ(D'2003-05-05')
DTIME S T INZ(T'12.12.12')
DRESULT S 10A
DMSG S 50A
DSALARY S 9P 2 INZ(1000)
D*
C EVAL MSG = 'Annual Salary : '
C +%TRIM(%EDITC(Salary*12
C :'A': *CURSYM))
C*
C MSG DSPLY
C DATE DSPLY
C TIME DSPLY
C UDATE DSPLY
C*
C EVAL *INLR = *ON
%SUBSTR
DLEN S 4S 0 INZ(0)
DSTR S 12A INZ('TEST STRING')
C STR DSPLY
C EVAL LEN=%LEN(STR)
C LEN DSPLY
C EVAL STR=%SUBST(STR:2:3)
C STR DSPLY
C SETON LR
%SIZE
25
RPG-ILE LABS
DN S 4S 0 INZ(0)
C STR1 DSPLY
C EVAL N=%SIZE(STR1)
C N DSPLY
C SETON LR
Output :
TEST STRING
14
%EDITC
Scan will look for occruance of the sSrc string in the sStr string and write the
position of nSrc (if found in sStr) to nPos.
NPos is zero based so add 1 to nPos. Specify nPos in SubSt() function to get the
rest of the characters after nPos.
Arguments to %SCAN :
26
RPG-ILE LABS
c*
c Eval srcstr = 'b'
c Eval Loc = %Scan(srcstr:String1:3)
c 'b loc :' Dsply
c Loc Dsply
c*
c Eval srcstr = 'x'
c 'x loc :' Dsply
c Eval Loc = %Scan(srcstr:String1:1)
c Loc Dsply
c Eval *inlr = *on
OUTPUT :
DSPLY d loc :
DSPLY 4
DSPLY b loc :
DSPLY 0
DSPLY x loc :
DSPLY 0
27
RPG-ILE LABS
Linkage : RPCAT
CODE :
ds1 s 4a inz('abcd')
ds2 s 4a inz('qrst')
ds3 s 8a
ds4 s 8a
c s1 cat '#':0 s3
c s1 cat '#':2 s4
c s3 Dsply
c s4 Dsply
c* output :
c* abcd#
c* abcd #
c Eval *inlr = *on
PF contents :
---
OUTPUT :
REMARKS :
28
RPG-ILE LABS
OUTPUT : 1 2 3 4
29
RPG-ILE LABS
LAB : TABLE
30
RPG-ILE LABS
31
RPG-ILE LABS
PSDS
D SDS
D PGNAM 1 10
D UNAME 254 263
D DATE 270 275
D TIME 282 287
I*
C* Main Logic
C* ---- -----
C*
C *IN03 DOWEQ *OFF
C*
C MOVEL PGNAM DNAME
C MOVEL UNAME DUNAM
C MOVE DATE DDATE
C MOVE TIME DTIME
MULTI OCCURANCE DS
D JSRDS DS 30 OCCURS(20)
D SCODE 1 5
D SROLL 6 10 0
D SNAME 11 30
C 1 OCCUR JSRDS
C MOVEL 'S001' SCODE
C Z-ADD 1 SROLL
C 2 OCCUR JSRDS
C MOVEL 'S002' SCODE
C Z-ADD 2 SROLL
C MOVEL 'TRIAL' SNAME
C 1 OCCUR JSRDS
C SNAME DSPLY
C SCODE DSPLY
C SROLL DSPLY
C 2 OCCUR JSRDS
C SCODE DSPLY
C SROLL DSPLY
C '---' DSPLY
C JSRDS DSPLY
C SETON LR
D JSRDTA UDS
D BCODE 1 4
D BNAME 5 20
C BCODE DSPLY
C BNAME DSPLY
C SETON LR
32
RPG-ILE LABS
Infds :
FTEST1 IF E DISK
FTEST1D UF A E DISK INFDS(STR1)
F INFSR(*PSSR)
D STR1 DS
D STA *STATUS
C READ PFREC1D 26
C Z-ADD 0 VAR 2 0
C READ PFREC 25
C *IN25 DOWEQ *OFF
C Z-ADD NUMBER NUM
C NUM DSPLY
C*
C WRITE PFREC1D
C READ PFREC 25
C ENDDO
C SETON LR
C*
C *PSSR BEGSR
C READ PFREC 25
C ENDSR
NOW IF YOU DO A READ, THE DATA IS TAKEN FROM THE PF AND WRITTEN TO THE FIRST
OCCURANCE OF DS. AND SO ON…
dNOccur s 4s 0 inz(12)
dds001 ds occurs(10)
dN1 4s 0
dN2 4s 0
d**
d sds
dStatus *status
d*
c* specify impossible occurance
33
RPG-ILE LABS
c*
c NOccur Occur ds001 66
c If *in66 = *on
c 'unreachable' dsply
c Status Dsply
c*
c* value of Status will be 122
c*
c EndIf
C Eval *inlr =*on
C Return
IDS001 DS
I 1 40CODE
I 5 14 NAME
C *ENTRY PLIST
C PARM DS001
C NAME DSPLY
C CODE DSPLY
C MOVEL'XML' NAME
C Z-ADD22 CODE
C SETON LR
C RETRN
IDS001 DS
I 1 40CODE
I 5 14 NAME
C Z-ADD12 CODE
C MOVEL'SAM' NAME
C CALL 'RPRCV'
C PARM DS001
C 'PARENT' DSPLY
C NAME DSPLY
C CODE DSPLY
C SETON LR
C RETRN
CODE :
* _____________________________________________________
* RPOVR.
* Demo of overlay and multi occurances of variable being
* overlayed.
* a is broken into 2 sections identified by b and c
* There are 10 instances of a , so there are 10 inst of b and c
*
* ########## <-- a(1)
* -----~~~~~
* b(1) c(1)
34
RPG-ILE LABS
* _____________________________________________________
dds001 ds
da 10a Dim(10)
db 5a overlay(a)
dc 5a overlay(a:6)
dcount s 2s 0 inz(1)
dtemp s 5
dabc s 2
c*
c Dow count<4
c* conv to character
c Movel count abc
c 'ABC' cat abc temp
c* ABC01...
c Eval b(count) = temp
c 'xyz' cat abc temp
c* xyz01...
c Eval c(count) = temp
c a(count) dsply
c* ABC01xyz01 ...
c Eval count = count + 1
c End
c Eval *inlr = *on
PF contents :
nil
OUTPUT :
DSPLY ABC01xyz01
DSPLY ABC02xyz02
DSPLY ABC03xyz03
REMARKS :
CREATE EXTDS : A TYPICAL BCODE, BNAME BPRICE PHYSICAL FILE WITH RECORD SIZE 21
CREATE DDS, COMPILE AND WRITE 5-6 RECORDS TO THE SAME.
FEXTDS IF E DISK
IDS001 EIDSEXTDS 4 21
C 1 OCUR DS001
C READ BM 55
C DS001 DSPLY
C 2 OCUR DS001
C READ BM 55
35
RPG-ILE LABS
C DS001 DSPLY
C 1 OCUR DS001
C DS001 DSPLY
C SETON LR
FBM001 if e Disk
DMYDS E DS EXTNAME(BM001) Occurs(4)
c Read BM
C* --------------------------------------------
C* The READ opcode copies the data read from
C* PF into the current occurance of the DS.
C* --------------------------------------------
c 1 Occur MyDS
C BCODE Dsply
C BNAME Dsply
C BPRICE Dsply
c 2 Occur MyDS
c Read BM
C BCODE Dsply
C BNAME Dsply
C BPRICE Dsply
C Eval *INLR = *ON
* END *
36
RPG-ILE LABS
37
RPG-ILE LABS
38
RPG-ILE LABS
LAB : LDA
Lda :
FD002 CF E WORKSTN
C *IN03 DOWEQ *OFF
C *DTAARA DEFINE *LDA CYNAM 10
C IN CYNAM
C CLEAR CYNAM
C MOVE 'test st' CYNAM
C OUT CYNAM
C MOVEL CYNAM DCYNAM
C EXFMT DATA
C ENDDO
C MOVE *ON *INLR
C SETON LR
FD001 CF E WORKSTN
C *IN03 DOWEQ *OFF
C *DTAARA DEFINE EMPN 5 0
C IN EMPN
C Z-ADD EMPN DEMPNO
C EXFMT DATA
C *IN03 IFEQ *ON
C LEAVE
C ENDIF
C ENDDO
C MOVE *ON *INLR
Create a dataarea called “JSRDTA” fo the type *CHAR and length 10.
Listing :
NOTE : If you do not lock the data area during the IN operation, you cannot
UPDATE (ie Change) its contents. You can then only read the data area.
Listing of CLDTAARA2 :
39
RPG-ILE LABS
Pgm
ALCOBJ OBJ((QGPL/MYDTA *DTAARA *excl)) WAIT(0)
monmsg msgid(CPF1002) exec(goto end1)
CHGDTAARA DTAARA(QGPL/MYDTA) VALUE('sec')
SNDPGMMSG MSG('hi2!') TOPGMQ(*EXT) MSGTYPE(*INQ)
DLCOBJ OBJ((QGPL/MYDTA *DTAARA *excl))
goto end
END1: SNDPGMMSG MSG('cannot allocate')
end: Endpgm
LISTING OF CLDTAARA1 :
Pgm
ALCOBJ OBJ((QGPL/MYDTA *DTAARA *excl)) WAIT(0)
monmsg msgid(CPF1002) exec(goto end1)
/* cannot alocate since it is already locked. */
CHGDTAARA DTAARA(QGPL/MYDTA) VALUE('FIRST')
SNDPGMMSG MSG('hi !') TOPGMQ(*EXT) MSGTYPE(*INQ)
DLCOBJ OBJ((QGPL/MYDTA *DTAARA *excl))
goto end
END1: SNDPGMMSG MSG('cannot allocate')
RPPARENT
RPCHILD
fpfbmast if e disk
c Read bm 88
c 'child!' dsply
c Eval *in44 = *off
c 44 Eval *inlr = *on
40
RPG-ILE LABS
c Return
c
Child does not allow the SETON LR to take place. Result is that child returns without
Closing the PFBMAST file. This can be confirmed by Shift + Esc and 14 to see open files.
FTEST1 IF E DISK
FTEST1D UF A E DISK INFDS(STR1)
F INFSR(*PSSR)
D STR1 DS
D STA *STATUS
C READ PFREC1D 26
C Z-ADD 0 VAR 2 0
C READ PFREC 25
C *IN25 DOWEQ *OFF
C Z-ADD NUMBER NUM
C NUM DSPLY
C* ---------------------------------------------------------------------
C WRITE PFREC1D
C READ PFREC 25
C ENDDO
C SETON LR
C* ---------------------------------------------------------------------
C *PSSR BEGSR
C READ PFREC 25
C ENDSR
C* ---------------------------------------------------------------------
41
RPG-ILE LABS
Lab : I specs
In this lab we look at creating a flat physical file and access the same from a RPGLE
program. The program breaks the row from the flat physical file into sections as
required and assigns that data to variable. This happens for every read operation.
FPfFlat IF F 21 Disk
IPfFlat XX
I 1 4 0cd
I 5 14 nm
I 15 21 2pr
I* First I line is by PI. Second by PJ.
C read pfFlat
C cd dsply
C nm dsply
C pr dsply
The shaded I spec portion indicates the sections of the input record and variables to
which those sections will be assigned.
For each read operation, 1 row is read from the physical file. It is read as 1 single
row of 21 positions. However, in the program, the row is split up and different
sections of the same are assigned to different variables suc as cd,nm and pr as in
above case. CD gets data abetween positions 1 and 4. Same for nm and pr.
Thus although data, while reading is un-structured, it is bifercated into different
sections and used as required in the program.
Data read from physical file :
0001ACAD 0000120
To the read opcode, we pass the PFFLAT as the record format since flat physical file
has same name for file and record format.
42
RPG-ILE LABS
LAB : O Specs
FPfFlat o F 21 Disk
dcd s 4s 0 inz(108)
dnm s 10a inz('Physics')
dpr s 7s 2 inz(100.25)
c Except e1
C Eval *inlr = *on
oPFFLAT e e1
o cd 4
o nm 14
o pr 21
OUTPUT :
LAB : O Specs
FPfFlat o F 21 Disk
dcd s 4s 0 inz(108)
dnm s 10a inz('Physics')
dpr s 7s 2 inz(100.25)
c Except e1
c Except e2
C Eval *inlr = *on
oPFFLAT e e1
o cd 4
o nm 14
o pr 21
o e e2
o 14 '** ERROR ** '
In above case, the string ‘ ** ERROR * *’ is inserted into the physical file. It is
placed from the beginning of the record, so some part of the same appears in the
BCode column while some in BName column. (!!)
43
RPG-ILE LABS
44
RPG-ILE LABS
LAB : Declaration of sub files. (rest pf the code is same,no need to cover all
that )
FDSP1 CF E WORKSTN
F SFILE(SFLDATA:RRN)
LAB : Database basics : How access is done when you try to get a non-keyed access to
a LF which has a K on a certain field.
Database files : PFBMK : typical book master file. LFBMK : Typical book master based
on pfbmk and keys on BPRICE.
Linkage : RPREAD
CODE :
FLfbmk IF E Disk
c 5 setll bm
c Read bm
c bcode dsply
c bprice dsply
c
c Eval *inlr=*on
c Return
PF contents : LFBMK
45
RPG-ILE LABS
OUTPUT :
5
220.00
REMARKS :
Linkage : RPREAD1
CODE :
FLfbmk IF E k Disk
dsrc s 7p 2 inz(320)
c src setll bm
c Read bm
c bcode dsply
c bprice dsply
c Eval src = 90
c*
c* SETLL starts searching from the top of the Database file.
c* Record with BPRICE=90 comes way before rec with BPRICE=320
c src setll bm
c Read bm
c bcode dsply
c bprice dsply
c Eval *inlr=*on
c Return
PF contents :
OUTPUT :
DSPLY 3
DSPLY 32000
DSPLY 9
DSPLY 9000
REMARKS :
Linkage : RPREAD2
CODE :
FLfbmk IF E k Disk
46
RPG-ILE LABS
dsrc s 7p 2 inz(20)
D*
c* Too less. No rec has bprice = 20. The least value=75.
c*
c src setll bm 444546
c *in44 dsply
c *in45 dsply
c *in46 dsply
c Setoff 444546
c Read bm
c bcode dsply
c bprice dsply
c Eval src = 3000
c*
c* Too large value. No record has bprice = 3000.Largest val is 2,400
c*
c src setll bm 444546
c *in44 dsply
c *in45 dsply
c *in46 dsply
c Setoff 444546
c Read bm
c bcode dsply
c bprice dsply
c Eval *inlr=*on
c Return
PF contents :
Same as prev.
OUTPUT :
DSPLY 0
DSPLY 0
DSPLY 0
DSPLY 10 at the first record.
DSPLY 7500
DSPLY 1 too high a value.
DSPLY 0
DSPLY 0
DSPLY 10 still at the first record.
DSPLY 7500
REMARKS :
47
RPG-ILE LABS
Linkage : RPREAD2
CODE :
FLfbmk IF E k Disk
dsrc s 7p 2 inz(420)
D*
c src setll bm 444546
c *in44 dsply
c *in45 dsply
c *in46 dsply
c Setoff 444546
c Eval src=20
c* Too less. No rec has bprice = 20. The least value=75.
c*
c src setll bm 444546
c *in44 dsply
c *in45 dsply
c *in46 dsply
c Setoff 444546
c Read bm
c bcode dsply
c bprice dsply
c Eval src = 3000
c*
c* Too large value. No record has bprice = 3000
c*
c src setll bm 444546
c *in44 dsply
c *in45 dsply
c *in46 dsply
c Setoff 444546
c Read bm
c bcode dsply
c bprice dsply
c Eval *inlr=*on
c Return
PF contents :
OUTPUT :
DSPLY 0
DSPLY 0
DSPLY 1
DSPLY 0
DSPLY 0
DSPLY 0
DSPLY 10
DSPLY 7500
DSPLY 1
DSPLY 0
DSPLY 0
DSPLY 10
DSPLY 7500
48
RPG-ILE LABS
REMARKS :
To start with, 420 is passed as search argument to setll. SETLL finds an exact match
so the file pointer is positioned to that record and EQ indicator is set on (*in46
= *ON) . So we get 0 0 1 as the output. Next we put 20 as factor-one to setll. There
is no record with this value of bprice. The rec with the least bprice value is 75
which is the first record. Hence file pointer is positioned to the first record and
this is read. No indicator is changed.SETLL does not complain.
So output : 0 0 0 10 75
Next we put 3000 as factor 1 argument to SETLL which is too high. The rec with
largest BPRICE value is 2,400. Hence file pointer is not moved at all and HI
indicator is set on.
Hence Output : 1 0 0 10 75
49
RPG-ILE LABS
Linkage : RPREAD3
CODE :
FLfbmk IF E k Disk
dsrc s 7p 2 inz(120)
D*
c src chain bm
c Dow Not %EOF
c BCode dsply
c BPrice dsply
c src ReadE bm
c EndDo
c Eval *inlr=*on
c Return
PF contents :
OUTPUT :
DSPLY 1
DSPLY 12000
DSPLY 4
DSPLY 12000
DSPLY 8
DSPLY 12000
DSPLY 11
DSPLY 12000
REMARKS :
First CHAIN locates the first record from top. Remaining records with same bprice can
be located using READE.
50
RPG-ILE LABS
CODE :
DSLFBMK :
A DSPSIZ(24 80 *DS3)
A PAGEUP(25)
A PAGEDOWN(26)
A R SFLDT SFL
A DCODE 4 0B 5 10COLOR(WHT)
A DNAME 20 B 5 21COLOR(WHT)
A DPRICE 7 2B 5 49EDTWRD(' . ')
A COLOR(WHT)
A 5 61'Rs'
A R SFLCTL SFLCTL(SFLDT)
A CA03(03)
A 50 SFLDSP
A 51 SFLDSPCTL
A 52 SFLCLR
A SFLSIZ(0005)
A SFLPAG(0004)
A 1 23'Book Master Record'
A COLOR(WHT)
A 3 10'Code'
A COLOR(WHT)
A 3 28'Name'
A COLOR(WHT)
A 3 53'Price'
A COLOR(WHT)
RPSFLK :
F*
FLfbmk IF E k Disk
Fdslfbmk CF E Workstn sfile(sfldt:rrn)
drrn s 4s 0 inz(0)
D*
C*
c Exsr CLRSR
c ExSR LDSR
c Dow *in03 = *off
c ExSR DspSR
c ExSR UsrSR
c EndDO
c Eval *inlr = *on
c Return
c*
c UsrSR BegSR
c* Pg up
c If *in25 = *on
c Eval *in25 = *Off
c*
c* go back 8 records.
c*
c do 8
51
RPG-ILE LABS
c ReadP bm
c if %EOF(lfbmk)
c Leave
c EndIf
c EndDo
c EndIf
c* end of PG UP
c* Pg Dn
c If *in26 = *on
c Eval *in26 = *Off
c EndIf
c*
c* In either case,Load is necessary.
c*
c Exsr LDSR
c EndSr
c*
c ClrSR BegSR
c Eval rrn = 0
c Eval *in52 = *on
c Write SflCtl
c Eval *in52 = *off
c EndSR
c*
c LdSR BegSR
c Exsr ClrSR
c*
c* load next 4 records to subfile
c*
c Read bm
c Do 4
c*
c if %EOF
c Leave
c EndIf
c*
c Eval DCode = BCode
c Eval DName = BName
c Eval DPrice = BPrice
c Eval rrn = rrn + 1
c Write SFLDT
c Read bm
c EndDO
c EndSR
c*
c DspSR BegSR
c Eval *in50 = *on
c Eval *in51 = *on
c Exfmt SflCTL
c Eval *in51 = *off
c Eval *in50 = *off
c EndSR
PF contents :
OUTPUT :
52
RPG-ILE LABS
The records are displayed in single page subfile in ascending order of Bprice.
REMARKS :
53
RPG-ILE LABS
FPFBM IP F 21 DISK
FQPRINT O F 80 PRINTER OFLIND(*IN20)
IPFBM AA
I 1 4 0CODE
I 5 14 NAME
I 15 21 2PRICE
C 20 SETOFF 20
OQPRINT H 1P 1 1
O 40 '<TITLE COMES HERE>'
O D 1 1
O CODE Z 10
O NAME 30
O PRICE Q 60
O T 20 1 1
O 78 '------------------'
FPFLGC IP F 63 DISK
F*
FQPRINT O F 132 PRINTER OFLIND(*INOF)
LAB : SPECIFY OVERFLOW LINE NUMBER AND NUMBER OF LINES ON THE FORM
ILE CODE :
RUN THIS PROGRAM AND SEE THE NUMBER OF PAGES OF OUTPUT CREATED.
FPFBM IP F 21 DISK
FQPRINT O F 80 PRINTER OFLIND(*IN20) FORMLEN(10) FORMOFL(09)
IPFBM AA
I 1 4 0CODE
I 5 14 NAME
I 15 21 2PRICE
C 20 SETOFF 20
OQPRINT H 1P 1 1
O 40 '<TITLE COMES HERE>'
O D 1 1
54
RPG-ILE LABS
O CODE Z 10
O NAME 30
O PRICE Q 60
O T 20 1 1
O 78 '------------------'
RPG/400 CODE :
L – SPECS ARE USED AS UNDER :
FPFBM IP F 21 DISK
FQPRINT O F 80 20 LPRINTER
LQPRINT 20FL 18OL
IPFBM AA
I 1 40CODE
I 5 14 NAME
I 15 212PRICE
C 20 SETOF 20
OQPRINT H 11 1P
O 40 '<TITLE COMES HERE>'
O D 11
O CODE Z 10
O NAME 30
O PRICE Q 60
O T 11 20
O 78 '------------------'
55
RPG-ILE LABS
O T L1
O 37 'TOTAL TIME'
O T LR
O 37 'LR IS ON '
O OF '* OVER FLOW *'
CODE : RPLC2
* ____________________________________________________________
* Simple program demonstrating a logic cycle.
* ____________________________________________________________
* Database file contains BCODE BIN and BOUT fields
* which store the qty of books comming in and going out
* along with their codes.
* Objective is to display the total bin and bout for each book.
* ____________________________________________________________
*
FQPRINT O F 80 PRINTER
FPFBIO1 IP F 12 DISK
DTOTBIN S 5I 0 INZ(0)
DTOTBOUT S 5I 0 INZ(0)
iPFBIO1 AA 88
i 1 4 0bcode L1
i 5 8 0bin
i 9 12 0bout
C*
C IF *INL1 AND *IN88
C EVAL TOTBIN = 0
C EVAL TOTBOUT = 0
C ENDIF
C*
C IF *IN88
C EVAL TOTBIN = TOTBIN + BIN
C EVAL TOTBOUT = TOTBOUT + BOUT
C ENDIF
C*
C*____________________________________________
OQPRINT D N1P
O 10 'CODE :'
O BCODE Z 20
O 30 'IN :-'
O BIN Q 40
O 50 'OUT :-'
O BOUT Q 60
O T L1 88 1 1
O '_______________________
O T L1 88 1 1
O 10 'TOTAL IN :'
O TOTBIN 17
O 40 'TOTAL OUT : '
O TOTBOUT 50
O*
O T L1 88 1 1
O '_______________________
56
RPG-ILE LABS
PF contents : PFBIO1
CODE : 1 IN :- 10 OUT :-
CODE : 1 IN :- OUT :- 10
CODE : 1 IN :- 10 OUT :-
_________________________
TOTAL IN : 00020 TOTAL OUT : 00010
_________________________
CODE : 2 IN :- 10 OUT :-
CODE : 2 IN :- OUT :- 10
CODE : 2 IN :- 10 OUT :-
_________________________
TOTAL IN : 00020 TOTAL OUT : 00010
_________________________
CODE : 3 IN :- 10 OUT :-
CODE : 3 IN :- OUT :- 10
CODE : 3 IN :- 10 OUT :-
CODE :RPLC3
* ____________________________________________________________
* DEMONSTRATING L1 AND L2 INDICATORS.
* ____________________________________________________________
* Database file contains SBCODE,BCODE BIN and BOUT fields
* which store the qty of books comming in and going out
* along with their codes AND THE subject code.
* Objective is to display the total bin and bout for each book.
* grouped by BCode and then Grouped by SBCODE (subject code)
* SBCODE : 1 for mechanical Engg.
* BCODE : 1 for the first book in the mech engg book.
* ____________________________________________________________
*
FQPRINT O F 80 PRINTER
FPFBIO3 IP F 16 DISK
DTOTBINSB S 5I 0 INZ(0)
DTOTBOUTSB S 5I 0 INZ(0)
DTOTBIN S 5I 0 INZ(0)
DTOTBOUT S 5I 0 INZ(0)
DTEMP S 4S 0 INZ(0)
iPFBIO3 AA 88
i 1 4 0sbcode L2
i 5 8 0bcode L1
57
RPG-ILE LABS
i 9 12 0bin
i 13 16 0bout
C*
C*
C IF (*INL1 AND *IN88) and (*INL2)
C EVAL TOTBIN = 0
C EVAL TOTBOUT = 0
C EVAL TOTBINSB = 0
C EVAL TOTBOUTSB = 0
C ENDIF
C*
C IF (*INL1 AND *IN88)
C EVAL TOTBIN = 0
C EVAL TOTBOUT = 0
C ENDIF
c*
C IF *IN88
C EVAL TOTBIN = TOTBIN + BIN
C EVAL TOTBOUT = TOTBOUT + BOUT
C EVAL TOTBINSB = TOTBINSB + BIN
C EVAL TOTBOUTSB = TOTBOUTSB + BOUT
C ENDIF
C*
C*____________________________________________
OQPRINT D N1P
O 10 'CODE :'
O BCODE Z 15
O 25 'IN :-'
O BIN Q 30
O 35 'OUT :-'
O BOUT Q 40
O 45 'SBCODE :'
O SBCODE Q 50
O T L1 88 1 1
O '______________________
O T L1 88 1 1
O 10 'TOTAL IN :'
O TOTBIN 17
O 40 'TOTAL OUT : '
O TOTBOUT 50
O*
O T L1 88 1 1
O '___________________
O*
O*
O T L1 88 L2 1 1
O '+ + + + + + + + + +
O T L1 88 L2 1 1
O 17 'GR.TOTL IN:'
O TOTBINSB 17
O 40 'GR. TOTL OUT:'
O TOTBOUTSB 50
O*
O T L1 88 L2 1 1
O '~~~~~~~~~~~~~~~~~~~
O*
PF contents :PFBIO3
58
RPG-ILE LABS
L1 L2
SBCODE BCODE BIN BOUT
1 1 10 0
1 1 0 10
1 1 10 0
1 2 10 0
1 2 0 10
1 2 10 0
1 3 10 0
1 3 0 10
1 3 10 0
2 1 20 0
2 1 0 20
2 1 20 0
2 2 20 0
2 2 0 20
2 2 20 0
2 3 20 0
2 3 0 20
2 3 40 0
OUTPUT :
*...+....1....+....2....+....3....+....4....+....5...
CODE : 1 IN :- 1OUT :- SBCODE : 1
CODE : 1 IN :- OUT :- SBCODE : 1
CODE : 1 IN :- 1OUT :- SBCODE : 1
_________________________
TOTAL IN : 00020 TOTAL OUT : 00010
_________________________
CODE : 2 IN :- 1OUT :- SBCODE : 1
CODE : 2 IN :- OUT :- SBCODE : 1
CODE : 2 IN :- 1OUT :- SBCODE : 1
_________________________
TOTAL IN : 00020 TOTAL OUT : 00010
_________________________
CODE : 3 IN :- 1OUT :- SBCODE : 1
CODE : 3 IN :- OUT :- SBCODE : 1
CODE : 3 IN :- 1OUT :- SBCODE : 1
_________________________
_________________________
TOTAL IN : 00020 TOTAL OUT : 00010
_________________________
+ + + + + + + + + + + +__
GR.TOT00060 GR. TOTL OUT: 00030
~~~~~~~~~~~~~~~~~~~~~~~~~
CODE : 1 IN :- 2OUT :- SBCODE : 2
CODE : 1 IN :- OUT :- SBCODE : 2
CODE : 1 IN :- 2OUT :- SBCODE : 2
_________________________
TOTAL IN : 00040 TOTAL OUT : 00020
_________________________
CODE : 2 IN :- 2OUT :- SBCODE : 2
CODE : 2 IN :- OUT :- SBCODE : 2
CODE : 2 IN :- 2OUT :- SBCODE : 2
_________________________
TOTAL IN : 00040 TOTAL OUT : 00020
_________________________
59
RPG-ILE LABS
60
RPG-ILE LABS
CODE :
* ____________________________________________________________
* Demonstrating the M1 AND L1 indicator.
* ____________________________________________________________
* Database file PFBIO1 contains BCODE BIN and BOUT fields
* Database file PFBIO2 contains XBCODE XBIN and XBOUT fields
* which store the qty of books comming in and going out
* along with their codes.
* Objective is to SEE WHAT M1 DOES.
* ____________________________________________________________
*
FQPRINT O F 80 PRINTER
FPFBIO1 IP F 12 DISK
FPFBIO2 IS F 12 DISK
DTOTBIN S 5I 0 INZ(0)
DTOTBOUT S 5I 0 INZ(0)
DXTOTBIN S 5I 0 INZ(0)
DXTOTBOUT S 5I 0 INZ(0)
DTEMP S 4S 0 INZ(0)
iPFBIO1 AA 88
i 1 4 0bcode L1M1
i 5 8 0bin
i 9 12 0bout
I*
iPFBIO2 AA 89
i 1 4 0Xbcode L1M1
i 5 8 0Xbin
i 9 12 0Xbout
C*_________________________________________
C IF *INL1
C EVAL TOTBIN=0
C EVAL XTOTBIN=0
C EVAL TOTBOUT=0
C EVAL XTOTBOUT=0
C ENDIF
C*
C 88 EVAL TOTBIN = TOTBIN + BIN
C 88 EVAL TOTBOUT = TOTBOUT + BOUT
C*
C 89 EVAL TOTBIN = TOTBIN + XBIN
C 89 EVAL TOTBOUT = TOTBOUT + XBOUT
C*_____________________________________________________
OQPRINT D N1P 88
O 10 'CODE :'
O BCODE Z 20
O 30 'IN :-'
O BIN Q 40
O 50 'OUT :-'
O BOUT Q 60
O*** D N1P
O*** 10 '**MR**'
O D N1P 89
O 10 'XCODE :'
O XBCODE Z 20
O 30 'XIN :-'
O XBIN Q 40
O 50 'XOUT :-'
61
RPG-ILE LABS
O XBOUT Q 60
O T L1 1 1
O 20 'TOTBIN :'
O TOTBIN 30
O 50 'TOTBOUT :'
O TOTBOUT 60
PF contents :
PFBIO1 PFBIO2
BCODE BIN BOUT XBCODE XBIN XBOUT
1 10 0 2 50 0
1 0 10 2 50 0
1 10 0 2 50 0
2 10 0 2 50 0
2 0 10 3 50 0
2 10 0 3 50 0
3 10 0 4 50 0
3 0 10 4 50 0
3 10 0
5 200 0
5 0 100
OUTPUT :
CODE : 1 IN :- 10 OUT :-
CODE : 1 IN :- OUT :- 10
CODE : 1 IN :- 10 OUT :-
TOTBIN : 00020 TOTBOUT : 00010
CODE : 2 IN :- 10 OUT :-
CODE : 2 IN :- OUT :- 10
CODE : 2 IN :- 10 OUT :-
XCODE : 2 XIN :- 50 XOUT :-
XCODE : 2 XIN :- 50 XOUT :-
XCODE : 2 XIN :- 50 XOUT :-
XCODE : 2 XIN :- 50 XOUT :-
TOTBIN : 00220 TOTBOUT : 00010
CODE : 3 IN :- 10 OUT :-
CODE : 3 IN :- OUT :- 10
CODE : 3 IN :- 10 OUT :-
XCODE : 3 XIN :- 50 XOUT :-
XCODE : 3 XIN :- 50 XOUT :-
TOTBIN : 00120 TOTBOUT : 00010
XCODE : 4 XIN :- 50 XOUT :-
XCODE : 4 XIN :- 50 XOUT :-
TOTBIN : 00100 TOTBOUT : 00000
CODE : 5 IN :- 200 OUT :-
CODE : 5 IN :- OUT :- 100
TOTBIN : 00200 TOTBOUT : 00100
REMARKS :
The physical files must have data in ascending or descending order. Any deviation
from this causes a run time error. System starts with the physical file and reads
first rec from physical file. It also scans the first record in the secondary file .
If the Bcode values match the MR is set ON. (we applied a M1 on BCode remember ?).
The system starts processing records in primary file till Bcode does not change. Once
the Bcode is found to be different in the subsequent record, system starts reading
62
RPG-ILE LABS
records with the same bcode from the secondary file (if there were no matching
records in the secondary file having this bcode, system will switch ON the L1
indicator and MR will never be ON in the first place)
Now instead of returning back to primary file for the next set, the system
reads records with bcode= 4 in the seondary file and then comes back to
primary file to read records with bcode=5.
PFBIO1 PFBIO2
BCODE BIN BOUT XBCODE XBIN XBOUT
1 10 0 2 50 0
1 0 10 2 50 0
1 10 0 2 50 0
2 10 0 2 50 0
2 0 10 3 50 0
2 10 0 3 50 0
3 10 0 4 50 0
3 0 10 4 50 0
3 10 0
5 200 0
5 0 100
Linkage : RPGLC6
CODE :
* ____________________________________________________________
* Demonstrating the M1 AND L1 indicator.
* ____________________________________________________________
* Database file PFBIO1 contains BCODE BIN and BOUT fields
* Database file PFBIO2 contains XBCODE XBIN and XBOUT fields
* which store the qty of books comming in and going out
* along with their codes.
* Objective is to SEE WHAT M1 DOES.
* ____________________________________________________________
63
RPG-ILE LABS
*
FQPRINT O F 80 PRINTER
FPFBIO3 IP F 16 DISK
FPFBIO4 IS F 16 DISK
DTOTBIN S 5I 0 INZ(0)
DTOTBOUT S 5I 0 INZ(0)
DXTOTBIN S 5I 0 INZ(0)
DXTOTBOUT S 5I 0 INZ(0)
DTEMP S 4S 0 INZ(0)
iPFBIO3 AA 88
i 1 4 0sbcode L1M1
i 5 8 0bcode
i 9 12 0bin
i 13 16 0bout
I*
iPFBIO4 AA 89
i 1 4 0Xsbcode L1M1
i 5 8 0Xbcode
i 9 12 0Xbin
i 13 16 0xbout
C*_________________________________________
C IF *INL1
C EVAL TOTBIN=0
C EVAL XTOTBIN=0
C EVAL TOTBOUT=0
C EVAL XTOTBOUT=0
C ENDIF
C*
C 88 EVAL TOTBIN = TOTBIN + BIN
C 88 EVAL TOTBOUT = TOTBOUT + BOUT
C*
C 89 EVAL TOTBIN = TOTBIN + XBIN
C 89 EVAL TOTBOUT = TOTBOUT + XBOUT
C*_____________________________________________________
OQPRINT D N1P 88
O 10 'CODE :'
O BCODE Z 20
O 30 'IN :-'
O BIN Q 40
O 50 'OUT :-'
O BOUT Q 60
O*** D N1P
O*** 10 '**MR**'
O D N1P 89
O 10 'XCODE :'
O XBCODE Z 20
O 30 'XIN :-'
O XBIN Q 40
O 50 'XOUT :-'
O XBOUT Q 60
O T L1 1 1
O 20 'TOTBIN :'
O TOTBIN 30
O 50 'TOTBOUT :'
O TOTBOUT 60
64
RPG-ILE LABS
PF contents :
PFBIO3 PFBIO4
SBCODE BCODE BIN BOUT XSBCODE XBCODE XBIN XBOUT
1 1 10 0 1 1 100 0
1 1 0 10 1 1 0 100
1 1 10 0 1 1 100 0
1 2 10 0 1 2 100 0
1 2 0 10 1 2 0 100
1 2 10 0 1 2 100 0
1 3 10 0 1 3 100 0
1 3 0 10 1 3 0 100
1 3 10 0 1 3 100 0
2 1 20 0 2 1 200 0
2 1 0 20 2 1 0 200
2 1 20 0 2 1 200 0
2 2 20 0 2 2 200 0
2 2 0 20 2 2 0 200
2 2 20 0 2 2 200 0
2 3 20 0 2 3 200 0
2 3 0 20 2 3 0 200
2 3 20 0 2 3 200 0
OUTPUT :
CODE : 1 IN :- 10 OUT :-
CODE : 1 IN :- OUT :- 10
CODE : 1 IN :- 10 OUT :-
CODE : 2 IN :- 10 OUT :-
CODE : 2 IN :- OUT :- 10
CODE : 2 IN :- 10 OUT :-
CODE : 3 IN :- 10 OUT :-
CODE : 3 IN :- OUT :- 10
CODE : 3 IN :- 10 OUT :-
XCODE : 1 XIN :- 100 XOUT :-
XCODE : 1 XIN :- XOUT :- 100
XCODE : 1 XIN :- 100 XOUT :-
XCODE : 2 XIN :- 100 XOUT :-
XCODE : 2 XIN :- XOUT :- 100
XCODE : 2 XIN :- 100 XOUT :-
XCODE : 3 XIN :- 100 XOUT :-
XCODE : 3 XIN :- XOUT :- 100
XCODE : 3 XIN :- 100 XOUT :-
TOTBIN : 00660 TOTBOUT : 00330
CODE : 1 IN :- 20 OUT :-
CODE : 1 IN :- OUT :- 20
CODE : 1 IN :- 20 OUT :-
CODE : 2 IN :- 20 OUT :-
CODE : 2 IN :- OUT :- 20
CODE : 2 IN :- 20 OUT :-
CODE : 3 IN :- 20 OUT :-
CODE : 3 IN :- OUT :- 20
CODE : 3 IN :- 20 OUT :-
XCODE : 1 XIN :- 200 XOUT :-
XCODE : 1 XIN :- XOUT :- 200
65
RPG-ILE LABS
REMARKS :
First all records in the primary file with SBCODE = 1 are processed, then the system
proceeds to process all records in the secondary file with XSBCODE = 1 anf when all
records with sbcode/xsbcode=1 are exhausted, then the subtotal is pronted and
displayed.
66
RPG-ILE LABS
FDSP1 CF E WORKSTN
F SFILE(SFLDATA:RRN)
Linkage : rpsub
CODE :
fpfbm if e disk
fdssub cf e workstn sfile(sfldt:rrn)
drrn s 4s 0 inz(0)
c exsr clrsr
c exsr ldsr
c dow *in03 = *off
c exsr DSPSR
c EndDo
c*
c Eval *inlr = *on
c Return
c*
c*
c clrsr Begsr
c Eval *in52 = *on
c Write SFLCTL
c Eval *in52 = *off
c Endsr
c*
c ldsr Begsr
c read bm 55
c Dow *in55=*off
c z-add bcode dcode
c movel bname dname
c z-add bprice dprice
c Eval rrn = rrn + 1
c Write sfldt
c read bm 55
c Enddo
c Endsr
c*
c dspsr Begsr
c Seton 5051
c Exfmt sflctl
c Setoff 5051
c Endsr
67
RPG-ILE LABS
A 4 46'Rs'
A R SFLCTL SFLCTL(SFLDT)
A CA03(03)
A 50 SFLDSP
A 51 SFLDSPCTL
A 52 SFLCLR
A SFLSIZ(0005)
A SFLPAG(0004)
A 1 21'Book Master Information Sc
A COLOR(WHT)
PF contents :
OUTPUT :
REMARKS :
Linkage : RPSINGLE
CODE : RPSINGLE
68
RPG-ILE LABS
c recptr Setll bm 77
c* If *in77 = *on
c* Eval recptr = recptr -4
c* Eval *in77 = *off
c* recptr Setll bm 77
c* EndIf
c*
c Read bm
c do 4
c Eval dcode = bcode
c Eval dname = bname
c Eval dprice = bprice
c Eval rrn = rrn + 1
c Write SFLDT
c Read bm
c*
c If %eof
c Leave
c Endif
c*
c ENDDO
c*
c ENDSR
c* |~~~~~~~~|
c DSPSR BEGSR
c Eval *in50 = *on
c Eval *in51 = *on
c Exfmt sflctl
c EXSR USRSR
c Eval *in50 = *off
c Eval *in51 = *off
c ENDSR
c*
c USRSR BEGSR
c*
c* in25 = Page Up
c*
c if *in25 = *on
c 'pag up !' dsply
c Eval *in25= *off
c Eval recptr = recptr - 4
c**
c If recptr < 1
c Eval recptr = 1
c EndIf
c**
c EXSR LDSR
c*
c EndIf
c*
c* in26 = Page Down -> Get the next 4 records.
c*
c if *in26 = *on
c 'pag dn !' dsply
c Eval *in26= *off
c Eval recptr = recptr + 4
c**
c EXSR LDSR
c*
c Endif
69
RPG-ILE LABS
c*
c ENDSR
PF contents :
OUTPUT :
REMARKS :
Linkage : RPEXP
CODE :
70
RPG-ILE LABS
C EXSR UsrSR
C EndDo
C Eval *INLR = *ON
C Return
C*
C* ________________________________________________
C*
c CLRSR BegSr
c Eval *in52=*on
c Write SFLCTL
c Eval *in52=*off
c EndSR
c*
c*
c LDSR BegSR
c RecPtr Setll BM
c Do 4
c Read BM
c*
c If %eof
c Leave
c EndIf
c*
c Z-add BCode DCode
c Movel BName DName
c Z-add BPrice DPrice
c Eval rrn = rrn + 1
c Write SFLDT
c EndDo
c EndSR
c*
c DspSR BegSR
c Eval drecptr = recptr
c Eval *in50=*on
c Eval *in51=*on
c Exfmt SflCTL
c Eval *in50=*off
c Eval *in51=*off
c EndSr
c*
c*
c*
c UsrSR BegSR
c* check for
c* PageDn (next
c* set)
c If *in26=*on
c Eval *in26=*off
c 'pg dn' Dsply
c Eval RecPtr = RecPtr + 4
c EXSR LDSR
c EndIf
c*
c EndSR
A DSPSIZ(24 80 *DS3)
A CA03(03 'exit')
A R SFLDT SFL
71
RPG-ILE LABS
A DCODE 4 0B 8 6COLOR(WHT)
A DNAME 20 B 8 18COLOR(WHT)
A DPRICE 7 2B 8 42EDTWRD(' . ')
A COLOR(WHT)
A 8 52'Rs'
A COLOR(WHT)
A R SFLCTL SFLCTL(SFLDT)
A PAGEDOWN(26 'dn')
A 50 SFLDSP
A 51 SFLDSPCTL
A 52 SFLCLR
A SFLSIZ(0005)
A SFLPAG(0004)
A DRECPTR 4S 0H SFLRCDNBR
A 2 23'expanding subfile demo.'
A 4 24'Book Master Information '
A COLOR(WHT)
A 6 7'Code Name
A rice'
A COLOR(WHT)
PF contents :
OUTPUT :
REMARKS :
Linkage : rpdatae
CODE :
RPDATAE
72
RPG-ILE LABS
C Eval *in52=*on
C Write Sflctl
C Eval *in52=*off
C EndSR
c*
c*____________________________________________
c DSPSR Begsr
c Eval *in50=*on
c Eval *in51=*on
c Exfmt SFLCTL
c Eval *in50=*off
c Eval *in51=*off
c EndSR
c*
c* ___________________________________________
c ChgSR BegSR
c ReadC SFLDT 55
c Dow *in55=*off
c DCode Dsply
c DName Dsply
c ReadC SFLDT 55
c EndDo
c EndSR
A DSPSIZ(24 80 *DS3)
A R SFLDT SFL
A DCODE 4 0B 10 3COLOR(RED)
A DNAME 20 B 10 13COLOR(WHT)
A DPRICE 7 2B 10 43EDTWRD(' . ')
A COLOR(WHT)
A 10 54'Rs'
A R SFLCTL SFLCTL(SFLDT)
A CA03(03)
A 50 SFLDSP
A 51 SFLDSPCTL
A 52 SFLINZ
A SFLSIZ(0010)
A SFLPAG(0007)
A 3 25'Data Entry Subfile'
A 6 2'Enter the book details in
A owing table :'
A COLOR(BLU)
A 8 3'CODE NAME
A PRICE'
A COLOR(BLU)
PF contents :
No pf
OUTPUT :
REMARKS :
73
RPG-ILE LABS
Display DSUSR :
A DSPSIZ(24 80 *DS3)
A CF05(05)
A R SFLDT SFL
A DCODE 4 0B 6 4COLOR(WHT)
A DNAME 20 B 6 14
A 55 DSPATR(RI)
A DPRICE 7 2B 6 38EDTWRD(' . ')
A COLOR(WHT)
A 6 48'Rs'
A R SFLCTL SFLCTL(SFLDT)
A CA03(03)
A 50 SFLDSP
A 51 SFLDSPCTL
A 52 SFLCLR
A SFLSIZ(0010)
A SFLPAG(0008)
A OVERLAY
A 2 4'Book Master datab
A COLOR(WHT)
A 3 4'_________________
A COLOR(WHT)
A R FOOT
A OVERLAY
A 22 2'F5:'
A 22 6'Remove'
A 22 13'Hilight'
RPUSR :
74
RPG-ILE LABS
Remarks : A subfile is displayed. Make changes to 2 rows and press ENTER. A READC
traps the changes and switches ON the DSPATR(RI) indicator for those records. The
records are thus hi-lighted. Press F5 to remove the hi-light. To remove, the system
goes from first recrord of the subfile to the last and does UPDATE for each record
with the DSPATR(RI) indicator being set OFF.
This removes the Hi-light.
Display file :
75
RPG-ILE LABS
A DSPSIZ(24 80 *DS3)
A CF05(05)
A R SFLDT SFL
A 77 SFLNXTCHG
A DCODE 4 0B 6 4COLOR(WHT)
A DNAME 20 B 6 14
A 55 DSPATR(RI)
A DPRICE 7 2B 6 38EDTWRD(' . ')
A COLOR(WHT)
A 6 48'Rs'
A R SFLCTL SFLCTL(SFLDT)
A CA03(03)
A 50 SFLDSP
A 51 SFLDSPCTL
A 52 SFLCLR
A SFLSIZ(0010)
A SFLPAG(0008)
A OVERLAY
A 2 4'Book Master datab
A COLOR(WHT)
A 3 4'_________________
A COLOR(WHT)
A R FOOT
A OVERLAY
A 22 2'F5:'
A 22 6'Remove'
A 22 13'Hilight'
RPG :
Fdsusr1 cf e workstn sfile(sfldt:rrn)
drrn s 4s 0 inz(1)
dtotrec s 4s 0 inz(1)
dtemp s 4s 0 inz(1)
c ExSR SRClr
c Exsr SRLoad
c Dow *in03 = *Off
c Exsr SRUsr
c Exsr SRDsp
c Eval *in55= *off
c EndDo
c Eval *inlr = *on
c Return
c*____________________________________________________
c SRClr BegSR
c Eval *in52 = *on
c Write SFLCTL
c Eval *in52 = *off
c EndSR
c* ___________________________________________________
c SRLoad BegSR
c Do 100
c Eval DCode = rrn
c Eval DName = 'Abc'
c Eval Dprice = 1.2 * rrn
c Write SFLDT
c Eval rrn = rrn + 1
c Eval totrec = totrec + 1
76
RPG-ILE LABS
c EndDO
c EndSR
c*____________________________________________________
c*
c SRDsp BegSR
c Eval *in50 = *on
c Eval *in51 = *on
c write sflctl
c write foot
c Exfmt SflcTL
c Eval *in50 = *off
c Eval *in51 = *off
c EndSR
c*____________________________________________________
c SRUsr BegSR
c Z-add 1 dummy
c If *in05 = *off
c Dow dummy = 1
c Readc sfldt
c If %Eof
c Leave
c EndIf
c Eval *in55 = *on
c Eval *in77 = *on
c update sfldt
c Eval *in77 = *off
c EndDo
c EndIF
c*
c* Check if user wants to clear the hi-light
c* User presses F5 to remove all hi-lights.
c*
c Eval *in55 = *off
c If *in05 = *on
c '05 on' dsply
c Z-add 1 dummy
c Dow dummy = 1
c Readc sfldt
c If %Eof
c Leave
c EndIf
c Eval *in55 = *off
c*********** Eval *in77 = *on
c update sfldt
c 'remove' dsply
c EndDo
c Eval *in05 = *off
c EndIF
c EndSR
77
RPG-ILE LABS
LAB : SFLNXTCHG
Linkage : RPSFLNXT,DSSFLNXT
CODE :
78
RPG-ILE LABS
c IF *in06=*on
c Eval *in06=*off
c Exsr ChgSR1
c EndIf
c*
c IF *in10=*on
c Eval *in10=*off
c EXSR ChgSR2
c EndIF
c ENDSR
c*
c ChgSR1 BegSR
c Readc SFLDT 78
c*
c DoW NOT *in78
c DCode Dsply
c DName Dsply
c* ---------------
c* should we reset
c* the MDT ?
c* ----------------
c If ResetMDT = 1
c Eval *in77=*ON
c* Switch on MDT
c Update SFLDT
c Eval *in77=*OFF
c 'reset !' Dsply
c EndIf
c*
c Readc SFLDT 78
c EndDO
c*
c EndSR
c*
c ChgSR2 BegSR
c eval ResetMDT = 1
c Exsr ChgSR1
c eval ResetMDT = 0
c EndSR
A DSPSIZ(24 80 *DS3)
A CA03(03)
A CF06(06)
A CF10(10)
A R SFLDT SFL
A 77 SFLNXTCHG
A DCODE 4 0B 8 4COLOR(RED)
A DNAME 20 B 8 21COLOR(WHT)
A DPRICE 7 2B 8 48EDTWRD(' . ')
A COLOR(WHT)
A 8 59'Rs'
A R SFLCTL SFLCTL(SFLDT)
A 50 SFLDSP
A 51 SFLDSPCTL
A 52 SFLCLR
A SFLSIZ(0006)
A SFLPAG(0005)
A 2 18'Demo of SFLNXT Change'
79
RPG-ILE LABS
PF contents :
OUTPUT :
If 1,2 (or more) records are edited and F6 is pressed, the program shows us the
records that have changed and resets their MDT. Press F6 again has no effect since
the MDT of those records are now reset (ie set to 0).
However, if F10 is pressed, the changed records are displayed but their MDTs are set
back to 1. Pressing F10 again and again will re-display the same set of records since
their MDTs are never set to zero.
REMARKS :
Linkage : RPSFLCHAIN
CODE :
80
RPG-ILE LABS
C Write SflCTL
C Eval *in52 = *off
C EndSR
C*
C*
C LDSR BegSR
c Read bm
c Dow Not %EOF
c Eval DCode = BCode
c Eval DName = BName
c Eval DPrice = BPrice
c Eval RRN = RRN + 1
c Eval Cntr = Cntr + 1
c Write SFLDT
c Read bm
c EndDo
c EndSR
c*
c*
c DspSR BegSR
c Eval *in50=*on
c Eval *in51=*on
c Exfmt SFLCTL
c Eval *in50=*off
c Eval *in51=*off
c EndSR
c*
c*
c UsrSR BegSR
c Eval temp=1
c IF *in06=*on
c* ___________________
c*|access each record |
c*|of the subfile. |
c*|if the record has |
c*|bprice greater than|
c*|the one specified, |
c*|Hilight it otherwis|
c*|leave it. |
c*|___________________|
c Dow temp< cntr
c temp Chain SFLDT
c* in77 is for SFLNXTCHG
c*
c if Dprice > DUsrPrc
c Eval *in77 = *ON
c Eval *in88 = *ON
c Update SFLDT
c Eval *in77 = *Off
c Eval *in88 = *Off
c* else !
c else
c Eval *in88 = *off
c Eval *in77 = *on
c Update SFLDT
c Eval *in77 = *off
c*
c EndIf
c Eval temp=temp+1
c EndDo
81
RPG-ILE LABS
A DSPSIZ(24 80 *DS3)
A CA03(03)
A CF06(06)
A CF10(10)
A R SFLDT SFL
A 77 SFLNXTCHG
A DCODE 4S 0B 8 4COLOR(RED)
A 88 DSPATR(RI)
A DNAME 20A B 8 21COLOR(WHT)
A 88 DSPATR(RI)
A DPRICE 7Y 2B 8 48EDTWRD(' . ')
A 88 DSPATR(RI)
A COLOR(WHT)
A 8 59'Rs'
A R SFLCTL SFLCTL(SFLDT)
A SFLSIZ(0006)
A SFLPAG(0005)
A 50 SFLDSP
A 51 SFLDSPCTL
A 52 SFLCLR
A 2 18'Demo of SFLNXT Change'
A 7 4'Code Name
A Price'
A COLOR(WHT)
A 4 3'Enter upper limit for book
A '
A COLOR(WHT)
A DUSRPRC 7 2B 4 40EDTWRD(' . ')
A COLOR(RED)
A 6 4'Press F6 to hi-light all r
A ith book prices greater tha
A rice'
A COLOR(TRQ)
PF contents :
OUTPUT :
Enter a book price in the “Upper Limit” field. And press F6. All records where the
book price is greater than the specified book price are highlighted. Reset of the
records are not highlighted.
82
RPG-ILE LABS
REMARKS :
Principle : Scan each record in the subfile using chain. For each record check if
DPRICE is greater than DUSRPRC (which is user specified price) if DPRICE is larger,
switch on indicators for SFLNXTCHG and DSPATR(RI) and call UPDATE. This maeks the
record active (in77) and hi-lights it (in88). Switch off both indicator. Proceed to
the next record.
In this manner all records are checked and MDT is set on for those who have bprice
greater than specified. Hilighting is done only when SFLNXTCHG is on. If this is
tried at other times, when SFLNXTCHG is off, there will be no effect.
STUDY PROGRAM
For following program displays al records of the Book Master database file.
It accepts book price from user and
Displays all records where book price is 100 greater than specified book price in RI
form.(reverse image)
It displays records where bprice = specified bprice or upto specified bprice + 100 in
Hi intensity (bname comes with a column sperator)
Linkage : RPSFLCHAI1
Display file : DSSFLCHAI1
83
RPG-ILE LABS
84
RPG-ILE LABS
c ENDSR
c HiLight BegSR
c* 88 is for DSPATR(RI)
c*
c Eval *in88 = *on
c Write SFLCTL
c Eval *in88 = *off
c
c EndSR
c*
DISPLAY FILE :
A DSPSIZ(24 80 *DS3)
A CA03(03)
A CF06(06)
A CF10(10)
A R SFLDT SFL
A 77 SFLNXTCHG
A DCODE 4S 0B 8 4
A 88 DSPATR(RI)
A 89 DSPATR(UL)
A DNAME 20A B 8 21
A 88 DSPATR(RI)
A 89 DSPATR(CS)
A DPRICE 7Y 2B 8 48EDTWRD(' . ')
A 88 DSPATR(RI)
A 89 DSPATR(HI)
A
A 8 59'Rs'
A R SFLCTL SFLCTL(SFLDT)
A SFLSIZ(0006)
A SFLPAG(0005)
A 50 SFLDSP
A 51 SFLDSPCTL
A 52 SFLCLR
A 2 18'Demo of SFLNXT Change'
A 7 4'Code Name
A Price'
A COLOR(WHT)
A 4 3'Enter upper limit for book
A '
A COLOR(WHT)
A DUSRPRC 7 2B 4 40EDTWRD(' . ')
A COLOR(RED)
A 6 4'Press F6 to hi-light all r
A ith book prices greater tha
A rice'
A COLOR(TRQ)
Linkage : rpmulti,dsmulti
CODE :
85
RPG-ILE LABS
86
RPG-ILE LABS
c Eval *in60=*on
c Exfmt SFLCTL2
c Eval *in60=*off
c Eval *in61=*off
c EndSR
DISPLAY FILE :
A DSPSIZ(24 80 *DS3)
A CA03(03)
A R SFLDT1 SFL
A DCODE1 4 0B 4 5COLOR(WHT)
A DNAME 20 B 4 18COLOR(WHT)
A DPRICE 7 2B 4 43EDTWRD(' . ')
A COLOR(WHT)
A 4 53'Rs'
A R SFLCTL1 SFLCTL(SFLDT1)
A 50 SFLDSP
A 51 SFLDSPCTL
A 52 SFLCLR
A SFLSIZ(0005)
A SFLPAG(0004)
A 1 25'Book Master Information'
A COLOR(WHT)
A 3 6'Code Name
A Price'
A R SFLDT2 SFL
A DCODE2 4 0B 18 10
A DBIN 4 0B 18 22
A DBOUT 4 0B 18 31
A R SFLCTL2 SFLCTL(SFLDT2)
A 60 SFLDSP
A 61 SFLDSPCTL
A 62 SFLCLR
A SFLSIZ(0004)
A SFLPAG(0003)
A OVERLAY
A 14 12'Transaction Details'
A COLOR(RED)
A 16 11'Code IN OUT'
A COLOR(WHT)
PF contents :
OUTPUT :
Simple displays all records in the respective files in the respective subfiles. It is
a simple display program.
REMARKS :
---
87
RPG-ILE LABS
CODE :
DISPLAY FILE :
A DSPSIZ(24 80 *DS3)
A CA03(03)
A R SFLDT SFL
A DCODE 4 0B 6 7
A DNAME 20 B 6 18
A DPRICE 7 2B 6 41EDTWRD(' . ')
A R SFLCTL SFLCTL(SFLDT)
A 50 SFLDSP
A 51 SFLDSPCTL
A 52 SFLCLR
A SFLSIZ(0005)
A SFLPAG(0004)
A SFLCSRRRN(&N)
A N 5S 0H
A 3 7'test subfile'
88
RPG-ILE LABS
PF contents :
nil
OUTPUT :
SFLCSRRRN loads the rrn number of the record where cursor is present into the
supplied variable : N. Thus if cursor is on the second page and second record (and
page size is 5 ) then n=7.
REMARKS :
Can get direct access to exact rrn number of the subfile where the cursor is located.
Linkage : TESTRPG2,sUBMOD,
Display : TESTSFL
CODE :
TESTRPG2 :
D*
D*
c Callb 'SUBMOD'
c Eval *inlr=*on
SUBMOD :
89
RPG-ILE LABS
c Eval *in06=*off
c callp UsrSR
c EndIf
c*
c EndDo
c Eval *inlr=*on
c Return
c*
c* _____________________________________
c*
PClrSR B
dclrsr pi
c Eval *in52=*on
c Write SflCTL
c Eval *in52=*off
PClrSR E
c*
c*
PLdSR B
dLdsr pi
c Read BM
c dow Not %EOF
c Eval DCode = BCode
c Eval DName = BName
c Eval DPrice = BPrice
c Eval rrn = rrn + 1
c Write SFLDT
c Read BM
c Enddo
PLdSR E
c*
c*
PDspSR B
DDspSR PR
c Eval *in50=*on
c Eval *in51=*on
c if n <> 0
c Eval drecptr = n
c EndIf
c Exfmt SflCTL
c Eval *in50=*off
c Eval *in51=*off
PDspSR E
c*
PUsrSR B
DUsrSR PR
dtemp s 4s 0 inz(0)
c* check where the cursor is.
c* if n is zero, cursor is not in the subfile at all.
c* n is a parameter given to SFLCSRRRN in the subfile.
c*
c If n=0
c return
c endIf
c* read the subfile record where cursor is present
c n chain sfldt
c*
c* ------------------------------------------
c* show matching records in the transaction file in a new subfile.
c Eval temp = dcode
90
RPG-ILE LABS
c Callp ShowSubfile(temp)
PUsrSR E
c*
c*===================================================
c* showsubfile displays the second subfile containing
c* matching records from the transaction file.
c*
PShowSubFile B
DShowSubFile PI
dtheCode 4s 0
dretval s 5i 0
c*arg theCode contains the dcode,
c callp clrsr1
c Eval retval = ldsr1(theCode)
c*
c If retval =-1
c* no records were loaded !!!
c 'no records !'dsply
c return
c EndIf
c*
c callp dspsr1
c return
PShowSubFile e
PClrsr1 b
dClrsr1 PI
c Eval rrn1=0
c Eval *in62=*on
c Write sflctl1
c Eval *in62=*off
PClrsr1 e
c*
PLdsr1 b
dLdsr1 PI 5i 0
dbkcode 4s 0
dretval s 5i 0
c 'filter :' dsply
c bkcode dsply
c Eval rrn1 = 0
c 1 Setll bio
c Read bio
c Dow Not %EOF
c*
c* pickup only records where bcode matches
c If xBCode = bkcode
c Eval DCode1 = xBCode
c Eval DBin = xBin
c Eval DBout = xBout
c Eval RRN1 = RRN1 +1
c write Sfldt1
c EndIf
c Read bio
c Enddo
c If rrn1=0
c* No records where loaded!!!
c 'no rec !' dsply
c Eval retval=-1
c return retval
c else
c Eval retval=1
91
RPG-ILE LABS
c return retval
c
c EndIf
PLdsr1 E
PDspSR1 B
c Eval *in60 = *On
c Eval *in61 = *On
c Exfmt Sflctl1
c Eval *in60 = *Off
c Eval *in61 = *Off
PDspSR1 E
DISPLAY FILE :
A DSPSIZ(24 80 *DS3)
A CA03(03)
A CF06(06)
A R SFLDT SFL
A DCODE 4 0B 6 7
A DNAME 20 B 6 18
A DPRICE 7 2B 6 41EDTWRD(' . ')
A R SFLCTL SFLCTL(SFLDT)
A SFLSIZ(0005)
A SFLPAG(0004)
A 50 SFLDSP
A 51 SFLDSPCTL
A 52 SFLCLR
A SFLCSRRRN(&N)
A DRECPTR 4S 0H SFLRCDNBR
A N 5S 0H
A 4 57'F6 : lookup Transaction'
A COLOR(BLU)
A 1 9'Book Master Records'
A COLOR(RED)
A R SFLDT1 SFL
A DCODE1 4S 0B 17 10
A DBIN 4S 0B 17 20
A DBOUT 4S 0B 17 29
A R SFLCTL1 SFLCTL(SFLDT1)
A 60 SFLDSP
A 61 SFLDSPCTL
A 62 SFLCLR
A SFLSIZ(0005)
A SFLPAG(0004)
A OVERLAY
A 15 23'Transaction Details...'
A COLOR(RED)
A DSPATR(UL)
PF contents :
Frist subfile displays all records of the PFBM. Second subfile displays select
records from PFBIO. The selection criteria comes from the frist subfile. Use will
place cursor on a record and press F6. The dcode at the cursor location is scanned
and transaction records related to that bcode are loaded into the second subfile that
is displayed.
OUTPUT :
92
RPG-ILE LABS
REMARKS :
---
Linkage : DSWINSFL
Linkage :
CODE :
A DSPSIZ(24 80 *DS3)
A CA03(03)
A R SFLDT SFL
A DCODE 4 0B 7 10COLOR(RED)
A DNAME 20 B 7 19COLOR(WHT)
A DPRICE 7 2B 7 33EDTWRD(' . ')
A COLOR(WHT)
A 7 43'Rs'
A R SFLCTL SFLCTL(SFLDT)
A 50 SFLDSP
A 51 SFLDSPCTL
A 52 SFLCLR
A SFLSIZ(0011)
A SFLPAG(0007) .
A WINDOW(2 2 16 60)
A OVERLAY
A 4 18'Subfile Test'
A COLOR(WHT)
A 6 10'Code'
A COLOR(WHT)
A 6 20'Name'
A COLOR(WHT)
A 6 34'Price'
A COLOR(WHT)
PF contents :
OUTPUT :
REMARKS :
93
RPG-ILE LABS
A R SMAS
A SROLL 4S 0
A SNAME 10A
CAUTION :
FOLLOWING PROGRAM GIVES INCORRECT RESULTS FOR
C EVAL VCD2=%TRIM(%SUBST(VCD1:NOFF:4))
SUITABLE FUNCTION TO CONVERT THE CHARECTER REPRESENTATION OF A STRING INTO NUMERIC IS REQUIRED.
REST OF THE PROGRAM GIVES THE DATA IN THE RECORD SEND BY THE DB ENGINE TO THIS PROGRAM VIA
COMMAND LINE ARGUMENTS.
DPARM1 DS 130
DNOFF 65 68B 0
DPARM2 DS
DLENG 1 40
DLEN1 S 4S 0
DVCD1 S 130A
DVCD2 S 10A
DROLLNO S 4F
D* ___________________________________________________
C *ENTRY PLIST
C PARM1 PARM PARM1
C PARM2 PARM PARM2
C NOFF DSPLY
C*
C EVAL VCD1=PARM1
C EVAL VCD2=%TRIM(%SUBST(VCD1:NOFF:4))
C VCD2 DSPLY
C ADD 5 NOFF
C EVAL VCD2=*BLANKS
C EVAL VCD2=%SUBST(VCD1:NOFF:10)
C VCD2 DSPLY
C* 5STUDENT5
C EVAL *INLR=*ON
C RETURN
C*
94
RPG-ILE LABS
LAB : Working with Procedures in the ILE program. Compilation procedure. Variable
life time and scoping. Local and Global variables.
* ---------------------------
*
* ---------------------------
DADDNUM pr 5i 0
dA1 5i 0
dA2 5i 0
DA s 5i 0
DB s 5i 0
DX s 5i 0
c eval A=5
c eval B=20
c eval x=ADDNUM(A:B)
c X dsply
c seton LR
C* ____________________________________________
C*
PADDNUM B
DADDNUM PI 5I 0
DNUM1 5I 0
DNUM2 5I 0
DRES S 5I 0
C EVAL RES=NUM1+NUM2
C RETURN RES
PADDNUM E
Use option 15 to create a Module object. Then use command CRTPGM to create program
object. For CRTPGM, specify the module as P1 and program object name as any name like
, say, P1. this creates a P1 object in the current library.
95
RPG-ILE LABS
MODULE R0 CALLS PROCEDURES IN MODULES R1 (ILLUSTRATES CALL BY REF AND CALL BY VALUE )
DFN1 PR
DX1 5I 0
DFN2 PR
DX2 5I 0 VALUE
DNUM1 S 5I 0 INZ(10)
DNUM2 S 5I 0 INZ(10)
C NUM1 DSPLY
C CALLP FN1(NUM1)
C NUM1 DSPLY
C NUM2 DSPLY
C CALLP FN2(NUM2)
C NUM2 DSPLY
C SETON LR
HNOMAIN
DFN1 PR
DA 5I 0
DFN2 PR
DB 5I 0 VALUE
PFN1 B EXPORT
DFN1 PI
DA 5I 0
C IF A = 10
C EVAL A = A + 1
C ENDIF
PFN1 E
PFN2 B EXPORT
DFN2 PI
DB 5I 0 VALUE
C IF B = 10
C EVAL B = B + 1
C ENDIF
PFN2 E
96
RPG-ILE LABS
DFN1 PR
DX1 5I 0
DNUM1 S 5I 0 INZ(10)
DNUM2 S 5I 0 INZ(10)
C NUM1 DSPLY
C CALLP FN1(NUM1)
C NUM1 DSPLY
C SETON LR
HNOMAIN
DFN1 PR
DA 5I 0
DFN2 PR
DB 5I 0 VALUE
PFN1 B EXPORT
DFN1 PI
DA 5I 0
D*
C IF A=10
C CALLP FN2(A)
C ENDIF
C EXSR SR1
C*
C SR1 BEGSR
C EVAL A=A+5
C ENDSR
PFN1 E
PFN2 B
DFN2 PI
DB 5I 0 VALUE
C IF B = 10
C EVAL B = B + 1
C ENDIF
PFN2 E
* ----------------------------------
| CALLING BOUND CLLE PROCEDURE |
* ----------------------------------
DPROC1 PR
C CALLB 'PROC1'
C SETON LR
97
RPG-ILE LABS
0001.00 pgm
0002.00 WRKSPLF
0003.00 endpgm
LAB : CALLB
R0 : CLIENT APPLICATION :
DFN1 PR
DX1 5I 0
DNUM1 S 5I 0 INZ(10)
C CALLB 'R1' <-- DIRECT CALL TO R1
C NUM1 DSPLY
C CALLP FN1(NUM1)
C NUM1 DSPLY
C SETON LR
DFN1 PR
DA 5I 0
DVAL1 S 5I 0 INZ(10)
C CALLP FN1(VAL1)
C 'MAINCODE END'DSPLY
C SETON LR
C*__________________________________________
PFN1 B EXPORT
DFN1 PI
DA 5I 0
D*
C IF A=10
C EVAL A=A+10
C ENDIF
PFN1 E
98
RPG-ILE LABS
LAB : *VARSIZE
DFn1 PR
DStr1 4a OPTIONS(*VARSIZE)
dS1 s 3a inz('abc')
dS2 s 8a inz('abcxyzmn')
dS3 s 1a inz('a')
c
c
C Callp Fn1(s1)
C Callp Fn1(s2)
C Callp Fn1(s3)
C Eval *inlr = *on
C Return
H NOMAIN
dMyds sds
dLnNum 21 28
dStatus *status
d*
dFn1 PR
dstr 4a OPTIONS(*VARSIZE)
PFn1 B Export
dFn1 PI
dstr1 4a OPTIONS(*VARSIZE)
dRslt s 20a
c
c Eval Rslt = 'I Got : '+ str1
c rslt Dsply
PFn1 E
99
RPG-ILE LABS
MODULE : R1
MODULE : R0
LISTING OF RO :
DFN1 PR
DX1 5I 0
DNUM1 S 5I 0 INZ(10)
DNUM2 S 5I 0 INZ(25) EXPORT
C NUM2 DSPLY
C CALLB 'R1'
C NUM2 DSPLY
C NUM1 DSPLY
C CALLP FN1(NUM1)
C NUM1 DSPLY
C SETON LR
R1 MODULE :
H*
DNUM2 S 5I 0 IMPORT
DFN1 PR
DA 5I 0
DVAL1 S 5I 0 INZ(10)
C CALLP FN1(VAL1)
C EVAL NUM2=NUM2+100
C NUM2 DSPLY
C 'MAINCODE END'DSPLY
C SETON LR
C*
C* -----------------------------------------
PFN1 B EXPORT
DFN1 PI
DA 5I 0
D*
100
RPG-ILE LABS
C IF A=10
C EVAL A=A+10
C ENDIF
PFN1 E
OUTPUT :
DSPLY 25
DSPLY 125
DSPLY MAINCODE END
DSPLY 125
DSPLY 10
DSPLY 20
LAB : *NOPASS : optional parameter. Need not be passed. Will be passed only if the
need is there.
dP1 PR 2s 0
d 5i 0
d 5i 0
d 10a
d 10a options(*NOPASS)
d*
dn1 s 5i 0 inz(100)
dn2 s 5i 0 inz(8)
ds1 s 10a inz('C')
ds2 s 10a inz('ACAD')
dRetVal s 2s 0 inz(0)
C Eval RetVal=P1(N1:N2:S1)
C Eval *INLR = *ON
C Return
C*--------------------------------------------------
PP1 B
dP1 PI 2s 0
dn1 5i 0
dn2 5i 0
ds1 10a
ds2 10a Options(*NOPASS) // parameter with NOPASS
should
// be at the last.
dlocal s 2s 0
dParams s 5i 0
c 'Procedure' Dsply
c Eval params = %PARMS()
c If params = 4
c 'all 4 passed'dsply
c EndIf
c If params = 3
c '3 passed' dsply
c EndIf
c Eval Local=18
c return Local
PP1 E
101
RPG-ILE LABS
OUTPUT :
DSPLY Procedure
DSPLY 3 passed
Because parameters are positional, once you specify *NOPASS on a parameter, all parameters after
that must be also be coded with *NOPASS. When the procedure is called, if an optional parameter
is omitted, all parameters after that must also be omitted. A procedure can check if an optional
parameter was passed by using the %PARMS built in function. %PARMS will be set to the number
of parameters passed.
Lab : *OMIT
dP1 PR 2s 0
d 5i 0
d 5i 0
d 10a
d 10a options(*OMIT)
d*
dn1 s 5i 0 inz(100)
dn2 s 5i 0 inz(8)
ds1 s 10a inz('C')
ds2 s 10a inz('ACAD')
dRetVal s 2s 0 inz(0)
C Eval RetVal=P1(N1:N2:S1:*omit)
C Eval *INLR = *ON
C Return
C*--------------------------------------------------
PP1 B
dP1 PI 2s 0
dn1 5i 0
dn2 5i 0
ds1 10a
ds2 10a Options(*OMIT)
dlocal s 2s 0
c 'Procedure' Dsply
c Eval Local=18
c return Local
PP1 E
dP1 PR 2s 0
d 5i 0
d 5i 0
d 10a
options(*OMIT) // this parameters may
not be
102
RPG-ILE LABS
// still returns 4
c If params = 4
c 'all 4 passed'dsply
c EndIf
c If params = 3
c '3 passed' dsply
c EndIf
c*
c* S1 is not passed by the calling procedure,so S1's address
c* will be *NULL
c*
c If %addr(S1) = *null
c 'S1 omitted' dsply
c EndIf
c Eval Local=18
c return Local
PP1 E
OUTPUT :
DSPLY Procedure
DSPLY all 4 passed
DSPLY S1 omitted
We've seen up to this point that by using bind-by-reference rather than bind-by-copy we have a
much simpler maintenance task. When simple changes are made to the procedures (for example,
103
RPG-ILE LABS
to fix bugs), only the service program needs to be updated. The programs that are bound to the
service program will automatically use the new procedure the next time they are called.
The problem is when we make a less superficial change to a module. If, for example, we add a
new procedure to a module, or add optional parameters to an existing procedure, a different
signature will get generated when we create the service program. All programs that are bound to
that service program will need to be rebound, or they will get a signature violation error when
called.
At first, this seems like a pretty major oversight. The reason signature checks were added to ILE
was to prevent a program from calling a module with unknown changes, possible causing serious
application errors. This is very similar in concept to level checks on database files.
Also like level checks, there is a way around the problem. By using binder language you can
explicitly assign a signature to a service program which will override the system generated one.
LAB : Signature
Signatures
When a service program is created, it is assigned a unique signature based on the procedure
sequence and exports. When a program is bound to a service program, it is bound to the signature
as well. If new procedures are added to the service program, or exports are re-arranged, a
different signature will be generated. If the program is run against the new version of the service
program without being re-bound, a run-time error will generate.
A signature in this sense is very similar to a record format level identifier. If a record format
changes and the program is not re-compiled, you will get a level check error which is very similar
to a signature violation.
By using a binder language you can explicity specify a signature and eliminate signature
violations.
Lets assume we have a source member called PROC1 that has three procedures in it - DayOfWeek,
Uppercase, and Lowercase. In our example, this source member will get compiled into a module,
and a service program will get created from the module.
The binder source for the service program will look like this:
104
RPG-ILE LABS
The service program will then be given a signature of "PROC1a" rather than a system generated
one. If we make changes to the PROC1 module, we can determine ourselves if all programs using
it need to be changed.
If we made simple changes, added procedures, or added optional parms to the end of a procedure
interface, we could retain the existing signature.
If we made changes that we know will require modifications to the calling procedures, we can
assign a new signature of "PROC1b". This will force us to change and re-bind our programs.
LAB : RTVSRVSRC : auto generate the binder language code for a given service program
Create a service program from modules M1, M2, M3. Each modules exports 2 sub-
procedures, thus 6 procedures are exported. Some of these can be suppresed. Instead
of writing the binder language member from sctracth, use RTVSRVSRC and provide name
of the service program to it. The command prepares a member (of NO specific type) and
writes export definations to it. Change type of this member to BND. Comment out all
exports that you do not want to export and then re-create service prgoram using
CRTSRVPGM.
dP1 PR 2s 0
d 5i 0
d 4a
d*
dn1 s 5i 0 inz(100)
d*s1 (cannot pass smaller size) 4a inz('C')
ds1 s 6a inz('ABCDEF')
dRetVal s 2s 0 inz(0)
C Eval RetVal=P1(N1:S1)
C Eval *INLR = *ON
C Return
C*-------------------------------------------------
PP1 B
dP1 PI 2s 0
dn1 5i 0
ds1 4a
dlocal s 2s 0
c s1 Dsply
c Eval Local=18
c return Local
PP1 E
105
RPG-ILE LABS
Although the procedure expects an argument of size 4a, we pass 6a. (less will cause
compiler error). Truncation will happen. Data is stored left justified.
1. Automatic conversion will only occur if the expected parameter and the passes parameter
are the same general type. For example, numeric data will not be converted to character.
2. Shorter than expected numeric fields can safely be passed to a procedure. Longer than
expected numeric fields can also passed, however if a significant digit is truncated, you will
get a run-time overflow error.
3. Character strings of a greater length than expected may be passed. Right-side truncation
will occur (similar to MOVEL).
4. The keyword OPTIONS(*VARSIZE) may be coded on the D-specs of the procedure interface
and prototype to allow shorter length than expected character strings.
LAB : Operational Descriptor keyword and the CEEDOD API (should be called to retrieve the length
of the passed field which is controlled by *VARSIZE)
LAB :
LAB :
LAB : supress the main procedure of a module in a service program using a binder
language code,.
106
RPG-ILE LABS
107
RPG-ILE LABS
SERVER APPLICATION CODE : WE SHALL EXPORT ONLY THE ADNUM AND SUBNUM FUNCTIONS OUT OF
THE TOTAL 4 FUNCTIONS DEFINED IN THE LESER1 MODULE. (IN THE LESRC SOURCE PF)
HNOMAIN
H* ____________PROTOTYPE SECTION ____________
H* __________________________________________
DADDNUM pr 5i 0
DA1 5i 0
DSUBNUM pr 5i 0
DA2 5i 0
DMULNUM pr 5i 0
DA2 5i 0
DDIVNUM pr 5i 0
DA2 5i 0
D* __________ PROTOTYPE SECTION ENDS __________
D* --------------------------------------------
D*
PADDNUM B export
DADDNUM PI 5i 0
DA1 5i 0
Dresult S 5i 0
C eval result=A1+1
C 'ADDING**' DSPLY
C return result
PADDNUM e
P* __________________________________________
PSUBNUM B export
DSUBNUM PI 5i 0
DA2 5i 0
Dresult S 5i 0
C eval result=A2-1
C 'SUBTRACT*' DSPLY
C return result
PSUBNUM e
108
RPG-ILE LABS
P* __________________________________________
PMULNUM B export
DMULNUM PI 5i 0
DA2 5i 0
Dresult S 5i 0
C eval result=A2*2
C return result
PMULNUM e
P* __________________________________________
PDIVNUM B export
DDIVNUM PI 5i 0
DA2 5i 0
Dresult S 5i 0
C eval result=A2/2
C return result
PDIVNUM e
STRPGMEXP PGMLVL(*CURRENT)
export SYMBOL(ADDNUM)
export SYMBOL(SUBNUM)
endpgmexp
PROCEDURE :
1. Create the client application (LECLI1) that calls the procedures ADDNUM and
SUBNUM. The prototypes of the procedures are given in the client application.
Use option 15 to create the Module oBject of the client application.
2. Create the LESER1 server application as specified in the above code. It
contains 4 procedures, but we wish to export only the 2 procedures : ADDNUM
and SUBNUM.
3. Now create a Binder Language member s1 of the type BND and specify the above
code in it. IT is clear that ADDNUM and SUBNUM are the only procedures
exported.
4. Use CRTSRVPGM to create a service program. Specify the name of the Service
program as S1, Export as *SRCFILE, Export source file as LESRC (all our
program members are in LESRC) and export source member as S1. Since the Binder
language code S1 is guiding th process of creation of the service program,
onlu the exported procedures are now available to client applications.
5. Finally, use CRTPGM to specify LECLI1 as the module (PEP) and S1 as the
service program. The program P1 is created and can be run using CALL P1.
6. Make a change in the LECLI module : Write SOME code that uses MULNUM function.
(SOMETHING LIKE EVAL X = mulnum(B) or so…) After writing the code, convert
the LECLI1 code to Module object by using option 15. The module creates OK
with 00 severity.
7. Now try creating a program P2 using the LECLI1 Module and S1 service program
(as we did while creating P1). The program is not created. This is because the
Binder language code in the S1 (BND) object does not allow export of MULNUM
procedure. Thus we need to make a change in the S1 Member.
8. Change the S1 Binder language member as follows :
STRPGMEXP PGMLVL(*CURRENT)
export SYMBOL(ADDNUM)
export SYMBOL(SUBNUM)
export SYMBOL(MULNUM)
endpgmexp
109
RPG-ILE LABS
9. Use Update Service program (UPDSRVPGM) to update this service program with
the new Binder language definition (in addition, you also need to specify the
LESER1 module object in the parameters of this command).
10. Use CRTPGM to create a program object P2 from LECLI1 And S1 service program.
110
RPG-ILE LABS
LAB : Using CALLB to call main line code in a Module. Exchange data using IMPORT And
EXPORT.
* ________________________________________________________
* THIS MODULE CALLS THE LEMN MODULE WITH A CALLB OPCODE.
* N1 AND N2 ARE EXPORTED WHILE LEMN EXPORTS THE AVGNUM VARIABLE
* WHICH CONTAINS THE AVERAGE CACULATED BY LEMN.
* ________________________________________________________
*
*
DN1 s 5i 0 EXPORT
DN2 s 5i 0 EXPORT
DAVNUM s 5i 0 IMPORT
C eval N1=10
C eval N2=10
C CALLB 'LEMN'
C AVNUM DSPLY
C SETON LR
* ________________________________________________________
* THIS MODULE HAS MAIN LINE CODE THAT WILL BE CALLED
* BY CLIENT APPLICATION USING CALLB OPCODE.
* N1 N2 VALUES COME FROM THE CLIENT APPLICATION
* WHILE THE COMPUTED VALUE OF AVNUM (AVERAGE) IS EXPORTED
* BY THIS MODULE.
* ________________________________________________________
*
*
DN1 s 5i 0 IMPORT
DN2 s 5i 0 IMPORT
DAVNUM s 5i 0 EXPORT
C eval AVNUM=((N1+N2)/2)
C SETON LR
Creation : Use option 15 for both to create their respective module objects and then
use CRTPGM to create a program out of those modules.
* * *
111
RPG-ILE LABS
COMPARISON CHART
112
RPG-ILE LABS
OPERATION EXTENDERS :
RPG/400
READ BM N
55
ILE – RPG :
READ(N) BM
5
(P) : Pad the resulting string on the RIGHT hand side rather than left hand side.
MOVE S1 S2
Causes a padding of S2 on left.
S2 = “bbbbbABC”
MOVE(P) S1 S2
113
RPG-ILE LABS
CHEAT SHEET
MAX LF BASED ON PF : 32
114
RPG-ILE LABS
MORE ON SPECIFICATIONS
115
RPG-ILE LABS
CONVERSION CONSIDERATIONS
CVTRPGSRC
Source: details of the Source RPG file, member type, Soruce PF and library
Target : Name of LE source physical file,Member name and library name.
EXPAND COPY MEMBER EXPCPY: SET THIS TO *YES If you are using a /COPY in the source
member.
FREE and DEBUG operations in RPG /400 are not supported in RPG LE.
H-SPEC KEYWORDS
116
RPG-ILE LABS
Lab : Select a record format from a LF (amongst the multiple record formats)
Create 2 physical files : BMAST and PMAST (book master and publisher master)
Create a LF as follows :
A R BM PFILE(BKMAST)
A BCODE
A BNAME
A BPRICE
A K *NONE
A R PM PFILE(PMAST)
A PCODE
A PNAME
A K *NONE
RUNQRY on the LF returns records only from the first record format.
From ILE (or RPG) you can specify which record format is to be accessed as follows :
RPG/400 EQUIVALENT
------------------
FFILE1 UF E
DISK
F FMT1
KIGNORE
F FMT2
KIGNORE
F FMT3
KCOMMIT
This renaming of input database fields is not required in RPG IV since the limits
have been increased.
117
RPG-ILE LABS
118
RPG-ILE LABS
119
RPG-ILE LABS
BEST PRACTICE : Input the date from the user as a sinple 6S 0 numeric value. Proper
edit code and edit word should be used. Test this number (for example : 311204 using
the TEST(D) opcode. Specify the proper Format (such as *DMY) in the factor 1 and
check the state f the indicator in the LO section. Of the Indicator remains off, the
date is correct. This,way, the onus of checking correctness of the date (including
leap years and other factors) is on the system.
DSDATE2 :
A DSPSIZ(24 80 *DS3)
A CA03(03)
A R RDATE
A 5 10'INPUT THE DATE YOU WISH TO TEST’
A 8 10'===> '
A COLOR(BLU)
A FLD001 6Y 0B 8 17EDTWRD(' / / ')
A EDTMSK(' & & ')
A 6 10'(Format : DD/MM/YY'
A 6 29')'
A 12 11'Press ENTER to check...'
A COLOR(BLU)
===> ________
H DATFMT(*DMY)
FDsdate2 CF E WORKSTN
DDT1 S D
D* fld001 IS A 6S 0 FIELD : SIMPLE NUMERIC FIELD BUT HAS APPEARANCE
120
RPG-ILE LABS
HNOMAIN
FPFBM5 UF A E DISK
F*
D* --- VALIDATION ---
D*
121
RPG-ILE LABS
DVLD_DT PR 4S 0
DDCODE 4S 0 VALUE
DI1 1A
DDNAME 10A VALUE
DI2 1A
DDPRICE 7S 2 VALUE
DI3 1A
D* --- SAVE DATA TO PFBM5 ---
D*
DSAVE_DATA PR 4S 0
DDCODE 4S 0 VALUE
DDNAME 10A VALUE
DDPRICE 7S 2 VALUE
P*1
PSAVE_DATA B EXPORT
DSAVE_DATA PI 4S 0
DDCODE 4S 0 VALUE
DDNAME 10A VALUE
DDPRICE 7S 2 VALUE
DRETVAL S 4S 0 INZ(1)
C* DOES ALL SAVING TO PHYSICAL FILE
C*
C READ BM 44
C EVAL BCODE=DCODE
C EVAL BNAME=DNAME
C EVAL BPRICE=DPRICE
C WRITE BM 77
C* CHECK WRITE ERROR
C IF *IN77=*ON
C EVAL RETVAL=0
C* WRITE WAS NOT SUCCESSFUL
C*
C ELSE
C EVAL RETVAL=1
C* WRITE WAS SUCCESSFUL
C ENDIF
C RETURN RETVAL
PSAVE_DATA E
PVLD_DT B EXPORT
DVLD_DT PI 4S 0
DDCODE 4S 0 VALUE
DI1 1A
DDNAME 10A VALUE
DI2 1A
DDPRICE 7S 2 VALUE
DI3 1A
DRETVAL S 4S 0 INZ(1)
C*
C* START VALIDATION FOR DCODE
C*
C IF ((DCODE<100) OR (DCODE > 700))
C EVAL I1 = '1'
C ELSE
C EVAL I1 = '0'
C ENDIF
C*-
C*
C* START VALIDATION FOR DNAME
C*
C IF DNAME=*BLANKS
122
RPG-ILE LABS
C EVAL I2 = '1'
C ELSE
C EVAL I2 = '0'
C ENDIF
C*
C* START VALIDATION FOR DPRICE
C*
C IF DPRICE<0
C EVAL I3 = '1'
C ELSE
C EVAL I3 = '0'
C ENDIF
C*
C* ATLEAST 1 INDICATOR IS ON IF DATA IS NOT VALID
C* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
C IF ((I1 = '1') OR (I2 = '1') OR (I3 = '1'))
C EVAL RETVAL=0
C ELSE
C EVAL RETVAL=1
C ENDIF
C*
C RETURN RETVAL
C*
PVLD_DT E
P* ------------------------------------------
123
RPG-ILE LABS
C*-(
C IF *IN12 = *ON MAIN
C EVAL *INLR = *ON
C RETURN
C ENDIF
C IF *IN07=*ON
C EVAL *IN90 = *OFF
C EVAL *IN91 = *OFF
C EVAL *IN92 = *OFF
C EVAL RETVAL=VLD_DT(DCODE:*IN90:DNAME:*IN91:DPRICE
C :*IN92)
C IF RETVAL = 1
C EVAL RETVAL = SAVE_DATA(DCODE:DNAME:DPRICE)
C ENDIF
C ENDIF
C ENDDO
124
RPG-ILE LABS
DN1 S 4S 0 inz(120)
DS1 S 4A
DPtr1 S *
C EVAL Ptr1 = %ADDR (N1)
C EVAL S1 = %Str(Ptr1)
C S1 DSPLY
C EVAL *inlr = *on
DS1 S 4A inz('pqrs')
DS2 S 4A
DPtr1 S *
C EVAL Ptr1 = %ADDR (S1)
C EVAL S2 = %Str(Ptr1)
C S2 DSPLY
C*output : pqrs
C EVAL S1 = *BLANKS
C EVAL %Str(Ptr1:5) = 'abcd'
C* In the above expr. abcd is loaded into the pointer
C* from position 1 of abcd to position 4 abcd. Scanning stops at
C* position 5. thus 5 is the number of characters read from the RHS
C* expression.
C* OUTPUT : abcd
C S1 dsply
C EVAL *inlr = *on
DDS1 ds
DS1 30A
DS2 30A
DS3 30A
DPtr1 S *
Dstr S 90A
D*-------------------------------------------
C EVAL Ptr1 = %Addr(DS1)
C eval str = 'CODE not between 100&700 '
C 'Name cannot be BLANK ' +
C 'Price cannot be Negative'
C EVAL %Str(Ptr1:(%Size(str)+1))=str
C S1 DSPLY
c S2 DSPLY
c S3 DSPLY
C EVAL *INLR = *ON
LAB : Pointers
Linkage : RPPOINTER
125
RPG-ILE LABS
CODE :
Ds1 s 5a inz('xyz')
Ds2 s 5a inz(' ')
Dps1 s *
c Eval ps1 = %Addr(s1)
c Eval %Str(ps1:4) = 'abc'
c* _____________________________________________________________
c* |%Str(ps1:4) <- Load 'abc' into positions 1,2,3 of ps1.
c* |4th pos is for the terminator which is added automatically.
c* |____________________________________________________________
c s1 Dsply
c Eval s2 = %Str(ps1)
c s2 Dsply
c Eval *inlr=*on
PF contents :
OUTPUT :
REMARKS :
LAB : Pointer
Linkage : ---
CODE :
c s2 dsply
c Move s2 n1
c Eval n1 = n1 + 1
c n1 Dsply
c Eval *inlr=*on
C* OUTPUT :
C* 123
C* 124
PF contents :
126
RPG-ILE LABS
OUTPUT :
REMARKS :
Linkage :
CODE :
Linkage : RPPOINTER1
PF contents :
OUTPUT :
REMARKS :
127
RPG-ILE LABS
M1 Listing :
H DATFMT(*DMY)
DDs001 ds
DDys 2a
DMnt 2a
DYrs 2a
DFind_Difference PR
DD1 d
DD2 d
Dpr *
D*---------------------------------------------------
DD1 s D INZ(D'27/01/04')
DD2 S D INz(D'15/03/04')
Dpr s * inz(*NULL)
dTemp s 8a
D*
c EVAL pr = %Addr(Ds001)
C CAllp Find_Difference(D1:D2:pr)
c EVAL Temp = %Str(pr:7)
c Temp dsply
C Eval *inlr = *on
C Return
C* -------------------------------------------------------
M2 Listing :
128
RPG-ILE LABS
LAB :
Linkage :
CODE :
Linkage : RPPOINTER2
Listing :
d*
d* __________________________________________________________
d* Simple program to illustrate a pointer to a Data structure.
d* The pointer to DS is passed as a argument to a procedure
d* Processing can be done in the procedure.
d* ___________________________________________________________
d*
dFn1 PR
dp *
dDS001 DS
Ds1 15a inz('This is')
Ds2 15a inz('a test')
D*
Dps1 s *
c Eval ps1 = %Addr(DS001)
c callp Fn1(Ps1)
c Eval *inlr=*on
c* ----------------------------------------
c*
PFn1 B
DFn1 PI
dpArg1 *
dTemp0 s 30a
dTemp1 s 15a
dTemp2 s 15a
c Eval Temp0 = %Str(pArg1)
c Eval Temp1 = %Subst(Temp0:1:15)
c Eval Temp2 = %Subst(Temp0:16:15)
c Temp1 dsply
c Temp2 dsply
PFn1 E
PF contents :
OUTPUT :
129
RPG-ILE LABS
REMARKS :
LAB : Pointer to a DS
Linkage :
CODE :
Pass a pointer to DS to a function that will decipher the data in the DS and display
it in strings of length 10.
Main thing here is that Multi occurances of DS can be any value. The length of s1 (a
component of DS) can be any value.
Only condition :
d*
d* __________________________________________________________
d* DS of any size can be passed. Only condition is as follows :
d* (no of occurances * sizeof(s1) ) > 10
d* and should be a multiple of 10.
d* ___________________________________________________________
d* TARGET : In the next program, show this data in a Window Subfile !
dFn1 PR
dp *
d 4s 0
d 4s 0
d*****
dnOccurs s 4s 0 inz(40)
d* // MUST contain no of occurances of the data structure.
dnSize s 4s 0 inz(20)
d* // MUST contain size of S1 which is the only member of the data
d* // structure.
dDS001 DS occurs(40)
Ds1 20a inz('aaa')
D*
Dps1 s *
c Eval ps1 = %Addr(DS001)
c callp Fn1(Ps1:nOccurs:nSize)
c Eval *inlr=*on
c* ________________________________________
PFn1 B
DFn1 PI
dpArg1 *
dnOccurs 4s 0
dnSize 4s 0
d*----------------------------------------
dnLoops s 4s 0
dnStPos s 4s 0
dnCntr s 4s 0 inz(0)
d*-------------------------------------------
dnBase s 4s 0 inz(10)
d* nBase is always 10 !!!
d*-------------------------------------------
130
RPG-ILE LABS
d* var is the variable that will hold 10 positions of data from the input
d* total data.
dvar s 10a
c Eval nLoops = (nOccurs * nSize)/10
c Do nLoops
c Eval nStPos = (nBase * nCntr)+1
c Eval var = %Subst(%Str(pArg1):nStPos:nBase)
c Eval nCntr = nCntr + 1
c var Dsply
c EndDO
c 'loops :' dsply
c nLoops dsply
PFn1 E
PF contents :
OUTPUT :
REMARKS :
Suppose Element s1 in DS001 is of the size 40. The number of occurances of the SD are
20.
Total size = 40 * 20 = 800.
WE wish to break this 800 into units of 10 since the variable that will hold the data
will have a size of 10.
Thus number of iterations for the loop that shows those 800 bytes are 800/10 = 80.
WE access 10 positions at a time of this 800 characters long string by using
substring().
Linkage :
CODE :
Linkage : RPCONV
ds1 s 5a inz('123')
dn1 s 5s 0 inz(108)
c Eval n1 = %Int(s1)
c Eval n1 = n1 + 1
c n1 dsply
c Eval *inlr = *on
PF contents :
OUTPUT :
131
RPG-ILE LABS
REMARKS :
132
RPG-ILE LABS
dMyPsds sds
dSts *status
derr_line_no 21 28
dnsts s 4s 0 inz(0)
dArg1 s 4s 0 inz(12)
dArg2 s 4s 0 inz(0)
dRslt s 4s 0 inz(0)
dRtPoint s 6a
dTemp s 4s 0 inz(0)
c '-------' Dsply
c 'Start..' dsply
c '-------' Dsply
c Opr1 Tag
c Eval Rslt = Arg1 / Arg2
c Rslt Dsply
c '--- ' Dsply
c Eval *inlr = *on
c Return
c*
c*
c *pssr BEGSR
c Move sts nsts
c Move err_line_no Temp
c* is the error divide by zero ? ie 102 ?
c If nsts = 102
c Eval Arg2=2
c else
c* error is not a divide by zero End program.
c Eval RtPoint = '*CANCL'
c Endif
c If RtPoint <> '*CANCL'
c goto Opr1
c Endif
c Endsr RtPoint
OUTPUT :
DSPLY -------
DSPLY Start..
DSPLY -------
DSPLY 6
Program requests a Starting position outside the string length thus causing control
to jump into the PSSR error handler. PSSR displays lot of information.
133
RPG-ILE LABS
FDSERR CF E WORKSTN
DString1 s 10a inz('abcdefghij')
DStPos s 2s 0 inz(3)
DNumOfChar s 2s 0 inz(4)
DRslt s 10a
D*
DMyPSDS sds
DErr_Status *status
DErr_ProcName *Proc
DErr_Routine *Routine
DERr_LineNum 21 28
DErr_ExcpType 40 42
DErr_ExcpNum 43 46
DErr_PgmLib 81 90
DErr_ExcpData 91 170
DErr_ExcpID 171 174
DErr_Date 191 198
DErr_Year 199 200s 0
DErr_User 254 263
DErr_FileInfo 209 243
D*------------------------------------------------------------------
c Eval Rslt = %SubSt(String1:StPos:NumOfChar)
c Rslt Dsply
c* output : cdef
c Eval StPos = 10
c Eval NumofChar = 1
c Eval Rslt = *All' '
c Eval Rslt = %SubSt(String1:StPos:NumOfChar)
c Rslt Dsply
c* output : j
c* -------------------------------------
c* Deliberately cause an error condition
c* give an invalid starting position.
c*
c Eval StPos = 12
c Eval NumofChar = 4
c Eval Rslt = *All' '
c Eval Rslt = %SubSt(String1:StPos:NumOfChar)
c Rslt Dsply
c* output : ?
c 'Prg ENDED' DSPLY
c Eval *inlr = *on
c Return
c*
c* =====================================
c *PSSR BEGSR
c movel Err_excpdata DExcpData
c exfmt Rerr
c 'pssr' DSPLY
c 'Line number' dsply
c Err_Linenum dsply
c 'Err_Status' dsply
c Err_Status dsply
c 'Err_ProcName'dsply
c Err_ProcName dsply
c 'Err_Routine' dsply
c Err_Routine dsply
c 'Err_ExcpType'dsply
c Err_ExcpType dsply
c 'Err_ExcpNum' dsply
134
RPG-ILE LABS
c Err_ExcpNum dsply
c 'Err_PgmLib' dsply
c Err_PgmLib dsply
c* Err_ExcpData dsply
c 'Err_ExcpID' dsply
c Err_ExcpID dsply
c 'Err_Date' dsply
c Err_Date dsply
c 'Err_Year' dsply
c Err_Year dsply
c 'Err_User' dsply
c Err_User dsply
c 'Err_FileInfo'dsply
c Err_FileInfo dsply
c EVAL StPos = 1
c EVAL NumOfChar = 3
c*
c*
c* GETIN causes control to start from the First C-spec line in the
c* Program ! Cannot use GETIN
c* GETIN actually stands for GET INPUT REC which reads next record
c* from next run of the Logic Cycle.
c* DETC also does same thing. Not specifying anything in the Factor 2 of
c* ENDSR also does not solve the problem. The system error handler is
c** displayed after PSSR executes of nothing is specified in Factor 2.
C* solution to this problem can be found in the next lab.
C*
c* ENDSR '*GETIN'
c*
c ENDSR
Output
Error Data was displayed in a Display File :
error data :
DSPLY cdef
DSPLY j
DSPLY pssr
Err_Status DSPLY 100
Err_ProcName DSPLY RPSCAN
Err_Routine DSPLY *DETC
Err_ExcpType DSPLY RNX
Err_ExcpNum DSPLY 0100
Err_PgmLib DSPLY SAM2
Err_ExcpData DSPLY
Err_ExcpID DSPLY 07062004
Err_Date DSPLY 20
Err_Year DSPLY SAM2
Err_User DSPLY
Err_FileInfo
135
RPG-ILE LABS
136
RPG-ILE LABS
0062.00 c*
0063.00 c* Convert to Numeric
0064.00 c*
0065.00 c Move Err_LineNum LineNum
0078.00 c EVAL StPos = 1
0079.00 c EVAL NumOfChar = 3
0080.00 c If LineNum = 26
0081.00 c Goto OPR1
0082.00 c Endif
0083.00 c If LineNum = 36
0084.00 c Goto OPR2
0085.00 c Endif
0086.00 c If LineNum = 48
0087.00 c Goto OPR3
0088.00 c Endif
0090.00 c ENDSR
Output :
DSPLY pssr
DSPLY Line number
DSPLY 00000026
DSPLY Err_Status
DSPLY 100
DSPLY abc
DSPLY pssr
DSPLY Line number
DSPLY 00000036
DSPLY Err_Status
DSPLY 100
DSPLY abc
DSPLY pssr
DSPLY Line number
DSPLY 00000048
DSPLY Err_Status
DSPLY 100
DSPLY abc
dNumericData s 4a inz('120')
dCharData s 4a inz('abc')
dBlankData s 4a
d*
c TESTN NumericData 777879
c* 78 becomes on since variable contains leading spaces.
c* No indicator will be on if data is numeric and has no leading
c* spaces.
c*
c exsr dspsr
c TESTN CharData 777879
c* no indicator is on since data not numeric
c exsr dspsr
c TESTN BlankData 777879
c* Equal indicator on since data is blank.
c exsr dspsr
c Eval *inlr = *on
c Return
137
RPG-ILE LABS
c*
c dspsr Begsr
c *in77 dsply
c *in78 dsply
c *in79 dsply
c Eval *in77=*Off
c Eval *in78=*Off
c Eval *in79=*Off
c Endsr
138
RPG-ILE LABS
The RPGLe program calls a CLP program that sends a *PRV Pgm msg that is not displayed
on the screen. Then it sends a PGM MSG of the type *ESCAPE which causes control to
immediately return back into RPGLE (ignoring the WRKSPLF in the CLP) the control
enters PSSR and displays various parameters of the error MSG thus received from the
child application. If the parent application in this case was a CL program, it would
have used program level monmsg .
RPGLE Program :
Fdserr cf e workstn
DMyPSDS sds
DErr_Status *status
DErr_ProcName *Proc
DErr_Routine *Routine
DERr_LineNum 21 28
DErr_ExcpType 40 42
DErr_ExcpNum 43 46
DErr_ExcpData 91 170
DErr_ExcpID 171 174
c 'Before' dsply
c call 'CLERR'
c end1 Tag
c 'After' dsply
c Eval *inlr = *on
c Return
c*
c*
c *PSSR BEGSR
c 'pssr' DSPLY
c move err_excpdata dexcpdata
c exfmt rerr
c 'Line Number' DSPLY
c Err_Linenum DSPLY
c 'Err_Status' dsply
c Err_Status dsply
c 'Err_ProcName'dsply
c Err_ProcName dsply
c 'Err_Routine' dsply
c Err_Routine dsply
c 'Err_ExcpType'dsply
c Err_ExcpType dsply
c 'Err_ExcpNum' dsply
c Err_ExcpNum dsply
c Goto end1
c ENDSR
CLERR Program :
PGM
SNDPGMMSG MSG('THIS IS CLERR.') TOPGMQ(*PRV)
SNDPGMMSG MSGID(CAE0032) MSGF(QCPFMSG) MSGTYPE(*ESCAPE)
WRKSPLF
ENDPGM
OUTPUT :
DSPLY Before
DSPLY pssr
139
RPG-ILE LABS
I tried to see the step by step execution but could not add CLERR program since it is
a OPM program ( Said *YES to OPM source level debugging as well as a *YES to updte
production files) still I cannot add CLERR to the list of programs debugged. When the
CALL statemnt was executed, STRDBG did not show the code or step by step execution of
code in the CLERR program. CLERR was executed instantly and control went directly to
PSSR.
DRslt s 4s 0
DFn1 PR 4s 0
DN1 4s 0
DN2 4s 0
DN3 4s 0
DFn2 PR 4s 0
DN1 4s 0
DN2 4s 0
Da1 s 4s 0 inz(0)
Da2 s 4s 0 inz(0)
Da3 s 4s 0 inz(0)
c
c
C Eval Rslt = Fn1(a1:a2:a3)
C Rslt Dsply
C Eval Rslt = Fn2(a1:a2)
C Rslt Dsply
C Eval *inlr = *on
C Return
C
C
H NOMAIN
dMyds sds
dLnNum 21 28
dStatus *status
d*
140
RPG-ILE LABS
dFn1 PR 4s 0
dx1 4s 0
dy1 4s 0
dz1 4s 0
dFn2 PR 4s 0
dx2 4s 0
dy2 4s 0
dRslt s 4s 0
PFn1 B Export
dFn1 PI 4s 0
dx1 4s 0
dy1 4s 0
dz1 4s 0
c
c z-add *zeros x1
c Eval Rslt = (x1+y1+z1)/x1
c cnt1 Tag
c Return Rslt
c*
c *Pssr Begsr
c 'Pssr1' Dsply
c LnNum Dsply
c Status Dsply
c If LnNum = '00000021'
c Goto cnt1
c Endif
c Endsr
c
PFn1 E
PFn2 B Export
dFn2 PI 4s 0
dx2 4s 0
dy2 4s 0
c z-add *zeros x2
c Eval Rslt = (x2+y2)/x2
c Cnt2 Tag
c Return Rslt
c*
c *Pssr Begsr
c 'Pssr2' Dsply
c If LnNum = '00000040'
c Goto cnt2
c Endif
c Endsr
c
PFn2 E
CODE :
PROGRAM : RPDATETEST
HDatfmt(*dmy-)
FDsDtTest cf e workstn
dCheckDate PR 5i 0
dto_be_tested 6s 0
141
RPG-ILE LABS
dretval s 5i 0
ddt s 6s 0
c*O
c Dow *in03 = *off
c Exfmt Rec1
c Eval dt = ddt001
c Eval RetVal = CheckDate(dt)
c Select
c when Retval = -1
c Eval dstat = 'Wrong !'
c when Retval = 1
c Eval dstat = 'Correct'
c other
c 'huh ?!' dsply
c endsl
c EndDo
c* -O
c Eval *inlr = *on
c return
c* Check Date procedure
c* ____________________________________________________
PCheckDate B
DCheckDate PI 5i 0
dTestDate 6s 0
dRetVal s 5i 0 inz(0)
c *DMY TEST(D) TestDate 66
c if *in66=*on
c Eval RetVal = -1
c Else
c Eval RetVal = 1
c EndIf
c Return RetVal
PCheckDate E
A DSPSIZ(24 80 *DS3)
A R REC1
A CA03(03)
A WINDOW(2 2 20 40)
A 2 13'Date Test Program'
A 5 5'Enter date to test :'
A DDT001 6Y 0B 7 6COLOR(BLU)
A EDTWRD(' - - ')
A EDTMSK(' & & ')
A 12 7'Status :'
A COLOR(WHT)
A DSTAT 10 O 12 18COLOR(WHT)
PF contents :
nil
OUTPUT :
REMARKS :
142
RPG-ILE LABS
143
RPG-ILE LABS
RP0001 Listing : This program is never compiled. Only used by RP0002 for its
subroutines.
c sr1 begsr
c 'hello' dsply
c endsr
c exsr sr1
c seton lr
c return
c/COPY SAM2/QRADLE,RP0001
The /Copy should come exactly where you wish to have the code pasted.
Since Subroutines come after SETON LR, I have placed the /COPY after Seton Lr and
RETURN.
RP001 Listing :
dn1 s 5i 0 inz(8)
d n2 s 5i 0 inz(100)
drslt s 5i 0
c Eval rslt = n1 + n2
c rslt Dsply
c Exsr SR001
c Eval *inlr = *on
c Return
c/COPY train12/sameerr,rp002
RP002 Listing :
c SR001 BegSr
c 'SR001!' Dsply
c EndSR
144
RPG-ILE LABS
145
RPG-ILE LABS
Linkage : RPCHAR
CODE :
DN1 s 5i 0 inz(108)
DS1 s 10a
c*
c* %Char converts int to character
c*
c Eval S1 = 'MECH' + %Char(N1)
c S1 Dsply
c*
c* Int converts char to int.
c* ---------------------------
c Monitor
C* Eval statement will definitely cause problem since we are trying to
C* convert non-numeric stuff to numeric.
C* We cannot use (E) as error handler operation extender since
C* E can be used with only those opcodes that allow error indicators (LO )
C*
c Eval N1 = %Int(s1)
c ON-ERROR
c 'Error' Dsply
c Endmon
c*
c*
c N1 Dsply
c Eval *inlr = *on
c Return
c*
PF contents :
---
OUTPUT :
Sensitive stuff (that can cause a run time error) should be placed inside MONITOR and
ENDMON group.If a statement (inside MONITOR group ) fails, control goes into ON_ERROR
and allows you to handle the error.
REMARKS :
146
RPG-ILE LABS
LAB : MONITOR and ENDMON: How it works. (this is the second lab)
Linkage : RPMON
CODE :
da s 4p 0 inz(10)
db s 4p 0 inz(2)
dc s 4p 0 inz(0)
ds s 4a
c Monitor
c Eval c = a/b
c Eval s = 'c = ' + %Char(c)
c Eval b = 0
c Eval c = a/b
c* the above EVAL throughs an exception
c* which is caught by ON_ERROR
c* the next EVAL statement is never executed
c* -----------------------------------------
c Eval s = 'c = ' + %Char(c)
c On-Error
c 'error !' Dsply
c EndMon
c 'Over' Dsply
c Eval *inlr = *on
PF contents :
---
OUTPUT :
REMARKS :
So long as the statements inside the MONITOR execute correctly, the execution
proceeds step by step. If a statement has a problem, control goes directly into ON-
ERROR skipping all the intermediate statements.
147
RPG-ILE LABS
dnum1 s 5i 0 inz(100)
c do 2
c If jsrvar <>12
c 'not 12' dsply
c z-add 12 jsrvar 5 0
c EndIf
c jsrvar Dsply
c EndDo
c Eval *inlr = *on
OUTPUT :
DSPLY not 12
DSPLY 12
DSPLY 12
dnum1 s 5i 0 inz(100)
c do 2
c If jsrvar <>12
c 'not 12' dsply
c z-add jsrvar jsrvar 5 0
c EndIf
c jsrvar Dsply
c EndDo
c Eval *inlr = *on
OUTPUT :
DSPLY not 12
DSPLY 0
DSPLY not 12
DSPLY 0
148
RPG-ILE LABS
149
RPG-ILE LABS
150
RPG-ILE LABS
CREATE A REPORT WITH NO SPACEA OR SPACEB FOR A RECORD FORMAT. WRITE A PROGRAM TO DO
MULTIPLE WRITE STATEMENTS TO THE RECORD FORMAT, YOU WILL FIND THAT THE LINES WILL BE
OVERWRITTEN.RLU DOES NOT AUTOMATICALLY PUT A LINE BETWEEN 2 WRITE OPERATIONS WHEN IT
COMES TO RECORD FORMAT OF A REPORT
FRL001 O E PRINTER
C WRITE RREC1
C WRITE RREC1
C WRITE RREC1
C WRITE RREC1
C WRITE RREC1
C EVAL *INLR = *ON
C RETURN
A R RREC1
A SPACEA(1)
A 4
A 'THIS IS A TEST'
A +8
A 'ONE MORE'
Report DDS :
A R RREC1
A 4'THIS IS A TEST'
A SPACEA(1)
A SKIPA(15)
A +8'ONE MORE'
After This is a TEST is printed on paper, a 1 line space is put. After that,
the paper slips straight to line 15, if LINE 15 found on the same page printing
continues on that page. If line 15 is already passed, system ejects current page and
continues printing from line 15 on the next page.
FRLHEX O E PRINTER
C write RHEX
C SETON LR
RLHEX Listing :
A R RHEX
151
RPG-ILE LABS
A 3
A ' '
A SPACEA(1)
A 15DFT(X'33') TRNSPY
A 17DFT(X'7C') TRNSPY
A R RHEX
A LINE(6.0 6.1 2 *HRZ 1)
Compile using Printer type as *SFPDS (Advanced Function Printer Data Stream) not IPDS
(intelligent Printer Data Stream)
A R RHEX PAGRTT(90)
A 5'HELLO'
A 11'WORLD'
Lab : CPI
A R RHEX LPI(9)
A 5'HELLO'
A 11'WORLD'
A R RDETL
A SPACEA(001)
A 3
A ' '
A PFLD1 4S 0 16
A R RPAGE
A 70
A 'PG '
A 75
A 78 PAGNBR
A EDTCDE(Z)
152
RPG-ILE LABS
LAB : POSITION keyword to place text at the right place on the paper
FRLpos O E PRINTER
dps s 4s 0 inz(12)
dpos1 s 5s 3 inz(2.00)
dpos2 s 5s 3 inz(3.00)
c Eval rfld1=ps
c Eval fld1=pos1
c Eval fld2=pos2
c write rpos
C SETON LR
Report :
A R RPOS
A RFLD1 4S 0 POSITION(&FLD1 &FLD2)
A FLD1 5S 3P
A FLD2 5S 3P
Please compile the report file with the device option set to
*AFPDS (Adv printing Function Data Stream)
OUTPUT :
A R RDETL
A CDEFNT(QFNTCPL/X0BITR)
A SPACEA(001)
A 3
A ' '
A PFLD1 4S 0 16
A R RPAGE
A 70
A 'PG '
A 75
153
RPG-ILE LABS
A 78 PAGNBR
A EDTCDE(Z)
RPG pprogram listing remains the same. Device type should not be anything other that
AFPDS.
LAB : indara
A DSPSIZ(24 80 *DS3)
A INDARA
A CA03(03)
A R RINDARA
A* OVERLAY
A CF07(07)
A 4 10'INDARA REC FMT'
A COLOR(WHT)
A R RINDARA1
A* OVERLAY
A CF07(08)
A 8 10'INDARA 1 '
A COLOR(RED)
FDSIndara CF E WORKSTN
c Dow *in03 = *off
c Write Rindara
c*** Write Rindara1
c Read Rindara 55
c Exsr ChkSR
c* Write Rindara
c Write Rindara1
c Read Rindara1 55
c Exsr ChkSR1
c Enddo
C Eval *inlr = *on
C Return
C*
C ChkSR Begsr
c 'INDARA :' dsply
C if *in07 = *on
c '07 ' dsply
c Endif
C if *in08 = *on
154
RPG-ILE LABS
If you press ENTER (and not any of the mapped function key), all indicators are
turned off. IN the next interation, both 07 and 08 are automatically OFF (don’t have
to be turned of explicitly).
A R RPOS
A PCHAR 4A
A POSITION(&FLD1 &FLD2)
A FLD1 5S 3P
A FLD2 5S 3P
A*
FRLpos O E PRINTER
dn1 s 5s 3 inz(1)
dn2 s 5s 3 inz(1)
d*
c Eval n1 = n1 + 1
c Eval n2 = n2 + 0.5
c Eval fld1 = n1
c Eval fld2 = n2
c write rpos
c Eval n1 = n1 + 1
c Eval n2 = n2 + 0.5
c Eval fld1 = n1
c Eval fld2 = n2
c write rpos
C SETON LR
155
RPG-ILE LABS
This worked , but no Preview or spool file is displayed although it is created. The
system gives error message that the spool file contains Graphics data which cannot be
displayed.
Only sol is to take a physical printout.
156
RPG-ILE LABS
FDSWINTRY cf E workstn
DStartLine s 3s 0 inz(3)
DStartPosition s 3s 0 inz(3)
DTempNum s 3s 0 inz(0)
D*
C Eval StLine = StartLine
C Eval StPos = StartPosition
C exfmt Rwin
C Eval StartLine = 3
C Eval StartPosition = 30
C Eval StLine = StartLine
C Eval StPos = StartPosition
C Exfmt Rwin
C Eval *inlr = *on
C Return
Display file :
A DSPSIZ(24 80 *DS3)
A R RWIN
A WINDOW(&STLINE &STPOS 9 9)
A STLINE 3S 0P
A STPOS 3S 0P
A FLD001 4 B 2 2
A FLD002 4 0B 4 2
A FLD003 4 B 6 2
A FLD004 4 0B 8 2
A 1 2'test Scr'
A DSPATR(UL)
LAB : RMVWDW : remove previously displayed windows when displaying current window.
A DSPSIZ(24 80 *DS3)
A R RWIN
A WINDOW(&STLINE &STPOS 9 9)
A RMVWDW
A STLINE 3S 0P
A STPOS 3S 0P
A FLD001 4A B 2 2
A FLD002 4S 0B 4 2
A FLD003 4A B 6 2
A FLD004 4S 0B 8 2
A 1 2'test Scr'
A DSPATR(UL)
FDSWINTRY cf E workstn
DStartLine s 3s 0 inz(3)
DStartPosition s 3s 0 inz(3)
DTempNum s 3s 0 inz(0)
D*
C Eval StLine = StartLine
C Eval StPos = StartPosition
C exfmt Rwin
C Eval StartLine = 3
157
RPG-ILE LABS
C Eval StartPosition = 30
C Eval StLine = StartLine
C Eval StPos = StartPosition
C Exfmt Rwin
C Eval *inlr = *on
C Return
fdstry cf e workstn
dn1 s 4s 0 inz(1)
c Eval stpos = 4
c Eval stlin = 3
c Dow *in03=*off
c write rwin
c exfmt rnormal
c if *in01 = *on
c Eval stpos = stpos +1
c Eval *in01 = *off
c Endif
c Enddo
c Eval *inlr = *on
c Return
A DSPSIZ(24 80 *DS3)
A R RNORMAL WINDOW(RWIN)
A CF01(01)
A CA03(03)
A 6 15'this is a normal record format’
A R RWIN
A WINDOW(&STLIN &STPOS 19 45)
A STLIN 3S 0P
A STPOS 3S 0P
LAB : How to display a Display file record format without the mandatory READ
operation on its record format
PART 1 :
FDSB00 CF E WORKSTN
C WRITE RB00
C 'HELO' DSPLY
C WRITE RB00
C SETON LR
C RETURN
The above code actually displays the display file record format, although there is no
READ operation. This is possible by setting the DFRWRT = *NO (defer write) during
Display file compilation.
PART 2 :
Same effect can be achieved by using FRCDTA (Force data) record level keyword.
A DSPSIZ(24 80 *DS3)
A R RBASE
A CA03(03)
158
RPG-ILE LABS
A FRCDTA
A 4 9'THIS IS A TEST OF BOO'
A 7 10'CODE :'
A 9 10'NAME :'
A 11 10'ADDRESS : '
A FLD1 4S 0B 7 21
A FLD2 20A B 9 21
A FLD3 30A B 11 21
A FLD4 30A B 12 21
A FLD5 30A B 13 21
A R RWIN
A CA12(12)
A WINDOW(4 50 9 9)
A OVERLAY
A FLD001 3 B 1 2
A FLD002 3 0B 3 2
A FLD003 2 0B 4 2
Rpgle :
FDSB00 CF E WORKSTN
C WRITE RBASE
C EXFMT RWIN
C WRITE RBASE
C WRITE RWIN
C READ RBASE 44
C SETON LR
C RETURN
LAB : csrloc TO POSITION THE CURSOR WHEN THE RECORD FORMAT IS BIEND DISPLAYED
FDSB00 CF E WORKSTN
C EVAL L = 9
C EVAL P = 21
C EXFMT RBASE
C SETON LR
C RETURN
A DSPSIZ(24 80 *DS3)
A R RBASE CSRLOC(L P)
A CA03(03)
A FRCDTA
A L 3S 0H
A P 3S 0H
A 4 9'THIS IS A TEST OF BOO'
A 7 10'CODE :'
A 9 10'NAME :'
A 11 10'ADDRESS : '
A FLD1 4S 0B 7 21
A FLD2 20A B 9 21
A FLD3 30A B 11 21
A FLD4 30A B 12 21
A FLD5 30A B 13 21
159
RPG-ILE LABS
LAB : CHECK(ER) to make Field Exit key work like ENTER key
It is recommended to use CHECK(ER) on the last field of the Display file. After data
entry operator has typed data into the last data field and pressed Field exit, he
need no press ENTER again to pass control into RPG. Then Field Exit is pressed for
the last field, it is works like ENTER because this field has CHECK(ER).
A DSPSIZ(24 80 *DS3)
A CA03(03)
A R RERASE
A 5 7'code : '
A 7 7'Name :'
A 9 7'Address :'
A FLD001 4S 0B 5 19
A FLD002 10A B 7 19
A FLD003 40A B 9 19
A FLD004 40A B 10 19
A 18 4'SAVE ? '
A FLD005 1A B 18 19CHECK(ER)
fdserase cf e workstn
c Exfmt RErase
c fld001 dsply
c Exfmt RErase
c fld001 dsply
c Exfmt RErase
c fld001 dsply
c Eval *inlr = *on
c Return
code : 2
Name : AMIT
SAVE ? Y
When User enters Y in the Save field, control immediately returns to RPG for further
operation.
A DSPSIZ(24 80 *DS3)
A CA03(03)
A R RERASE
A 5 7'code : '
160
RPG-ILE LABS
A 7 7'Name :'
A 9 7'Address :'
A FLD001 4S 0B 5 19
A FLD002 10A B 7 19
A CHECK(VN)
A FLD003 40A B 9 19
A FLD004 40A B 10 19
A 18 4'SAVE ? '
A FLD005 1A B 18 19CHECK(ER)
fdserase cf e workstn
c Exfmt RErase
c fld001 dsply
c Exfmt RErase
c fld001 dsply
c Exfmt RErase
c fld001 dsply
c Eval *inlr = *on
c Return
Display file listing (pay attention to the positions of the lines of the 2 record
formats. You will se that the the record formats overlap. Depending on need, one or
both can be displayed although only 1 will be in the READ mode)
CLRL (2) is specified for R1 record format.When R1 is displayed, All lines occupied
by R1 are first cleared. Since value specified CLRL is 2, a minimum of 2 lines will
be cleared. This last portion (last 2-3 lines) of RERASE is dislpayed
Even when an EXFMT is done to R1.
A DSPSIZ(24 80 *DS3)
A CA03(03)
A R RERASE
A OVERLAY
A 5 7'code : '
A 7 7'Name :'
A 9 7'Address :'
A FLD001 4S 0B 5 19TEXT('CODE VALUE')
A FLD002 10A B 7 19CHECK(VNE)
A FLD003 40A B 9 19
A FLD004 40A B 10 19
A 17 4'REC FMT 1'
A 18 4'SAVE ? '
A FLD005 1A B 18 19CHECK(ER)
A R R1 CLRL(2)
A OVERLAY
A 9 7'XXXXXXX'
A COLOR(RED)
161
RPG-ILE LABS
A 10 7'YYYYYYY'
A COLOR(RED)
A 11 7'ZZZZZZZ'
A COLOR(RED)
A FLD1 40A B 12 19
A COLOR(RED)
A FLD2 40A B 13 19
A COLOR(RED)
A 14 4'REC FMT 2'
A COLOR(RED)
RPGLE:
fdserase cf e workstn
c exfmt r1
c Exfmt RErase
c fld001 dsply
c exfmt r1
c Exfmt RErase
c fld001 dsply
c exfmt r1
c Exfmt RErase
c fld001 dsply
c Eval *inlr = *on
c Return
OUTPUT :
code : 1
Name : ANIL
XXXXXXX
YYYYYYY
ZZZZZZZ
TEST
DATA
REC FMT 2
REC FMT 1
SAVE ? Y
A DSPSIZ(24 80 *DS3)
A R RCHANGE
A CA03(03)
A 6 6'ARG1 : '
A COLOR(BLU)
A 8 6'ARG2 : '
A COLOR(BLU)
A 10 6'ARG3 :'
A COLOR(BLU)
A DARG1 4 0B 6 16COLOR(WHT)
A CHANGE(20)
162
RPG-ILE LABS
A DARG2 4 0B 8 16COLOR(WHT)
A CHANGE(21)
A DARG3 4 0B 10 16COLOR(WHT)
A CHANGE(22)
FDSCHANGE CF E WORKSTN
C Dow *in03 = *off
C Exfmt rchange
C *in20 Dsply
C *in21 Dsply
C *in22 Dsply
C Setoff 202122
C Enddo
C Eval *inlr= *on
C Return
| Float expressions are not allowed in the first parameter (you can use %DEC
| to convert a float to an editable format). The edit code is specified as
| a character constant; supported edit codes are: 'A' - 'D', 'J' - 'Q', 'X'
| - 'Z', '1' - '9'. The constant can be a literal, named constant or an
| expression whose value can be determined at compile time.
Subtopics
163
RPG-ILE LABS
4.1.1.5.1 %EDITC Examples
4.1.1.5 - 1
%EDITC Examples
| 4.1.1.5.1 %EDITC Examples
--------------------------------------------------------------------------
| D msg S 100A
| D salary S 9P 2
--------------------------------------------------------------------------
| Figure 125. %EDITC Example 1
--------------------------------------------------------------------------
| D neg S 5P 2 inz(-12.3)
| D pos S 5P 2 inz(54.32)
| D editparens PR 50A
| D val 30P 2 value
| D editedVal S 10A
| *---------------------------------------------------------------
| * Subprocedure EDITPARENS
| *---------------------------------------------------------------
| P editparens B
| D editparens PI 50A
164
RPG-ILE LABS
| D val 30P 2 value
| D lparen S 1A inz(' ')
| D rparen S 1A inz(' ')
| D res S 50A
| P editparens E
D RRN S 5 0
DDSINF001 DS
DKEYIN 369 369
DENTER C CONST(X'F1')
:
:
:
C IF KEYIN = ENTER
C // Code
165
RPG-ILE LABS
Example program :
REF :
***********************************************************
D F1 C CONST(X'31')
D F2 C CONST(X'32')
D F3 C CONST(X'33')
D F4 C CONST(X'34')
D F5 C CONST(X'35')
D F6 C CONST(X'36')
D F7 C CONST(X'37')
D F8 C CONST(X'38')
D F9 C CONST(X'39')
D F10 C CONST(X'3A')
D F11 C CONST(X'3B')
D F12 C CONST(X'3C')
D F13 C CONST(X'B1')
D F14 C CONST(X'B2')
D F15 C CONST(X'B3')
D F16 C CONST(X'B4')
D F17 C CONST(X'B5')
D F18 C CONST(X'B6')
D F19 C CONST(X'B7')
D F20 C CONST(X'B8')
D F21 C CONST(X'B9')
D F22 C CONST(X'BA')
D F23 C CONST(X'BB')
D F24 C CONST(X'BC')
D CLEAR C CONST(X'BD')
D ENTER C CONST(X'F1')
D HELP C CONST(X'F3')
D ROLLDN C CONST(X'F4')
D ROLLUP C CONST(X'F5')
D PRINT C CONST(X'F6')
D RCBKSP C CONST(X'F8')
D AUTENT C CONST(X'3F')
D WSDS DS
D functionKey 369 369
END
166
RPG-ILE LABS
Listing :-
FDStestF cf e workstn
c Exfmt R1
c If *inka = *on
c 'KA on !' dsply
c Endif
c
c If *inkb = *on
c 'KB on !' dsply
c Endif
c eval *inlr = *on
The display file DSTestF has CA01(01) and CA02(02) at the file level.
When user presses F1, the corresponding indicator KA is switched on.Similarly for F2
and KB.
END
167
RPG-ILE LABS
First Give A CHECK or RANGE condition for validation, then follow that by a
CHECKMSGID (<msg id> <lib>/<msg file name>)
First create a Message File called MSGF1 in SAM2 and add 2 messages with IDs MSG001
and MSG002.
A DSPSIZ(24 80 *DS3)
A R RVLD
A CA03(03)
A 5 17'ENTER A VALUE BETWEEN 100 & 200’
A 7 17'DATA : '
A FLD001 4S 0B 7 27COLOR(WHT)
A RANGE(100 200)
A CHKMSGID(MSG0001 SAM2/MSGF1)
A FLD002 1A B 11 18
RPGLE LISTING
FDSVLD CF E WORKSTN
C EXFMT RVLD
C SETON LR
C RETURN
LAB : ERRMSGId
FDSVLD CF E WORKSTN
C EXFMT RVLD
c* 10 corresp to
c* ERRMSGID
c*
c Eval *in10 = *on
C EXFMT RVLD
C SETON LR
C RETURN
A DSPSIZ(24 80 *DS3)
A R RVLD
A CA03(03)
A 517'ENTER A VALUE BETWEEN 100
A 617'OR BETWEEN 400 AND 500'
A 817'DATA : '
A FLD001 4S 0B 927COLOR(WHT)
A 10 ERRMSGID(MSG0002 *LIBL/MSGF1)
A FLD002 1A B 11 18
AS SETON 10 and EXFMT is done, the Error Message is loaded from the Message File and
displayed on the screen. The keyboard is locked and waits for Reset key to be
pressed.
168
RPG-ILE LABS
IN THE NEXT SCREEN SPECIFY THE FIRST DATA VARIABLE AS *CHAR WITH LEN 4 AND DEC POS 0
(!)
THE FOLLOWING CL PROGRAM WRITES RUN TIME VALUES INTO THE PRE-DEFINED MESSAGE.
:
PGM
DCL &N TYPE(*DEC) LEN(4 0) VALUE(123)
DCL &SN TYPE(*CHAR) LEN(4)
CHGVAR VAR(&SN) VALUE(&N)
SNDPGMMSG MSGID(MSG0003) MSGF(SAM2/MSGF1) MSGDTA(&SN)
ENDPGM
RPGLE EQIUIVALENT :
The Message MSG0003 has 1 variable field ( identified as &1 ) which was defined as
*CHAR with size 4 and dec pos 0 . here the RPGLE program specifies this message in
the CHKMSGID keyword. RPGLE makes sure that value of the variable CNTR is et to some
valid value before record format is displayed on the screen.
If you press + in the underline above, you can specify more fields.
A DSPSIZ(24 80 *DS3)
A R RVLD
A CA03(03)
A CNTR 4A P
A 5 17'ENTER A VALUE BETWEEN 100
A 6 17'OR BETWEEN 400 AND 500'
A 8 17'DATA : '
A FLD001 4S 0B 9 27COLOR(WHT)
169
RPG-ILE LABS
A RANGE(100 200)
A CHKMSGID(MSG0003 SAM2/MSGF1 &CNTR)
A FLD002 1A B 11 18
FDSVLD CF E WORKSTN
c EVAL CNTR='123'
C EXFMT RVLD
C
C SETON LR
C RETURN
Message details : Tried to put many variables into 1 message but wont work with
ERRMSGID. ERRMSGID can take ERRMSGID(MSG0099 MSGF1 &STR)
But not
ERRMSGID(MSG0099 MSGF1 &x &y &z)
ie ERRMSGID does not take more than 1 variables as values to the keyword.
I wanted to display something like this :
Message ID . . . . . . . . . : MSG0099
Message file . . . . . . . . : MSGF1
Library . . . . . . . . . : SAM2
Decimal
Field Data Type Length Positions
&1 *CHAR 75
this message contains no text only 1 variable : &1 which I s*CHAR and 75 in length
(roughly 1 row )
What ever u wish to write as a message is dumped into this variable.
The message is displayed via ERRMSGID as seen clearly in the following display file
listing :
A DSPSIZ(24 80 *DS3)
A R RVLD
A CA03(03)
A STR 75A P
A 8 17'DATA : '
A FLD001 4S 0B 9 27COLOR(WHT)
A 10 ERRMSGID(MSG0099 MSGF1 &STR)
A FLD002 1A B 11 18
RPGLE program :
170
RPG-ILE LABS
FDSVLD CF E WORKSTN
DN1 S 4S 0 INZ(122)
DN2 S 4S 0 INZ(16)
DTOTAL s 7s 0 inz(0)
DSN1 s 4a
DSN2 s 4a
DSTOTAL s 7a
d*
c EVAL TOTAL = N1 + N2
C Movel Total sTotal
C Movel N1 sN1
C Movel N2 sN2
c Eval Str = 'A = ' + SN1 + ' B = ' + SN2 + ' .'
c + 'Their Sum : ' + STotal
C EXFMT RVLD
C Eval *in10 = *ON
C EXFMT RVLD
C SETON LR
C RETURN
STR is a program to system variable which is passed to the MSG0099. RPGLE program
writes suitable text into this STR string and sets ON indicator 10. In the next WRITE
operation, the message is displayed on the screen. The message goes when RESET (left
CTRL key) is pressed.
* * *
171
RPG-ILE LABS
DArg1 s 4s 0 inz(-2)
DArg2 s 4s 0 inz(0)
DRslt s 4s 0 inz(0)
D
D
D SDS
D* ---------------------------------------
D* FOR PROCEDURE NAME/PROG NAME
D* YOU CAN SPECIFY EITHER 1 TO 10 OR *PROC
D* ---------------------------------------
DPGMNAM *PROC
DSTS *STATUS
DSRCLIN 21 28
DNUMPAR 37 39
DEXCTYP 40 42
DEXCNUM 43 46
DLIBNAM 81 90
DSRCFNAM 304 313
DSRCLIB 314 323
DSRCMEM 324 333
DPRONAM 334 343
DMODNAM 344 353
c
c 'aaa' Dsply
c Eval Rslt = Arg1/Arg2
c cnt1 Tag
c 'bbb' Dsply
c Eval *inlr = *on
c Return
c
c *PSSR Begsr
C PGMNAM DSPLY
C STS DSPLY
C PGMNAM DSPLY
C STS DSPLY
C SRCLIN DSPLY
C NUMPAR DSPLY
C EXCTYP DSPLY
C EXCNUM DSPLY
C LIBNAM DSPLY
C SRCFNAM DSPLY
C SRCLIB DSPLY
C SRCMEM DSPLY
C PRONAM DSPLY
C MODNAM DSPLY
c Goto cnt1
C Endsr
172
RPG-ILE LABS
DIV by ZERO
And
SQRT of a NEGATIVE NUMBER
DErrNum s 6s 0 inz(0)
DArg1 s 6s 0 inz(-4)
DArg2 s 6s 0 inz(0)
DRslt s 6s 0 inz(0)
DSErrNum s 6a
D
D
D SDS
D* ---------------------------------------
D* FOR PROCEDURE NAME/PROG NAME
D* YOU CAN SPECIFY EITHER 1 TO 10 OR *PROC
D* ---------------------------------------
DPGMNAM *PROC
DSTS *STATUS
DSRCLIN 21 28
DEXCTYP 40 42
DEXCNUM 43 46
c
c '1.' Dsply
c Eval Rslt = Arg1/Arg2
c cnt1 Tag
c '2. ' Dsply
c SQRT Arg1 Rslt
c cnt2 Tag
c '---------' Dsply
c Eval *inlr = *on
c Return
c
c *PSSR Begsr
C STS DSPLY
C SRCLIN DSPLY
C EXCTYP DSPLY
C EXCNUM DSPLY
c Select
c When SrcLin='00000020'
c Goto Cnt1
c When SrcLin='00000023'
c Goto Cnt2
c EndSl
c EndSR
173
RPG-ILE LABS
OUTPUT :
DSPLY 1.
DSPLY 102
DSPLY 00000020
DSPLY MCH
DSPLY 1211
DSPLY 2.
DSPLY 101
DSPLY 00000023
DSPLY RNX
DSPLY 0101
DSPLY ---------
H DatFmt(*DMY)
D*
D* Mydate is an impossible date
D* ----------------------------
DMydate S 6s 0 INZ(310204)
DMyDate1 s D inz(D'12/04/04')
D
D
D SDS
D* ---------------------------------------
DSTS *STATUS
DSRCLIN 21 28
DEXCTYP 40 42
DEXCNUM 43 46
c
c
c* This data area does not Exist
c* -----------------------------
c
C *DTAARA DEFINE DataArea1 5
c
c
c '1.' Dsply
c *DMY Move MyDate MyDate1
c cnt1 Tag
c '2. ' Dsply
c Call 'NoExist'
c cnt2 Tag
c '3.' Dsply
c *LOCK IN DataArea1
c OUT DataArea1
c UnLock Dataarea1
c cnt3 Tag
c Eval *inlr = *on
c Return
c
c *PSSR Begsr
C STS DSPLY
C SRCLIN DSPLY
C EXCTYP DSPLY
C EXCNUM DSPLY
c Select
c When SrcLin='00000024'
c Goto Cnt1
174
RPG-ILE LABS
c When SrcLin='00000027'
c Goto Cnt2
c When SrcLin='00000030'
c Goto Cnt3
c EndSl
c EndSR
OUTPUT :
DSPLY 1.
DSPLY 112
DSPLY 00000024
DSPLY RNX
DSPLY 0112
DSPLY 2.
DSPLY 211
DSPLY 00000027
DSPLY MCH
DSPLY 3401
DSPLY 3.
DSPLY 401
DSPLY 00000030
DSPLY CPF
DSPLY 1015
Following program creates error condition by tring to open a file twice.Proggram also
illustrates how the error can be corrected.
175
RPG-ILE LABS
DIsOpn 9 9
DIsEOF 10 10
DStatus 11 15 0
DOpCode 16 21
DMsgNbr 46 52
c*
c* ------------------------------------------
C 'OPEN NOW...' DSPLY
C Open pfBMAST 77
C If *IN77
C 'CANNOT OPEN' DSPLY
C Eval *inlr = *on
C Return
C Endif
C* ----------------------------------------------
c* Try to open again. Will obviously Fail.
c* ----------------------------------------------
C Open pfBMAST 77
c If *in77 = *on
c EXSR srBMAST
c Select
c When Status=1215
c* Attempt to open twice
c Eval Msg = 'Attempt made to open a file twice
c + ' Problem corrected.'
c Msg Dsply
c* More such WHEN statements ...
c*
c Endsl
c Endif
C '----------' Dsply
c* Perform Mandatory READ
c Read BM 55
c* Do some database
c* processing here...
c*
C Close pfBMAST
C Eval *inlr=*on
C Return
C
C srBMAST Begsr
C 'IsOpen ?' Dsply
c IsOpn Dsply
c 'Is EOF ?' Dsply
c IsEOF Dsply
c 'Status :' Dsply
c Status Dsply
c 'Op code :' Dsply
c opCode Dsply
c 'Message :' Dsply
c MsgNbr dsply
c ENDSR
OUTPUT :
176
RPG-ILE LABS
DSPLY Status :
DSPLY 1215
DSPLY Op code :
DSPLY OPEN F
DSPLY Message :
DSPLY
DSPLY Attempt made to open a file twice. Problem corrected.
SAM3 locks the PFBMAST for exclusive access. SAM2 tries to open it in Update mode.
Attempt fails : STATUS code is 1271 : Attempt to access a locked object.
SAM3’s program :
PGM
/* LOCK THE PFBMAST FILE TOTALLY. LET NO ONE OPEN */
OVRDBF FILE(PFBMAST) RCDFMTLCK((BM *EXCL)) +
OVRSCOPE(*JOB)
OPNDBF FILE(SAM2/PFBMAST) OPTION(*ALL) OPNSCOPE(*JOB)
/* WAIT TILL USER PRESSES ENTER KEY */
SNDPGMMSG MSG('record locked') TOPGMQ(*EXT)
CLOF OPNID(PFBMAST)
DLTOVR FILE(PFBMAST) LVL(*JOB)
ENDPGM
SAM2’s Program :
177
RPG-ILE LABS
C Close pfBMAST
C Eval *inlr=*on
C Return
OUTPUT :
SAM3 locks PFBMAST as *SHRRD. SAM2 tries to open the file in the mean tim ein update
mode. This is what happens : SAM2 opens it successfully !
SAM3’s program :
PGM
/* LOCK THE PFBMAST FILE TOTALLY. LET NO ONE OPEN */
OVRDBF FILE(PFBMAST) RCDFMTLCK((BM *SHRRD)) +
OVRSCOPE(*JOB)
OPNDBF FILE(SAM2/PFBMAST) OPTION(*ALL) OPNSCOPE(*JOB)
/* WAIT TILL USER PRESSES ENTER KEY */
SNDPGMMSG MSG('SHARE READ ') TOPGMQ(*EXT)
CLOF OPNID(PFBMAST)
DLTOVR FILE(PFBMAST) LVL(*JOB)
ENDPGM
SAM2 ‘s program :
178
RPG-ILE LABS
SAM3 locks the file first. SAM2 can access the file in *UPDATE mode.
SAM3 locks PF with *SHRNUP : SAM2 tries to open file in UPDATE Mode.
OUTPUT :
DSPLY OPEN NOW...
DSPLY CANNOT OPEN
DSPLY 1217
Result :
Code of sam3 :
CLlock :
PGM
/* LOCK THE PFBMAST FILE TOTALLY. LET NO ONE OPEN */
OVRDBF FILE(PFBMAST) RCDFMTLCK((BM *EXCL )) +
OVRSCOPE(*JOB)
/* CALL RPFIDS3 WHICH READS PFBMAST IN UPDATE MODE*/
CALL RPFIDS3
DLTOVR FILE(PFBMAST) LVL(*JOB)
ENDPGM
179
RPG-ILE LABS
d*
DDsBMast DS
DIsEOF 10 10
DStatus 11 15 0
DOpCode 16 21
DMsgNbr 46 52
c*
c* ------------------------------------------
C 'OPEN NOW...' DSPLY
C Open pfBMAST 77
C If *IN77
C 'CANNOT OPEN' DSPLY
c status dsply
C Eval *inlr = *on
C Return
c Endif
c Read BM 55
c* Do some database
c* processing here...
c 'ENDING' DSPLY
C Close pfBMAST
C Eval *inlr=*on
C Return
SAM2’s program :
Sam3’s screen :
180
RPG-ILE LABS
Sam2’s screen : (for both modes : READ FOR Update as well as READ FOR Input)
In the same job, at the same level, a program can open a Exclusively locked file :
PGM
/* LOCK THE PFBMAST FILE TOTALLY. LET NO ONE OPEN */
OVRDBF FILE(PFBMAST) RCDFMTLCK((BM *EXCL)) +
OVRSCOPE(*JOB) SHARE(*NO)
OPNDBF FILE(SAM2/PFBMAST) OPTION(*INP) OPNID(I4) +
OPNSCOPE(*JOB)
/* CALL RPFIDS3 WHICH READS PFBMAST IN UPDATE MODE*/
CALL RPFIDS3
CLOF OPNID(I4)
DLTOVR FILE(PFBMAST) LVL(*JOB)
ENDPGM
LAB : Locking excl in sam3a activation group and then opening a file in update mode
in sam3b act grp is possible
PGM
/* LOCK THE PFBMAST FILE TOTALLY. LET NO ONE OPEN */
OVRDBF FILE(PFBMAST) RCDFMTLCK((BM *EXCL)) +
SECURE(*YES) OVRSCOPE(*ACTGRPDFN) SHARE(*NO)
OPNDBF FILE(SAM2/PFBMAST) OPTION(*INP) OPNID(I4) +
OPNSCOPE(*ACTGRPDFN)
/* CALL RPFIDS3 WHICH READS PFBMAST IN UPDATE MODE*/
CALL RPFIDS3
CLOF OPNID(I4)
DLTOVR FILE(PFBMAST) LVL(*ACTGRPDFN)
ENDPGM
A program tries to read for update, if the READ fails, displays the error (satus
code)
If RPGFIDS3 is started first, it opens the PFBMAST in update mode. A READ operation
is performed. This is READ FOR UPDATE since the open mode was UPDATE.
Now that a READ for UPDATE has bnen done,the record is locked.
181
RPG-ILE LABS
At this time of RPFIDS2 is started, it may open the file in Update mode (since we
have not enabled any object level locking, the database file is for anyone to use and
open in any mode as desired) The RPFIDS2 has no problems opening thie file, but when
it tries to read this fie (READ FOR UPDATE) it cannot because the first record is
already locked by RPFIDS3.
Had RPFIDS2 tried to read the second or any other record (apart from rec 1) it would
have succeeded. The first record is locked by RPFIDS3.
The lock is released only when RPFIDS3 does an explicit UNLOCK operation or reads
another record for update.
RPFIDS2 opened the file in update mode but could not read record #1. It waited 60
secs (record wait time) and then switched on the indicator in the LO section.
We check state of this indicator and display the STATUS value which comes out to be
1218 !
182
RPG-ILE LABS
C Close pfBMAST
C Eval *inlr=*on
C Return
RPFIDS2 will have no problems opening the file in Input mode.In the input mode the
READ opcode causes a READ FOR INQUIRY that does not lock a record.
Program RPFIDS2 tries to perform a READ for Update for 3 times, if all 3 attempts
fail, it does a read for inquiry and display data in the record.
When RPFIDS2 is doing all this, RPFIDS3 has already locked the first record of the
PFBMAST with a READ for UPDATE.
Code for RPFIDS3 remains the same : opens PFMAST in Update mode and reads the first
record as READ for UPDATE. Then it stops with something displaed using DSPLY.
183
RPG-ILE LABS
DOpCode 16 21
DMsgNbr 46 52
c*
c* ------------------------------------------
C 'OPEN NOW...' DSPLY
C Open pfBMAST 77
C If *IN77
C 'CANNOT OPEN' DSPLY
c status dsply
C Eval *inlr = *on
c Return
c Endif
c Eval *in66 = '1'
c* This loop goes on till atleast 1 successful
c* READ operation is done.
c*
c dow *in66 = '1'
c Read BM 6655
c* will wait 60 seconds
c* If record still not available
c* will switch on 66
c*
C If *IN66
C 'CANNOT read' DSPLY
c status dsply
c Iter
c else
c* Do some database
c* processing here...
c 'RPFIDS 2' dsply
c bcode dsply
c bname dsply
c bprice dsply
c endif
c enddo
c 'ENDING 2' DSPLY
c
C Close pfBMAST
C Eval *inlr=*on
C Return
OUTPUT of RPFIDS2:
PGM
/* LOCK THE PFBMAST FILE TOTALLY. LET NO ONE OPEN */
ALCOBJ OBJ((SAM2/PFBMAST *FILE *EXCL *FIRST)) WAIT(5)
SNDPGMMSG MSG('Object is Alocated *EXCL.') TOPGMQ(*EXT)
DLCOBJ OBJ((SAM2/PFBMAST *FILE *EXCL PFBMAST))
ENDPGM
184
RPG-ILE LABS
SAM2 runs the following program shortly after SAm3 ran his program :
185
RPG-ILE LABS
ALCOBJ can be used for all Modes : *EXCL, *SHRRD, *SHRUP, *SHRNUP.
Opens pfbmast in Update mode and reads first record and stops with a DSPLY. Thus the
first record is effectively locked.
OUTPUT :
Run RPFIDS2 first. When it displays “Will DLT now”, run RPFIDS3. RPFIDS3 reads first
record in the PFBMAST and shows bcode value.Keep RPFIDS3 just at this point and press
186
RPG-ILE LABS
enter to continue running RPFIDS2. Now RPFIDS2 tries to DELETE record #1 but cannot
since RPFIDS3 has locked it. This the 77 indicator of the DELETE opcode becomes ON.
Display the Value of Status which comes out to be 1221 (unable to DELETE !)
OUTPUT :
187
RPG-ILE LABS
Following program tries to load duplicate record. BCODE has a Primarky Key constraint
and hence the WRITE operation fails. The status code is displayed.
COUTION : The BKMAST2 file must be Journaled before the following program can run.
Listing :
Record cannot be written since 1 record already has this BCODE value.
STATUS CODE : 1215
188
RPG-ILE LABS
F*fBMAST2 IF E DISK
FpfTRANs UF A E DISK Prefix(x:1) INFDS(dstrans) USROPN
dDSTRANS DS
dStatus *status
f*
f* PfTran has fields with the same name as in PFBMAST.
f* If you use prefix for pfTRAN, all fields and record format also
f* can be referenced by replaceing their first letter by x. For
f* example, a field in BTrans is BCode.It becomes xCode.
f*
c
c Open PFTRANS
c
c Read BTrans 55
c* put a invalid value for xcode. there is no book inthe Book Master
c* table with this name. Since the 2 tables are linked by referential
c* Integrity, the record cannot be written to BTrans
c* -------------------------------------------------
c Eval xcode = 7777
c Eval xQty= 7777
c Eval xMode = 'I'
c*
c* WRITE operation will fails.
c* Hence use indicator in LO indicator.
c*
c Write BTrans 77
c If *in77 = *on
c* error inwrite
c 'cannot write'Dsply
c Status Dsply
c Eval *in77 = *off
c Endif
c
c
c Close PFTRANS
c Eval *inlr = *on
c Return
OUTPUT :
Database file :
A UNIQUE(*EXCNULL)
A R BM
A BCODE 4S 0 ALWNULL
A BNAME 30A
A BPRICE 7S 2
A K BCODE
189
RPG-ILE LABS
Program Write 1 Null to BCODE and XML to BNAME. Then it reads all records form start
and disdplays records where BCODe is NULL.
Listing :
c If %NullInd(BCode)
This line checks if Value of BCOde for currently read record is Null or Not. If it IS
null, the %NULLIND function returns a TRUE.
OUTPUT :
190
RPG-ILE LABS
DSPLY Null !
DSPLY name1
DSPLY Null !
DSPLY name1
DSPLY Null !
DSPLY XML
DSPLY Null !
DSPLY XML
During compilation you get following errors /warnings if *USRCTL is not specified for
BCODE :
191
RPG-ILE LABS
Use CRTPF to create a flat physical file. Don’t specify the source PF or member name.
Only specify the record format length, and press ENTER.
192
RPG-ILE LABS
The Physical file PFMEM has 3 members : PFMEM , JAN and FEB
ODP
193
RPG-ILE LABS
ENBEDDED SQL :
LAB : Embedded SQL : basics
dnCode s 4s 0 inz(0)
dnTemp s 7s 2 inz(45.00)
d
d
d* I have made sure that only 1 record is returned.
d*
d*
c/EXEC SQL
c+ Select bcode into :nCode from pfbmast where
c+ bprice = :nTemp
c/END-EXEC
c nCode Dsply
c Eval *inlr = *on
c Return
c*
c*
NOTES :
dnCode s 4s 0 inz(0)
dsName s 10a
dnTemp s 7s 2 inz(45.00)
d
d
c/EXEC SQL
c+ DECLARE C1 Cursor For select bcode,bname from pfbmast
c+ where bcode IS NULL
c/END-EXEC
c/EXEC SQL
c+ Open C1
c/END-EXEC
c
c* Start reading the data
c* ----------------------
c Dow '1'
c/EXEC SQL
c+ Fetch from C1 into :nCode,:sName
c/END-EXEC
c*-
c If SQLCOD = 100
c Leave
c Endif
c*--
c
c nCode Dsply
c sName Dsply
c Enddo
c
c* -------Now close the cursor ----------
194
RPG-ILE LABS
c/EXEC SQL
c+ Close C1
c/END-EXEC
c Eval *inlr = *on
c Return
c*
c*
Accept the relative position from the current cursor pointer position and display the
record. If too high a relative position is specified, the SQLCOD is set to 100
(position exceeeds the last record in the cursor) The pointer remains at the current
record.
Relative works this way : Suppose of cursor pointer position is rec #4. If you
specify RELATIVE :n where n is 2, the pointer goes like : 5,6 and stops at 6 since
that is the second record from the 4th record. IF you specify Relative :n where nis –
2, the pointer goes back 2 records ie. To the second record.
Listing :
dnCode s 4s 0 inz(0)
dsName s 10a
dnRecNum s 4s 0 inz(-2)
d
d
c/EXEC SQL
c+ DECLARE C1 scroll Cursor For select bcode,bname from pfbmast
c+ where bcode <110
c/END-EXEC
c/EXEC SQL
c+ Open C1
c/END-EXEC
c
c* Start reading the data
c* ----------------------
c Dow '1'
c/EXEC SQL
c+ Fetch relative :nRecNum from C1 into :nCode,:sName
c/END-EXEC
c*--
c
c nCode Dsply
c sName Dsply
c SqlCod Dsply
c SqlWrn Dsply
c 'Pos :(0:End)'Dsply nRecNum
c If nRecNum = 0
c Leave
c Endif
c
c Enddo
c
c* -------Now close the cursor ----------
c/EXEC SQL
c+ Close C1
c/END-EXEC
c Eval *inlr = *on
195
RPG-ILE LABS
c Return
c*
c*
OUTPUT :
DSPLY 108
DSPLY EXCEL
DSPLY 100
DSPLY
DSPLY Pos :(0:End) 2
1
DSPLY 108
DSPLY EXCEL
DSPLY 100
DSPLY
DSPLY Pos :(0:End) 1
Program displays the first record in the cursor (which contains all records). It asks
for position and sets pointer to that position. Actually, it asks if the current
record is to be updateed or not before positioning to the requested record. After
updating , it points to the new record requested.
dnCode s 4s 0 inz(0)
dsName s 10a
dnRecNum s 4s 0 inz(1)
dsDecide s 1a inz('n')
d
d
c/EXEC SQL
c+ DECLARE C1 DYNAMIC scroll Cursor For select bcode,bname
c+ from pfbmast
c/END-EXEC
c/EXEC SQL
c+ Open C1
c/END-EXEC
c
c* Start reading the data
c* ----------------------
c Dow '1'
c/EXEC SQL
c+ Fetch relative :nRecNum from C1 into :nCode,:sName
c/END-EXEC
c*--
c 'DATA READ :-'Dsply
c nCode Dsply
c sName Dsply
c 'Code/Warn :' Dsply
c SqlCod Dsply
c SqlWrn Dsply
196
RPG-ILE LABS
Output :
LAB : Error Handling : watching values of SQLCOD and SQLERR for insert/update errors
In the following program, the first iteration of the DOW loop tries to load 120value
into to the BCODE field. This violates PK constraint on the BKMAST since oen of the
records already has BCODE as 120. Study the values of SQLCOD and SQLERR :
dnCode s 4s 0 inz(120)
dsName s 10a
dnPrice s 7s 2 inz(100)
dsDecide s 1a inz('n')
dnTemp s 7s 2 inz(45.00)
dCntr s 4s 0 inz(0)
d* ----------------------------------------------------------------------
D* SQL Communications area :automatically added,hence I commented it out.
d* ----------------------------------------------------------------------
D*SQLCA DS
D* SQLAID 1 8A
D* SQLABC 9 12B 0
D* SQLCOD 13 16B 0
D* SQLERL 17 18B 0
D* SQLERM 19 88A
197
RPG-ILE LABS
D* SQLERP 89 96A
D* SQLERRD 97 120B 0 DIM(6)
D* SQLERR 97 120A
D* SQLER1 97 100B 0
D* SQLER2 101 104B 0
D* SQLER3 105 108B 0
D* SQLER4 109 112B 0
D* SQLER5 113 116B 0
D* SQLER6 117 120B 0
D* SQLWRN 121 131A
D* SQLWN0 121 121A
D* SQLWN1 122 122A
D* SQLWN2 123 123A
D* SQLWN3 124 124A
D* SQLWN4 125 125A
D* SQLWN5 126 126A
D* SQLWN6 127 127A
D* SQLWN7 128 128A
D* SQLWN8 129 129A
D* SQLWN9 130 130A
D* SQLWNA 131 131A
D* SQLSTT 132 136A
c
c
c Dow '1'
c/EXEC SQL
c+ Insert into pfbmast values (:nCode,:sName,:nPrice)
c/END-EXEC
c*-
c 'Code :' Dsply
c nCode Dsply
c 'Price :' dsply
c nPrice Dsply
c 'sqlcod' Dsply
c sqlcod Dsply
c*--
c 'sqlerr' Dsply
c sqlerr Dsply
c*--
c 'sqlwrn' Dsply
c sqlwrn Dsply
c*--
c 'sqlwn0' Dsply
c sqlwn0 Dsply
c*--
c Eval nPrice = nPrice * 2
c Eval nCode = nCode - 1
c 'Exit ?' Dsply sDecide
c If sDecide = 'y' OR sDecide = 'Y'
Leave
c Endif
c Enddo
c
c Eval *inlr = *on
c Return
c*
c*
198
RPG-ILE LABS
DSPLY Code :
DSPLY 120
DSPLY Price :
DSPLY 10000 This is actually 100.00
DSPLY sqlcod
DSPLY 803-
DSPLY sqlerr
DSPLY 50345009
DSPLY sqlwrn
DSPLY
DSPLY sqlwn0
DSPLY
DSPLY Exit ? n
DSPLY Code :
DSPLY 119
DSPLY Price :
DSPLY 20000
DSPLY sqlcod
DSPLY 0
DSPLY sqlerr
DSPLY 7956
DSPLY sqlwrn
DSPLY
DSPLY sqlwn0
DSPLY
DSPLY Exit ? n
199
RPG-ILE LABS
LAB : QCMDEXC
dStrCommand s 7a inz('WRKSPLF')
dCmdLen s 15p 5 inz(7)
c call 'QCMDEXC'
c Parm StrCommand
c Parm CmdLen
c 'Done' dsply
c Eval *inlr = *on
c Return
200
RPG-ILE LABS
PAGE : 253
ADDITIONS TO THE MAIN COVERAGE BEGIN HERE (ADDILE5 )
LAB : Work in VARSIZE (passign a pramater lesser than expected size as a prameter to procedure)
201
RPG-ILE LABS
LAB :
/free
DateDue = %date (DUEDATE: *ISO);
DaysLate = %diff (CurDate: DateDue: *d);
LAB :
D CharToNum PI 30P 9
D string 100A CONST VARYING
D decComma 2A CONST OPTIONS(*NOPASS)
D currency 1A CONST OPTIONS(*NOPASS)
/free
// override defaults if optional parameters were passed
if %parms > 1;
decPoint = %subst(decComma : 1 : 1);
comma = %subst(decComma : 2 :1);
endif;
if %parms > 2;
cursym = currency;
endif;
// initialization
len = %len(string);
// begin reading the integer part
pNumPart = %addr(intPart);
// loop through characters
for i = 1 to len;
c = %subst(string : i : 1);
select;
// ignore blanks, digit separator, currency symbol
when c = comma or c = *blank or c = cursym;
iter;
// decimal point: switch to reading the decimal part
when c = decPoint;
pNumPart = %addr(decPart);
iter;
// sign: remember the most recent sign
when c = '+' or c = '-';
sign = c;
iter;
// more signs: cr, CR, () are all negative signs
when c = 'C' or c = 'R' or
c = 'c' or c = 'r' or
c = '(' or c = ')';
sign = '-';
iter;
// a digit: add it to the current build area
other;
eval numPart = numPart + c;
endsl;
endfor;
// copy the digit strings into the correct positions in the
// zoned variable, using the character overlay
202
RPG-ILE LABS
LAB :
LAB : Embeded SQL code in ILE program to be convered to Module and Bound to main line module
using : CRTPGM and CGTBNGRPG (see page 80 of ilerpg)
You can control the spacing and pagination of the compiler listing through the use
of the /EJECT and /SPACE compiler directives. The /EJECT directive forces a
page break. The /SPACE directive controls line spacing within the listing. For more
information on these directives refer to the ILE RPG Reference.
LAB : A status Module that contains error data structure. Any module / procedure hasa problem, it
updates the data structure. This is useful when a second procedure wishes to see the resultts of
execution of the last procedure.
LAB : Running 2 programs in same actgrp and in commitment env. If 1 commits, can the other
rollback ?
LAB : Running 2 programs in same actgrp and in commitment env. If 1 program reads a rec, can
some other job access the record ? (is it locked ? )
LAB : 2 Modules export procedure of the same name, it that OK ? If a client calls the procedure,
which one will be called ?
203
RPG-ILE LABS
LAB : A main line program declares a global int i. A bound module exports an int i. The main line
module get which I ? the imported one or the local one ?
LAB : Debugging a LE program that uses /COPY to include external source code fragments
To change the
optimization level of a program, use the CHGPGM command.
LAB : observability
Removing Observability
Observability involves the kinds of data that can be stored with an object, and that
allow the object to be changed without recompiling the source. The addition of this
data increases the size of the object. Consequently, you may want to remove the
data in order to reduce object size. But once the data is removed, observability is
also removed. You must recompile the source and recreate the program to replace
the data. The types of data are:
Create Data Represented by the *CRTDTA value. This data is necessary to
translate the code to machine instructions. The object must have
this data before you can change the optimization level.
Debug Data Represented by the *DBGDTA value. This data is necessary to
allow an object to be debugged.
Profiling Data Represented by the *BLKORD and *PRCORD values. This data is
necessary to allow the system to re-apply block order and
procedure order profiling data.
Use the CHGPGM command or the CHGMOD command to remove some or all
the data from a program or module respectively. Removing all observability
reduces an object to its minimum size (without compression). It is not possible to
change the object in any way unless you re-create it. Therefore, ensure that you
86 ILE RPG Programmer’s Guide
have all source required to create the program or have a comparable program
object with CRTDATA. To re-create it, you must have authorization to access the
source code.
Reducing an Object’s Size
The create data (*CRTDTA) associated with an ILE program or module may make
up more than half of the object’s size. By removing or compressing this data, you
will reduce the secondary storage requirements for your programs significantly.
Changing a Module or Program
Page 105
204
RPG-ILE LABS
*=================================================================*
* CvtToHex - convert input string to hex output string
*=================================================================*
H COPYRIGHT('(C) Copyright MyCompany 1995')
D/COPY RPGGUIDE/QRPGLE,CVTHEXPR
*-----------------------------------------------------------------*
* Main entry parameters
* 1. Input: string character(n)
* 2. Output: hex string character(2 * n)
*-----------------------------------------------------------------*
D CvtToHex PI OPDESC
D InString 16383 CONST OPTIONS(*VARSIZE)
D HexString 32766 OPTIONS(*VARSIZE)
*-----------------------------------------------------------------*
* Prototype for CEEDOD (Retrieve operational descriptor)
*-----------------------------------------------------------------*
D CEEDOD PR
D ParmNum 10I 0 CONST
D 10I 0
D 10I 0
D 10I 0
D 10I 0
D 10I 0
D 12A OPTIONS(*OMIT)
* Parameters passed to CEEDOD
D DescType S 10I 0
205
RPG-ILE LABS
D DataType S 10I 0
D DescInfo1 S 10I 0
D DescInfo2 S 10I 0
D InLen S 10I 0
D HexLen S 10I 0
*-----------------------------------------------------------------*
* Other fields used by the program *
*-----------------------------------------------------------------*
D HexDigits C CONST('0123456789ABCDEF')
D IntDs DS
D IntNum 5I 0 INZ(0)
D IntChar 1 OVERLAY(IntNum:2)
D HexDs DS
D HexC1 1
D HexC2 1
D InChar S 1
D Pos S 5P 0
D HexPos S 5P 0
Figure 42. Source for Service Program CvtToHex (Part 1 of 2)
Chapter 8. Creating a Service Program 93
*-----------------------------------------------------------------*
* Use the operational descriptors to determine the lengths of *
* the parameters that were passed. *
*-----------------------------------------------------------------*
C CALLP CEEDOD(1 : DescType : DataType :
C DescInfo1 : DescInfo2: Inlen :
C *OMIT)
C CALLP CEEDOD(2 : DescType : DataType :
C DescInfo1 : DescInfo2: HexLen :
C *OMIT)
*-----------------------------------------------------------------*
* Determine the length to handle (minimum of the input length *
* and half of the hex length) *
*-----------------------------------------------------------------*
C IFInLen > HexLen / 2
C EVAL InLen = HexLen / 2
C ENDIF
*-----------------------------------------------------------------*
* For each character in the input string, convert to a 2-byte *
* hexadecimal representation (for example, '5' --> 'F5') *
*-----------------------------------------------------------------*
C EVAL HexPos = 1
C DO InLen Pos
C EVAL InChar = %SUBST(InString : Pos :1)
C EXSR GetHex
C EVAL %SUBST(HexString : HexPos : 2) = HexDs
C EVAL HexPos = HexPos + 2
C ENDDO
*-----------------------------------------------------------------*
* Done; return to caller. *
*-----------------------------------------------------------------*
C RETURN
*=================================================================*
* GetHex - subroutine to convert 'InChar' to 'HexDs' *
**
* Use division by 16 to separate the two hexadecimal digits. *
* The quotient is the first digit, the remainder is the second. *
*=================================================================*
C GetHex BEGSR
C EVAL IntChar = InChar
C IntNum DIV 16 X1 5 0
C MVR X2 5 0
*-----------------------------------------------------------------*
* Use the hexadecimal digit (plus 1) to substring the list of *
* hexadecimal characters '012...CDEF'. *
*-----------------------------------------------------------------*
206
RPG-ILE LABS
Use the Change Job (CHGJOB) command (or other CL job command) to indicate
that your job uses the reply list for inquiry messages. To do this, you should
specify *SYSRPYL for the Inquiry Message Reply (INQMSGRPY) attribute.
The reply list is only used when an inquiry message is sent by a job that has the
Inquiry Message Reply (INQMSGRPY) attribute specified as
INQMSGRPY(*SYSRPYL). The INQMSGRPY parameter occurs on the following CL
commands:
v Change Job (CHGJOB)
v Change Job Description (CHGJOBD)
v Create Job Description (CRTJOBD)
v Submit Job (SBMJOB).
You can also use the Work with Reply List Entry (WRKRPYLE) command to
change or remove entries in the system reply list. For details of the ADDRPYLE
and WRKRPYLE commands, see the CL and APIs section of
207
RPG-ILE LABS
Isthis why a parent program uses FREE opcode ? to free the resources of a child that ended
normally without setting On the LR ?
When a program does not do a seton lr and ends, and suppose it runs in a named act grp, then the
files opened by the program remain open. Do RCLRSC (mostly) to close files or do a RCLACTGRP to
delete the act grp : this cleans up any resources loced up and closes open files.
d
LAB : RCLRSC
For ILE programs associated with a named activation group, the RCLRSC
command has no effect. You must use the RCLACTGRP command to free resources
in a named activation group.
LAB :
208
RPG-ILE LABS
209
RPG-ILE LABS
You can prevent database files in production libraries from being modified
unintentionally by using one of the following commands:
v Use the Start Debug (STRDBG) command and retain the default *NO for the
UPDPROD parameter
LAB :
LAB :
LAB :
LAB :
LAB :
LAB :
LAB :
LAB :
LAB :
LAB :
LAB :
LAB :
210
RPG-ILE LABS
LAB :
LAB :
LAB :
LAB :
LAB :
LAB :
LAB :
LAB :
LAB :
LAB :
LAB :
LAB :
LAB : Compiler listing as a very useful source of documentation (esp for program
maintenance).
Specify debugging and line no options in the compiler commandoptions toinclude all
them in the compiler listing.
SEE PAGE 89
LAB : Debugging : All options of debugging views etc. to get most out of debugger.
Debug commands.
Lab : page 89
Both the CRTBNDRPG and CRTRPGMOD (see “Using the CRTRPGMOD
Command” on page 74) commands create and update a data area with the status of
the last compilation. This data area is named RETURNCODE, is 400 characters
long, and is placed into library QTEMP.
211
RPG-ILE LABS
LISTING OF CL001 :
CALL RP01
CALL RP02
OUTPUT :
1
2
1
2
RP01 AND RP02 READ 2 RECORDS FROM FILE PFBM2. 9TYPICAL BCODE,BNAME BPRICE FILE)
OUTPUT SHOWS BCODES AS 1 2 1 2. THIS IS BECAUSE WHEN RP01 IS STARTED, IT OPENS THE
FILE PFBM2 AND SETS UP AN ODP. Reads 2 records and thus displays 1 2. RP01 ends and
closes the ODP. RP02 starts and sets up a new ODP. It does the same thing : reads 2
records and displays bcode : thus output is 1 2.
PGM
OVRDBF FILE(PFBM2) SECURE(*NO) OVRSCOPE(*CALLLVL) +
SHARE(*YES)
OPNDBF FILE(SAM2/PFBM2) OPTION(*ALL) OPNSCOPE(*ACTGRP)
SNDPGMMSG MSG('OUTPUT WHEN THE OVERRIDE WAS APPLIED ') +
TOPGMQ(*EXT)
CALL RP01
CALL RP02
CLOF OPNID(PFBM2)
DLTOVR FILE(PFBM2) LVL(*)
SNDPGMMSG MSG('______OVERRIDE REMOVE_______ ') +
TOPGMQ(*EXT)
CALL RP01
CALL RP02
ENDPGM
OUTPUT :
The ovrdbf specifies that file PFBM2 will be opened in the SHARE mode and that this
override is scoped to the CALL LEVEL. The currnet CL001 program sets up a call level.
All RPG programs called from this CL001 will run in that call level.
Scope of the the SHARE (*YES) is ACTGRPDFN level. Since all the programs will run in
the DEFAULT ACTIVATION group (they are RPG/400 programs) the ODP is shared by call
applications from this and higher call levels.
Thus RP01 RP02 and RP003 will share the ODP setup by the OPNDBF command.
Listing of RP01 :
FPFBM2 IF E DISK
C 'RP01' DSPLY
C READ BM 33
C BCODE DSPLY
C READ BM 33
C BCODE DSPLY
C CALL 'RP003'
C SETON LR
212
RPG-ILE LABS
Listing of RP003 :
FPFBM2 IF E DISK
C 'RP003' DSPLY
C READ BM 33
C BCODE DSPLY
C READ BM 33
C BCODE DSPLY
C SETON LR
Listing of RP02 :
FPFBM2 IF E DISK
C 'RP02' DSPLY
C READ BM 33
C BCODE DSPLY
C READ BM 33
C BCODE DSPLY
C SETON LR
Lab : CL001 calls the programs RP01,RP02 and RP01 calls RP003. CL001 also calls CL002
which sinply calls RP05 and RP06. CL002 does not say anything about override which
CL001 has setup an override at the activation group level.
Will override apply to the cl002 program ? all are running in the same activation
group.
YES
CL002 calls Rp05 and rp06 and shows that ODP is shared.
Listing of CL001 :-
PGM
OVRDBF FILE(PFBM2) SECURE(*NO) OVRSCOPE(*CALLLVL) +
SHARE(*YES)
OPNDBF FILE(SAM2/PFBM2) OPTION(*ALL) OPNSCOPE(*ACTGRP)
SNDPGMMSG MSG('OUTPUT WHEN THE OVERRIDE WAS APPLIED ') +
TOPGMQ(*EXT)
CALL RP01
CALL CL002
CALL RP02
CLOF OPNID(PFBM2)
DLTOVR FILE(PFBM2) LVL(*)
SNDPGMMSG MSG('______OVERRIDE REMOVE_______ ') +
TOPGMQ(*EXT)
CALL RP01
CALL RP02
ENDPGM
CL002 listing :
PGM
SNDPGMMSG MSG('CHILD CL002 PROGRAM STARTED. ') +
TOPGMQ(*EXT)
CALL RP01
CALL RP02
SNDPGMMSG MSG('______CL002 DONE_______ ') +
TOPGMQ(*EXT)
213
RPG-ILE LABS
ENDPGM
LAB : Override a OVERRIDE which was applied at the prevous call level.
Cl002 LISTING :
PGM
SNDPGMMSG MSG('CHILD CL002 PROGRAM STARTED.NO SHARING') +
TOPGMQ(*EXT)
OVRDBF FILE(PFBM2) SHARE(*NO) OPNSCOPE(*ACTGRPDFN)
CALL RP01
CALL RP02
SNDPGMMSG MSG('______CL002 DONE_______ ') +
TOPGMQ(*EXT)
DLTOVR FILE(PFBM2)
ENDPGM
CL002’S OVRDBF HAS NOT WORKED. THE FILE SHARE MODE STILL REMAINS *YES/
THEREFORE, RP01 AND RP02 (CALLED IN CL002) SHOWED THE RECORDS 56 AND 78 RATHER THAN 1
2 1 2 AS EXPECTED.
MAYBE CL002 WILL HAVE TO RUN IN ANOTHER ACTIVATION GROUP IN ODER TO GET A SEPARATE
ODP. SINCE CL002 IS A CHILD OF CL001 WHICH ALREADY IMPLEMENTED AN OVERRIDE SCOPED TO
THE ACTGRPLEVEL, CL002 COMES AT A HIGHER LEVEL AND BELONGS TO THE SAME ACTIVATION
GROUP AND IS THUS INFLUENCED BY THE PARENTS OVERRIDE SETTING.
HERE HOW …
LISTING OF CL002 :
PGM
SNDPGMMSG MSG('CHILD CL002 PROGRAM STARTED.NO SHARING') +
TOPGMQ(*EXT)
OVRDBF FILE(PFBM2) SECURE(*YES) SHARE(*NO) +
OPNSCOPE(*ACTGRPDFN)
CALL RP01
CALL RP02
SNDPGMMSG MSG('______CL002 DONE_______ ') +
TOPGMQ(*EXT)
DLTOVR FILE(PFBM2)
ENDPGM
MAKE SURE SECURE OPTION IS SET TO YES. THIS SECURES THE OVERRIDE FROM OTHER
OVERRIDES.
CL001 :
PGM
OVRDBF FILE(PFBM2) SECURE(*NO) OVRSCOPE(*CALLLVL) +
SHARE(*YES)
OPNDBF FILE(SAM2/PFBM2) OPTION(*ALL) OPNSCOPE(*ACTGRP)
SNDPGMMSG MSG('OUTPUT WHEN THE OVERRIDE WAS APPLIED ') +
TOPGMQ(*EXT)
CALL RP01
214
RPG-ILE LABS
CALL CL002
CALL RP02
CLOF OPNID(PFBM2)
DLTOVR FILE(PFBM2) LVL(*)
SNDPGMMSG MSG('______OVERRIDE REMOVE_______ ') +
TOPGMQ(*EXT)
CALL RP01
CALL RP02
ENDPGM
CL002 :
PGM
SNDPGMMSG MSG('CHILD CL002 PROGRAM STARTED.NO SHARING') +
TOPGMQ(*EXT)
OVRDBF FILE(PFBM2) SECURE(*YES) SHARE(*NO) +
OPNSCOPE(*ACTGRPDFN)
CALL RP01
CALL RP02
SNDPGMMSG MSG('______CL002 DONE_______ ') +
TOPGMQ(*EXT)
DLTOVR FILE(PFBM2)
ENDPGM
RP01 :
FPFBM2 IF E DISK
C 'RP01' DSPLY
C READ BM 33
C BCODE DSPLY
C READ BM 33
C BCODE DSPLY
C CALL 'RP003'
C SETON LR
RP003 :
FPFBM2 IF E DISK
C 'RP003' DSPLY
C READ BM 33
C BCODE DSPLY
C READ BM 33
C BCODE DSPLY
C SETON LR
RP02 :
FPFBM2 IF E DISK
C 'RP02' DSPLY
C READ BM 33
C BCODE DSPLY
C READ BM 33
C BCODE DSPLY
C SETON LR
OUTPUT :
215
RPG-ILE LABS
DSPLY RP003
DSPLY 3
DSPLY 4
CHILD CL002 PROGRAM STARTED.NO SHARING
DSPLY RP01
DSPLY 1
DSPLY 2
DSPLY RP003
DSPLY 1
DSPLY 2
DSPLY RP02
DSPLY 1
DSPLY 2
______CL002 DONE_______
DSPLY RP02
DSPLY 5
DSPLY 6
______OVERRIDE REMOVE_______
DSPLY RP01
DSPLY 1
DSPLY 2
DSPLY RP003
DSPLY 1
DSPLY 2
DSPLY RP02
DSPLY 1
DSPLY 2
SCOPING : I HAD TO KEEP THE SCOPING AS *CALLLVL FOR OVRDBF AND *ACTGRP FOR SHARE=YES
DOES THIS MEAN THAT OVRDBF WILL BE EFFECTIVE FOR THE CURRENT CL001 PROGRAM (CALLLVL)
? THEN WHY IS THERE ONE MORE OPTION FOR SCOPING FOR SHARE OPTION ? HOW COME SHARE
OPTION HAS NO CALLLVL SCOPING ? WHY ARE WE FORCED TO SPECIFY *ACTGRPDFN OR *JOB FOR
SHARE = *YES OPTION ?
CLQRYST CALLS CLQRY WHICH USES OPNQRYF AND CALLS RP001. THE ODP IS SHARED
SO THAT RP001 DOES NOT GET ALL RECORDS OF PF001,ONLY RECORDS WHERE BCODE < 4.
LISTING OF CLQRYST :
PGM
DCL &S *CHAR 40 'BCODE < 4'
CALL CLQRY PARM(&S)
ENDPGM
LISTING OF CLQRYF :
PGM PARM(&QRYSTR)
DCL &QRYSTR *CHAR 40
OVRDBF FILE(PFBM2) SHARE(*YES) OPNSCOPE(*ACTGRPDFN)
OPNQRYF FILE((SAM2/PFBM2)) OPTION(*ALL) QRYSLT(&QRYSTR)
/* SHOW ALL RECORDS */
CALL RP001
CLOF PFBM2
DLTOVR FILE(PFBM2)
ENDPGM
216
RPG-ILE LABS
LISTING OF RP001 :
FPFBM2 IF E DISK
C SETOF 03
C *IN03 DOWEQ*OFF
C READ BM 03
C BCODE DSPLY
C ENDDO
C*
C SETON LR
OUTPUT :
1
2
3
Heirarchy :
JOB
Contains ACTIVATION GROUP
Has CALL LEVELS
217
RPG-ILE LABS
CODE :
* RPIND.
* Demostrates external indicators.
* First set U1 to *ON. then do WRKJOB to see the job atributes.
* See the job Switch. Notice that it becomes 1000 0000
* The first '1' corresponds to U1 indicator.
*
*
c Eval *inU1 = *on
c If *inU1 = *ON
c 'test' Dsply
c Endif
c Eval *inlr = *on
PF contents :
nil
OUTPUT :
REMARKS :
U1,…U8 are called external indicators since other CL /RPG programs can access the
state oof those indicators.
dT1 s T
c time T1
c T1 dsply
c Eval *inlr = *on
DCon2 C Const(X'10')
c Con2 dsply
c Eval *inlr = *on
c Return
c*
218
RPG-ILE LABS
CODE :
* RPIND1.
* Demostrates RT indicator.
* set up an impossible condition for the LR indicator.
* In the following code, LR is never turned ON.
* So program never properly terminates.
*
* But after executing the last C instruction, the program
* returns control to OS and seems to end.This is since RT is 1
* If RT is not 1, program will loop infinetely or till LR
* becomes 1.
* The program actually does not end since calling it agains
* displays value of 'a' incremented by 1.
*
da s 5i 0 inz(10)
c Eval *inRT = *on
c 'a = ' dsply
c a dsply
c Eval a = a + 1
c*
c* set up an impossible condition
c*
c if a <0
c Eval *inlr = *on
c Endif
PF contents :
nil
OUTPUT :
Since LR is never turned on, program does not terminate but displays increasing
values of a every time it is called.
REMARKS :
Linkage : RPDEFUN
CODE :
c 'Starting...' DSPLY
/if defined(myvar1)
c 'ya ! defined'Dsply
/else
c 'Nop!' Dsply
/endif
c Eval *inlr=*on
PF contents :
219
RPG-ILE LABS
nil
OUTPUT :
REMARKS :
Compile the RPDEFUN program with option 14. and run the program. Output is NOP !
since the MYVAR1 varaible is not defined. Now type 14 to compile the same program
again and press F4 and F10 for extended prompting.
In the DEFINE parameter specify the name MYVAR1 to #define this variable.Press Enter
to Compile . Run the program now. Output is is Ya! Defined. Since now myvar1 is
defined to the program.
220
RPG-ILE LABS
Linkage : RPRANDOM
CODE :
dVar1 s 6s 0
dVar2 s 6s 0
dSysTime s z
c do 3
c time SysTime
c* SysTime Dsply
c Extrct SysTime:*ms Var1
c Eval Var1 = Var1/10000
c Var1 Dsply
c Extrct SysTime:*s Var2
c Eval Var1 = %abs(Var1 - Var2)
c Var1 Dsply
c EndDo
c Eval *inlr = *on
Number
generated
2005 03 24 12.52.53.613000 |53-61| = 8
2005 03 24 12.52.54.865000 32
2005 03 24 12.52.56.514000 5
2005 03 24 12.53.38.244000 14
2005 03 24 12.53.39.537000 14
2005 03 24 12.53.41.114000 30
2005 03 24 12.54.53.157000 38
2005 03 24 12.54.55.002000 55
2005 03 24 12.54.57.313000 26
2005 03 24 12.56.45.359000 10
2005 03 24 12.56.46.807000 34
2005 03 24 12.56.48.153000 33
Alternative approach : Pick up the MS (milli sec) part, at any time, it will be
random between 000 to 999.
PF contents :
OUTPUT :
REMARKS :
221
RPG-ILE LABS
Concept : A nomain module contains a FNTEST procedure that accepts 3 arguments. The
arguments are lenghts of sides of a triangle. If the lenghts are same, the triangle
is a equilateral triangle. In that case, a 3 is returned. If any 2 sides have equal
length, a 2 is returned (isosceles triangle). If none of the sides are equal, a 0 is
returned.
We design a test program to test the procedure against some test data which we hard
coded into the test program.
Name of the stub program : RPTEST.
Before running JSRP1, use CHGJOB to modify the SWITCH of your job to
1000 000. This makes U1 ON. RPTEST will produce output only if U1 is ON.
Linkage : RPTEST (stub program to test FNTEST proc in RPTEST1 module) RPTEST1 (no
main contains FNTEST procedure)
Both RPTEST and RPTEST1 are Bound by copy to form JSRP1 program object.
Run JSRP1 to start the test.
CODE :
dFNTest PR 5i 0
d 5i 0 value
d 5i 0 value
d 5i 0 value
d*****
dRetVal s 5i 0 inz(0)
dSide1 s 5i 0 inz(10)
dSide2 s 5i 0 inz(10)
dSide3 s 5i 0 inz(10)
c*
c* Test Case #1.
c* Check for EQUILATERAL TRIANGLE.
c*
c U1'EQUILA :3' Dsply
c Eval RetVal = FNTest(Side1:Side2:Side3)
c U1RetVal Dsply
c*
c* Test Case #2.
c* Check for ISOSCELES TRIANGLE.
c*
c Eval Side1 = 5
c Eval RetVal = FNTest(Side1:Side2:Side3)
c U1'ISOSCE : 2' Dsply
c U1RetVal Dsply
c*
c* Test Case #3.
c* Check for other than ISO and EQUI.
c*
c Eval Side2 = 4
c Eval RetVal = FNTest(Side1:Side2:Side3)
c U1'None :0' Dsply
c U1RetVal Dsply
c Eval *inlr = *on
222
RPG-ILE LABS
H*
HNomain
H* FNTEST return values
H* 3 : Equilateral triangle
H* 2 : Isosceles triangle
H* 0 : None of the above
H*
H*
dFNTEST PR 5i 0
d 5i 0 value
d 5i 0 value
d 5i 0 value
pFNTEST B export
dFNTEST PI 5i 0
dsd1 5i 0 value
dsd2 5i 0 value
dsd3 5i 0 value
dRetVal s 5i 0 inz(-2)
c*
c if (sd1=sd2) and (sd1=sd3) and (sd2=sd3)
c Eval Retval = 3
c return RetVal
c EndIf
c*
c if (sd1 = sd2 ) or (sd1 = sd3) or ( sd2 = sd
c Eval Retval = 2
c return RetVal
c* isosceles triangle
c EndIf
c*
c if (sd1 <>sd2 ) or (sd1 <>sd3) or ( sd2 <>sd
c Eval Retval = 0
c return RetVal
c* isosceles triangle
c EndIf
c*
c
PFNTEST E
PF contents :
nil
OUTPUT :
3 sets of test data produce 3 expected results. We are not testing for invalid data
(either numeric or otherwise).
REMARKS :
Other testing areas such as Boundary level testing, validation testing are not
covered in this Lab.
Program tries to calculate take home amount using formula for compound interest.
223
RPG-ILE LABS
Linkage : RPOFL
CODE :
dth s 5i 0 inz(0)
droi s 5i 0 inz(10000)
damt s 5i 0 inz(10000)
dyrs s 5i 0 inz(50)
c Eval th = amt * (1 + roi/100) ** yrs
c th dsply
c Eval *inlr=*on
PF contents :
nil
OUTPUT :
The target for a numeric operation is too small to hold the result (C G D F)
REMARKS :
Program is not robust enough to handle overflow errors. EVAL needs to do Error
handling.
Better solution :
The programmer who wrote the procedure should generate Tech specifications of the
procedure and design the procedure to accept argument values only within certain
sensible ranges.
The procedure should set retval variables to some negative values to indicate invalid
data values.
The tech specs can be handed over to the testor who will build the test cases around
the tech specs.
224
RPG-ILE LABS
Linkage : RPFREE
CODE :
Linkage : RPFREE
ds1 s 4 inz('abc')
dn1 s 4s 0 inz(1)
dn2 s 4s 0 inz(2)
dn3 s 4s 0 inz(3)
d**
/free
eval n3 = n1 + n2;
dsply 'N1 : ' ;
dsply N1 ;
dsply 'N2 : ';
dsply N2;
dsply 'N3 : ';
dsply N3;
eval *inlr = *on;
/End-Free
PF contents :
OUTPUT :
REMARKS :
Linkage : RPDSREAD
Code :
Fdsdbread cf e Workstn
Fpfbm if e Disk
dtemp s 4s 0
/free
Read bm;
Eval DCode = BCode;
Eval DName = BName;
Eval DPrice = BPrice;
Dow *in03 = *off;
Exfmt R1;
if (*in04 = *on);
*in04 = *off;
readp bm;
225
RPG-ILE LABS
if %Eof;
Setll 1, bm;
Read bm;
EndIf;
EndIf ;
if (*in05 = *on);
*in05 = *off;
read bm;
If %Eof;
// setll *hival, bm; DOES NOT WORK !!!
EndIf;
EndIf ;
226
RPG-ILE LABS
227
RPG-ILE LABS
228
RPG-ILE LABS
c Time SysTime
c Extrct SysTime:*ms N1
c Callp Reverse(N1)
c Extrct Systime:*s temp
c Eval temp = temp * 10
c Eval N1 = %Abs(temp-N1)
c Eval F1 = N1
c
C open(e) dsmemori
c If %error()
c* do nothing
c EndIf
c Time SysTime
c Extrct SysTime:*ms N2
c Callp Reverse(N2)
c Extrct Systime:*s temp
c Eval temp = temp * 10
c Eval N2 = %Abs(temp-N2)
c Eval F2 = N2
c*
c*
C close dsmemori
C open dsmemori
c Time SysTime
c Extrct SysTime:*ms N3
c Callp Reverse(N3)
c Extrct Systime:*s temp
c Eval temp = temp * 10
c Eval N3 = %Abs(temp-N3)
c Eval F3 = N3
c*
c*
PPGenerate E
P*
P* Calculates the score
P*
PComputeScore B
dComputeScore PI
dW0N1 6s 0
dW0N2 6s 0
dW0N3 6s 0
dW0Score 3s 0
d*
c If (F1 = W0N1) AND (F2=W0N2) AND (F3=W0N3)
c Eval W0Score = 100
c EndIf
c If (F1 = W0N1) AND (F2=W0N2) and (F3<>W0N3)
c Eval W0Score = 60
c EndIf
c If (F1 = W0N1) and (F2<>W0N2) and (F3<>W0N3)
c Eval W0Score = 30
c EndIf
c If (F1 <>W0N1) and (F2<>W0N2) and (F3<>W0N3)
c Eval W0Score = 0
c EndIf
PComputeScore E
PReverse b
dReverse Pi
dArg1 6s 0
dTemp s 6s 0
229
RPG-ILE LABS
dStr s 6a
dCounter s 3s 0 inz(1)
dCounter1 s 3s 0 inz(6)
dArrStr s 1a Dim(6)
c Eval str = %trim(%char(Arg1))
c Eval temp = %len(str)
c Do 6
c Eval ArrStr(counter) = %subst(str:counter1:1)
c Eval Counter1 = counter1 -1
c Eval Counter = counter +1
c EndDo
c Eval Counter1 = 6
c Eval Counter = 1
c Do 6
c Eval %subst(str:counter:1)=arrStr(Counter)
c Eval Counter = counter +1
c EndDo
c move str Temp
c Eval Arg1 = Temp
PReverse e
230