• The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
Menu
  • The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
  • A Handy RPG FUNction

    November 9, 2005 Ted Holt

    I like functions. I like the ones built into RPG, like %SUBST and %DATE and %CHAR and %FOUND. I like the ones built into SQL, like UPPER and DIGITS. Functions accomplish a lot of work with little effort because the code inside a function does not need to be included in the routines that call the function. I enjoy writing my own functions and using them in my programming. Today, I’m going to share a function I recently wrote that is proving to be useful to me. You may like it, too.

    Not long ago, I was working on an RPG program and needed to display a Y or N to indicate whether certain fields were true or not. I had a lot of five-line tests like this:

    if Type = 'E';
       EDICust = 'Y'; 
    else;            
       EDICust = 'N';
    endif; 
    

    Something about this looked familiar, and I finally realized what it was. I thought back to my System/34 and System/36 RPG II days, when I would look at RPG III code in the trade magazines and see things like this:

    C           TYPE      IFEQ 'E'
    C                     MOVE '1'       *IN25
    C                     ELSE   
    C                     MOVE '0'       *IN25
    C                     END
    

    This type of code looked strange to me at the time, since I was used to accomplishing the same task with one COMP operation.

    C*                                       HILOEQ
    C           TYPE      COMP 'E'               25
    

    Anyway, back to the present. I had the nagging thought that I should be able to replace the five-line IF-ELSE-ENDIF structure with one line, even in free-format RPG IV. Finally it dawned on me that I had used such a technique in Microsoft Access and Visual Basic. In a few minutes, I had my own IIF function.

    IIF is a very simple function. It accepts three arguments: a condition, a value to return if the condition is true, and a value to return if the condition is false. Here is the prototype:

    D iif             pr           256a   varying                  
    D  Condition                      n           value            
    D  TrueValue                   256a   varying value            
    D  FalseValue                  256a   varying value            
    

    And here is the function itself:

    P iif             b                                    
    D                 pi           256a   varying          
    D  Condition                      n           value    
    D  TrueValue                   256a   varying value    
    D  FalseValue                  256a   varying value    
     /free                                                 
         if Condition;                                     
            return TrueValue;                              
         else;                                             
            return FalseValue;
    endif;        
     /end-free         
    P                 e
    

    Using IIF, I was able to reduce the many five-line tests to one line each. Here’s the first example again:

    if Type = 'E';
       EDICust = 'Y'; 
    else;            
       EDICust = 'N';
    endif; 
    

    Here’s the same code, using the IIF function.

    EDICust = iif (Type = 'E': 'Y': 'N');
    

    Notice that my IIF function works with character data only. It would be nice to have another IIF function for numeric values, but I haven’t needed one yet. If I decide to write a numeric IIF, I will have to give it another name, since IBM doesn’t allow different functions of the same name in RPG. (At least, not yet. I hope we’ll see function overloading in a future release.)


    There is no need for an IIF function to set indicator variables. Setting indicator variables with one operation is easily handled with the present RPG syntax. For example, this:

    C           TYPE      IFEQ 'E'
    C                     MOVE '1'       *IN25
    C                     ELSE  
    C                     MOVE '0'       *IN25
    C                     END
    

    is easily replaced by this:

    *in25 = (type = 'E')
    

    If type has a value of E, indicator 25 turns on. If not, indicator 25 turns off. You can do the same thing in CL, by the way.

    dcl     &in25    type(*lgl)
    
    chgvar  var(&in25)  value(&TYPE *EQ 'E')
    

    Here is a short program interested professionals can compile and play with. Each test is done twice; the long way comes first, followed by the IIF version.

    H option(*srcstmt: *nodebugio)                                 
    H dftactgrp(*no) actgrp(*new)                                  
                                                                   
    D iif             pr           256a   varying                  
    D  Condition                      n           value            
    D  TrueValue                   256a   varying value            
    D  FalseValue                  256a   varying value            
                                                                   
    D DropShipCode    s              1a                            
    D ShipMsg         s              3a                            
    D Option          s              1a                            
    D Balance         s              7p 2                          
    D Age             s              3p 0                          
    D AgeCategory     s             12a                            
                                                                   
     /free                                                         
                                                                   
       // 1. If DropShipCode = 'X', print Yes, else print blanks.
    
       if DropShipCode = 'X';                               
          ShipMsg = 'Yes';                                  
       else;                                                
          ShipMsg = *blanks;                                
       endif;                                               
                                                            
       ShipMsg = iif (DropShipCode = 'X': 'Yes': *blanks);  
                                                            
       // 2. If Option is blank, assume Option = 'A'        
                                                            
       if Option = *blank;                                  
          Option = 'A';                                     
       endif;                                               
                                                            
       Option = iif (Option = *blank: 'A': Option);         
                                                            
       // 3. Place into categories by age.
    
       if Age < 6;                                                
          AgeCategory = 'Preschool';                              
       elseif Age < 18;                                           
          AgeCategory = 'School age';                             
       else;                                                      
          AgeCategory = 'Graduate';                               
       endif;                                                     
                                                                  
       AgeCategory = iif(Age<6: 'Preschool':                      
                         iif(Age<18:'School Age': 'Graduate'));   
                                                                  
       // 4. If Balance <= *zero, turn on indicator 25.           
                                                                  
       if Balance <= *zero;                                       
          *in25 = *on;                                            
       else;                                                      
          *in25 = *off;
    
       endif;                                              
                                                           
       *in25 = (Balance <= *zero);                         
                                                           
       *inlr = *on;                                        
                                                           
     /end-free                                             
     * ====================================================
    P iif             b                                    
    D                 pi           256a   varying          
    D  Condition                      n           value    
    D  TrueValue                   256a   varying value    
    D  FalseValue                  256a   varying value    
     /free                                                 
         if Condition;                                     
            return TrueValue;                              
         else;                                             
            return FalseValue;
         endif;        
     /end-free         
    P                 e
    

    I continually look for ideas for new functions to help me in my work. I hope you like IIF, and if you are not writing your own functions, I hope you will learn to do so soon. If you have a useful function you’d like to share with readers of Four Hundred Guru, please email it to me.

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

    Tags:

    Sponsored by
    CYBRA

    The next generation of barcode labeling software is here

    MarkMagic X

    MarkMagic barcode labeling software is the easiest way to design and print the barcode labels, electronic forms, reports, and RFID tags you need to communicate with your customers and suppliers.

    MarkMagic X comes in two major editions – one for IBM i, and one for WIndows, Linux, UNIX, IBM AIX, and other major operating systems.

    Learn More About MarkMagic X

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

    Wyse Takes Software-Oriented Thin Client Strategy to the Market Teamstudio Brings Domino Version Control to iSeries

    One thought on “A Handy RPG FUNction”

    • Ted Holt says:
      May 7, 2020 at 6:45 am

      Free-form version of iif

      dcl-proc iif;

      // Conditional IF
      // If the first parm is *on, return the second parm,
      // otherwise return the third parm.

      dcl-pi *n varchar(256);
      inCondition ind value;
      inTrueValue varchar(256) value;
      inFalseValue varchar(256) value;
      end-pi;

      if inCondition;
      return inTrueValue;
      else;
      return inFalseValue;
      endif;

      end-proc iif;

      Yes, I still use this thing. It’s handy!

      Reply

    Leave a Reply Cancel reply

