• The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
Menu
  • The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
  • Guru Classic: The New Basics — Indicators

    July 17, 2019 Jon Paris

    The history of indicators pre-dates even the earliest versions of RPG and takes us all the way back to the old tabulating machines, perhaps even earlier depending on how broad a definition one uses. What is without doubt, though, is that indicators in the sense of *INnn and *INLR were added to the RPG language as a vehicle for translating those old tabulator board programs.

    RPG has grown a lot since those early days, and yet many people still write code using the old-style numbered indicators. LR? Well, we’re kind of stuck with that, but there hasn’t been a need to use numbered indicators in your RPG programs for a very, very long time. Not since V4R2 in fact, when named indicators were first introduced into the language. Of course, if you use program-described report files, you have little choice but to use the numbered indicators on the O-specs themselves, but in the calculations you do have a choice.

    Since I first wrote the original version of this tip back in 2012, RPG has experienced another major change with the introduction of completely free-form data decelerations. That made this tip an obvious choice for re-working as a “Classic”.

    I covered some indicator basics in a previous article, An Indicator By Any Other Name. I strongly suggest you review that article as a refresher. This article picks up where that one left off, having established the following points:

    • Indicators can be treated as an array. That is, *In55 and *In(55) reference the same indicator.
    • The compiler understands that an indicator (named or otherwise) is a Boolean and can be tested as such. For example the following are both perfectly valid methods of using indicator 55.
       If *In(55);
        //    . . .
       Endif;
       If Not *In55;
        //    . . .
       EndIf;
    
    • Named constants can be used as array subscripts allowing names to be associated with indicators. For example, here’s one way to associate indicator 55 with the name: overCreditLimit_55.
        dcl-c  overCreditLimit_55  55;
           
        if *In(overCreditLimit_55);
          //    . . .
        EndIf;
    
    • A logical expression can be assigned to an indicator. For example, the following expression sets indicator 55 on or off depending on the true/false result of the test.
        *In(overCreditLimit) =
           ( orderTotal + currentBalance ) > creditLimit;
    

    Now Let’s Take The Next Step

    Indicators *In01 – *In99 are just a set of bytes in memory–consecutive bytes. So if we want to give names to all 99 indicators (or as many of them as we have used), we can do so by mapping the indicator array to a data structure of our own design. The following code demonstrates the basic idea. If pointers make you nervous, don’t worry. When used this way, you’ll never have to do anything with the pointer; the compiler does all the work for you. Here’s an example:

        dcl-s pIndicators  Pointer  Inz(%Addr(*In));
    
        dcl-ds indicators  Based(pIndicators);
          newPage_01            ind  Pos(1)
          endOfFile_02          ind  Pos(2);
          // 
          errorFlags  char(3)        Pos(55);
            overCreditLimit_55  ind  Pos(55);
            invalidCustomer_56  ind  Pos(56);
            badPartNumber_57    ind  Pos(57);
        end-ds;
    

    Note that I defined the pointer first, followed by the indicator data structure. If I do it this way, it makes it easy for me to incorporate the basic setup in a /Copy member if I want to and then add my own application specific definitions to the data structure.

    This example also defines a field (errorFlags), which makes it easy for me to turn on or off a group of error indicators very easily. Like so:

       errorFlags = *Off;
    

    I never did like the old approach of using MOVEA for this purpose. I find this way far better. A similar approach can be used with indicators for a subfile, where a particular on/off combination is needed to display or clear the subfile. In this case I would use named constants with the appropriate “0” and “1” pattern to achieve the settings I needed. Here’s an example:

        dcl-ds DisplayIndicators Based(pIndicators);
        // Input request indicators
          exit_3        ind   Pos(3);
          sortPrCode_5  ind   Pos(5);
          sortDesc_6    ind   Pos(6);
        // Output control indicators
          sflControls_90_92  char(3)   Pos(90);
        // Individual indicators shown for reference - not used in code
            sflDspCtl_90  ind   Pos(90);
            sflClear_91   ind   Pos(91);
            sflDsp_92     ind   Pos(92);
        end-ds;
          
        // Constants to set subfile operations
        dcl-c clearSfl   '010';
        dcl-c displaySfl '101';
    

    Using this approach then to set up the indicators to clear or display the subfile, I need only code a single line and, unlike MOVEA, what I am doing is very obvious to those who come after me. For example:

        sflControls_90_92 = ClearSfl;
        
        sflControls_90_92 = DisplaySfl;
    

    In fact, this is about the only time I ever use the old character style representations for indicators.

    INDDS: The Architected Approach To Naming Indicators

    Back in V4R2, the RPG compiler folks decided that, in the absence of direct DDS support for indicator names, they should come up with an RPG-specific implementation. INDDS was the result. It stands for INDicator Data Structure and is simply added to the F-spec of the file (or files) that are to use the named data structure for their indicators. There are several important things to note about INDDS:

    • When INDDS is used for a file, there is no longer any connection between the indicators used by the file and the standard *IN series. The device will only use the indicators defined in the specified data structure.
    • Each file can specify its own unique data structure or a single data structure can be shared by multiple files.
    • INDDS can only be specified for files defined with the INDARA (Indicator Area) keyword. I had hoped that over the years this restriction would be removed, but luckily I did not hold my breath waiting.
    • Display files can be changed to use this keyword with no problems at all providing that you keep in mind that with INDARA files a CLEAR or RESET of a record format will not affect the indicators, only the data fields.
    • The indicator array identified by the INDDS keyword is always 99 bytes long. The POS keyword provides an easy way to map the indicator number to the name.

    That said, let’s use a simple display file and include the same error indicators that we used in the earlier example. This is how the file declaration and indicator data structure would be coded:

        dcl-f DispFile WORKSTN(*EXT) USAGE(*INPUT:*OUTPUT)
                                     INDDS(dispIndicators);
        dcl-ds dispIndicators;
          //
          errorFlags  char(3)        Pos(55);
            overCreditLimit_55  ind  Pos(55);
            invalidCustomer_56  ind  Pos(56);
            badPartNumber_57    ind  Pos(57);
        end-ds;
    

    To me this is the cleanest approach to handling indicators and can be very useful when the limit of 99 regular indicators gets in the way. Suppose you need to have multiple files sharing some of the indicators but, in order to be able to use more than 99 indicators in total, don’t want to have them share the same data structure. This can be handled quite nicely using EVAL-CORR (Evaluate Corresponding).

    You just need to clone the relevant portions of (say) the display file data structure and add the keyword QUALIFIED to the new data structure definition. Then whenever you want to copy the state of the matching indicators from one data structure to the other you simply use an EVAL-CORR to copy them in the appropriate direction.

    The example below shows both this approach and a simpler option which takes advantage of the fact that the display file error indicators and the indicators used by the O-Specs for printing are grouped into a single field.

        dcl-ds printIndicators  Qualified  Based(pIndicators);
          // Print specific indicators
          newPage_01            ind  Pos(1);
          endOfFile_02          ind  Pos(2);
          // indicators common with display file
          errorFlags  char(3)        Pos(55);
            overCreditLimit_55  ind  Pos(55);
            invalidCustomer_56  ind  Pos(56);
            badPartNumber_57    ind  Pos(57);
        end-ds;
    
        // Copy all common indicators from display file to print
        Eval_Corr printIndicators = dispIndicators;  
        // Or just set print indicators from display file settings
        printIndicators.errorFlags = errorFlags; 
    

    It is important that you not change the names of the individual indicators or this won’t work. That’s the meaning of the “corresponding” part of the op-code. Only those fields with matching names and compatible data types will be copied.

    Hopefully I’ve helped to update your understanding of modern indicator usage. If there are any other basic aspects of modern RPG programming you would like to see covered in this series please let me know.

    Jon Paris is one of the world’s foremost experts on programming on the IBM i platform. A frequent author, forum contributor, and speaker at User Groups and technical conferences around the world, he is also an IBM Champion and a partner at Partner400 and System i Developer. He hosts the RPG & DB2 Summit twice per year with partners Susan Gantner and Paul Tuohy.

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

    Tags: Tags: 400guruclassic, FHGC, Four Hundred Guru Classic, IBM i, RPG

    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

    Guru Classic: Looking For Commitment, Part 2 Guru Classic: My Favorite Keyboard Shortcuts for RSE/RDi

    Leave a Reply Cancel reply

TFH Volume: 29 Issue: 42

This Issue Sponsored By

  • RPG & DB2 Summit
  • RPG & DB2 Summit
  • RPG & DB2 Summit

Table of Contents

  • Guru Classic: My Favorite Keyboard Shortcuts for RSE/RDi
  • Guru Classic: The New Basics — Indicators
  • Guru Classic: Looking For Commitment, Part 2

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