Taking advantage of CL advancements, starting with V5R3

Taking advantage of CL advancements, starting with V5R3


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

    Requires Free Membership to View

    Register today to access targeted resources from our editorial writers and independent industry experts including news, tips, and advice to help you do your job more efficiently and effectively. Stay informed on the hottest topics and biggest challenges faced by IT professionals working with iSeries products and services.

    By submitting your registration information to Search400.com you agree to receive email communications from TechTarget and TechTarget partners. We encourage you to read our Privacy Policy which contains important disclosures about how we collect and use your registration and other information. If you reside outside of the United States, by submitting this registration information you consent to having your personal data transferred to and processed in the United States. Your use of Search400.com is governed by our Terms of Use. You may contact us at webmaster@TechTarget.com.

    • 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.

This was first published in September 2009

Disclaimer: Our Tips Exchange is a forum for you to share technical advice and expertise with your peers and to learn from other enterprise IT professionals. TechTarget provides the infrastructure to facilitate this sharing of information. However, we cannot guarantee the accuracy or validity of the material submitted. You agree that your use of the Ask The Expert services and your reliance on any questions, answers, information or other materials received through this Web site is at your own risk.