Volume 5, Number 42 -- November 9, 2005
THIS ISSUE
SPONSORED BY:

ProData Computer Svcs
iTera
Patrick Townsend & Associates

Table of Contents

  • A Handy RPG FUNction
  • Edit Spooled Files with SEU
  • Admin Alert: Use Remote Output Queues to Share Printers Between Partitions

Content archive

  • The Four Hundred
  • Four Hundred Stuff
  • Four Hundred Guru

Recent Posts

  • IBM i Software And Power Systems Upgrades Keep Rolling Forward
  • Preparing For What’s Next In A Thoughtful, Structured Way
  • Guru: Fall Brings New RPG Features, Part 3
  • ARCAD Plugs IBM i DevOps Suite Into Microsoft Azure
  • Park Place Buys Curvature To Become Maintenance Goliath
  • 2021 Predictions for IBM i, Part 1
  • West Four Stands Out With On Demand Color Label Printing
  • HelpSystems Acquires Data Security, File Transfer Companies
  • Four Hundred Monitor, January 13
  • IBM i PTF Guide, Volume 23, Number 2

Subscribe

To get news from IT Jungle sent to your inbox every week, subscribe to our newsletter.

Pages

  • About Us
  • Contact
  • Contributors
  • Four Hundred Monitor
  • IBM i PTF Guide
  • Media Kit
  • Subscribe

Search

Copyright © 2021 IT Jungle

loading Cancel
Post was not sent - check your email addresses!
Email check failed, please try again
Sorry, your blog cannot share posts by email.