• 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
    WorksRight Software

    Do you need area code information?
    Do you need ZIP Code information?
    Do you need ZIP+4 information?
    Do you need city name information?
    Do you need county information?
    Do you need a nearest dealer locator system?

    We can HELP! We have affordable AS/400 software and data to do all of the above. Whether you need a simple city name retrieval system or a sophisticated CASS postal coding system, we have it for you!

    The ZIP/CITY system is based on 5-digit ZIP Codes. You can retrieve city names, state names, county names, area codes, time zones, latitude, longitude, and more just by knowing the ZIP Code. We supply information on all the latest area code changes. A nearest dealer locator function is also included. ZIP/CITY includes software, data, monthly updates, and unlimited support. The cost is $495 per year.

    PER/ZIP4 is a sophisticated CASS certified postal coding system for assigning ZIP Codes, ZIP+4, carrier route, and delivery point codes. PER/ZIP4 also provides county names and FIPS codes. PER/ZIP4 can be used interactively, in batch, and with callable programs. PER/ZIP4 includes software, data, monthly updates, and unlimited support. The cost is $3,900 for the first year, and $1,950 for renewal.

    Just call us and we’ll arrange for 30 days FREE use of either ZIP/CITY or PER/ZIP4.

    WorksRight Software, Inc.
    Phone: 601-856-8337
    Fax: 601-856-9432
    Email: software@worksright.com
    Website: www.worksright.com

    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

  • Public Preview For Watson Code Assistant for i Available Soon
  • COMMON Youth Movement Continues at POWERUp 2025
  • IBM Preserves Memory Investments Across Power10 And Power11
  • Eradani Uses AI For New EDI And API Service
  • Picking Apart IBM’s $150 Billion In US Manufacturing And R&D
  • FAX/400 And CICS For i Are Dead. What Will IBM Kill Next?
  • Fresche Overhauls X-Analysis With Web UI, AI Smarts
  • Is It Time To Add The Rust Programming Language To IBM i?
  • Is IBM Going To Raise Prices On Power10 Expert Care?
  • IBM i PTF Guide, Volume 27, Number 20

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