• 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
    DRV Tech

    Get More Out of Your IBM i

    With soaring costs, operational data is more critical than ever. IBM shops need faster, easier ways to distribute IBM applications-based data to users more efficiently, no matter where they are.

    The Problem:

    For Users, IBM Data Can Be Difficult to Get To

    IBM Applications generate reports as spooled files, originally designed to be printed. Often those reports are packed together with so much data it makes them difficult to read. Add to that hardcopy is a pain to distribute. User-friendly formats like Excel and PDF are better, offering sorting, searching, and easy portability but getting IBM reports into these formats can be tricky without the right tools.

    The Solution:

    IBM i Reports can easily be converted to easy to read and share formats like Excel and PDF and Delivered by Email

    Converting IBM i, iSeries, and AS400 reports into Excel and PDF is now a lot easier with SpoolFlex software by DRV Tech.  If you or your users are still doing this manually, think how much time is wasted dragging and reformatting to make a report readable. How much time would be saved if they were automatically formatted correctly and delivered to one or multiple recipients.

    SpoolFlex converts spooled files to Excel and PDF, automatically emailing them, and saving copies to network shared folders. SpoolFlex converts complex reports to Excel, removing unwanted headers, splitting large reports out for individual recipients, and delivering to users whether they are at the office or working from home.

    Watch our 2-minute video and see DRV’s powerful SpoolFlex software can solve your file conversion challenges.

    Watch Video

    DRV Tech

    www.drvtech.com

    866.378.3366

    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

  • The Power11 Transistor Count Discrepancies Explained – Sort Of
  • Is Your IBM i HA/DR Actually Tested – Or Just Installed?
  • Big Blue Delivers IBM i Customer Requests In ACS Update
  • New DbToo SDK Hooks RPG And Db2 For i To External Services
  • IBM i PTF Guide, Volume 27, Number 33
  • Tool Aims To Streamline Git Integration For Old School IBM i Devs
  • IBM To Add Full System Replication And FlashCopy To PowerHA
  • Guru: Decoding Base64 ASCII
  • The Price Tweaking Continues For Power Systems
  • IBM i PTF Guide, Volume 27, Numbers 31 And 32

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