Taking advantage of CL advancements, starting with V5R3
Using the new CL programming tools released in V5R3 on the IBM System i has advantages: New looping methods, subroutines, and multiple file declarations. See examples of old versus new programs that ease and shorten programming commands.
![]() |
|
![]() |
![]() |
Andrew Borts | ![]() |
![]() |
When was the last time you wanted to write a subroutine in your CL program to cut down the amount of code you're writing? Or use a logic more complex then "IF/THEN/ELSE
" within your CL program? When was the last time you wanted to loop through something without the use of GOTO
's and IF
's in the clunkiest use of code you've seen in a while. For me, it's daily. Who wants to clean up some code so our business rules and our code look related?
Starting in V5R3, there were significant changes to the organization of CL programming languages:
- New looping methods
- Until loop – DOUNTIL (ENDDO)
- For loop – DOFOR (ENDDO)
- While Loop – DOWHILE (ENDDO)
- Logical end and restart of loops
- ITERATE (same as RPG ITER)
- LEAVE – (same as RPG LEAVE)
- Multiple file declaration (V5R3)
- RCVF for up to five files
- Flow changes
- SELECT when
- Subroutines (V5R4)
- SUBR./ENDSUBR
DO/ENDDO vs DOUNTIL
Let me show you what you've been missing. In our old routines, we needed to group commands together using DO/ENDDO
DCLF FILE(*LIBL/FILE1) OPNID(ID1)
Again:
RCVF OPNID(ID1)
/* CPF0864 End of file detected for file &1 in &2. */
MONMSG MSGID(CPF0864) EXEC(DO)
ENDDO
GOTO CMDLBL(AGAIN)
In a word: Yuck. What if this looked like this?
DCLF FILE(*LIBL/FILE1) OPNID(ID1)
DCL VAR(&IMDONE) TYPE(*CHAR) LEN(1) VALUE('0')
DOUNTIL COND(&IMDONE *EQ '1')
RCVF OPNID(ID1)
/* CPF0864 End of file detected for file &1 in &2. */
MONMSG MSGID(CPF0864) EXEC(LEAVE)
ENDDO
CALL PGM(MENEXT)
Program flow is cleaned up. DOUNTIL
checks the logic after the first iteration so we'll try and read the file, and leave the loop when the file is completed.
Controlling patterns using DOWHILE
You can control the patterns of your CL programs using DOWHILE
as follows:
DCLF FILE(*LIBL/FILE1) OPNID(ID1)
DCL VAR(&FIL2FND) TYPE(*CHAR) LEN(1) VALUE('JHANCOCK')
DCL VAR(&FILEFND) TYPE(*CHAR) LEN(1) VALUE('1')
RTVOBJD OBJ(&FILE2FND) OBJTYPE(*FILE)
MONMSG MSGID(CPF9801) EXEC(CHGVAR VAR(&FILE2FND) +
VALUE('0'))
DOWHILE COND(&FILEFND *EQ '1')
RCVF OPNID(ID1)
MONMSG MSGID(CPF0864) EXEC(LEAVE)
ENDDO
CALL PGM(MENEXT)
I'm never going to perform the loop unless JHANCOCK is found. Once I reach the end of file in all of these examples, I leave the loop. I can pop back up to the top of the loop if my logic requires me to start with, for example, the next record in the file.
Setting the number of loops DOFOR
is for looping a set amount of times, then falling out of the loop. Say if you need to do something 15 times:
DOFOR VAR(&CTR) FROM(1) TO(15) BY(1)
The static values can be substituted for field names – from &FRM
to &TO
is a valid loop as well.
The examples I gave above also show how to uniquely identify up to five files – display or database files.
Using SELECT/WHEN/END/SELECT to clean up programs
So how many of our programs look like this?
IF COND(%SST(&FILENM 1 3) *EQ 'AAA') THEN(DO)
GOTO CMDLBL(LOOPTOP)
ENDDO
ELSE CMD(IF COND(%SST(&FILENM 1 3) *EQ 'BBB') +
THEN(DO))
GOTO CMDLBL(ENDOFLOOP)
ENDDO
A little ugly. So we can clean it up:
SELECT
WHEN COND(%SST(&FILENM 1 3) *EQ 'AAA') THEN(ITERATE)
WHEN COND(%SST(&FILENM 1 3) *EQ 'BBB') THEN(LEAVE)
ENDSELECT
The DO/ENDDO
grouping of code above may be a bit exaggerated. But, you can see that using the SELECT/WHEN/ENDSELECT
your code looks so much easier to understand.
Using CL subroutines
Subroutines clean up the code even more.
SELECT
WHEN COND(%SST(&FILENM 1 3) *EQ 'AAA') +
THEN(CALLSUBR SUBR(AAAFILE))
WHEN COND(%SST(&FILENM 1 3) *EQ 'BBB') +
THEN(CALLSUBR SUBR(BBBFILE))
ENDSELECT
RCLRSC
SUBR SUBR(AAAFILE)
ENDSUBR
ENDPGM
You see that subroutine AAAFILE
is called WHEN
AAA is in the prefix of the field &FILENM. (%SST is the substring command.)
Using this technique, your code will clean up, and you'll be writing shorter and shorter CL programs in no time.