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

    Migrate IBM i with Confidence

    Tired of costly and risky migrations? Maxava Migrate Live minimizes disruption with seamless transitions. Upgrading to Power10 or cloud hosted system, Maxava has you covered!

    Learn More

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

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

    2 thoughts 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
    • Ted Holt says:
      September 30, 2021 at 3:35 pm

      Be aware that the arguments to iif have to be valid.

      This won’t work:

      dcl-s OldStatus char(3) dim(4) ctdata perrcd(1);
      dcl-s NewStatus char(1) dim(4) alt(OldStatus);

      dcl-s Ax uns(3);

      Ax = %lookup(EmployeeStatus: OldStatus);
      Stat = iif(Ax > *zero: NewStatus (Ax): ‘?’);

      This will:

      Ax = %lookup(EmployeeStatus: OldStatus);
      if Ax > *zero;
      Stat = NewStatus (Ax);
      else;
      Stat = ‘?’;
      endif;

      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

  • POWERUp 2025 –Your Source For IBM i 7.6 Information
  • Maxava Consulting Services Does More Than HA/DR Project Management – A Lot More
  • Guru: Creating An SQL Stored Procedure That Returns A Result Set
  • As I See It: At Any Cost
  • IBM i PTF Guide, Volume 27, Number 19
  • IBM Unveils Manzan, A New Open Source Event Monitor For IBM i
  • Say Goodbye To Downtime: Update Your Database Without Taking Your Business Offline
  • i-Rays Brings Observability To IBM i Performance Problems
  • Another Non-TR “Technology Refresh” Happens With IBM i TR6
  • IBM i PTF Guide, Volume 27, Number 18

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 © 2025 IT Jungle