Published on System iNetwork (http://systeminetwork.com)
Use the READE Opcode, Please!
By cbushong
Created Apr 17 2008 - 19:20

By:
Bob Cozzi [1]

Read Equal Key

Use it or... well, use it.

Over the years, I've seen a number of people using the READE (read equal key) opcode in their RPG III and RPG IV programs. But I've also seen a handful of people not using it in situations where it was meant to be used.

Let's look at the READE opcode and its sibling READPE in more detail to make sure we're all using it to our advantage.

READE (Read Equal Key) allows you to read a database record in keyed sequence. If the next key matches that of the keylist specified, the record is returned to the program. If it doesn't match, you get the lovely %EOF (end of file) condition.

READPE (Read Prior Equal Key) does the same thing, but in reverse, reading upward toward the beginning of the file. Like READE, when READPE detects a key different from the keylist, it too signals an end-of-file condition. The %EOF built-in function is also used in this situation.

Remember, when %EOF is signaled the file must be repositioned before reading it again with a READE, READPE, READ, or READP. The CHAIN, SETLL, or SETGT are typically used to reposition the file after an end-of-file condition.

Typically, READE is used with a SETLL or CHAIN opcode to position the file and then read the set of records with a key equal to that of the keylist. Often I see people using SETLL or CHAIN and then use a READ opcode followed by an IF statement to check the record just read to see if its key fields match. Something like this:

      /free
         chain (actnbr) custmast;
         if %found();
            dow not %EOF();
               if (actnbr = c.acctno);
                 // do whatever
               endif;
               read custmast;
            enddo;
         endif;
      /end-free

In this example, a CHAIN opcode retrieves the first record that we're looking for, and then using a combination of %FOUND and a DOU (do until) loop reads through the file until the key changes or end of file is detect. I think, officially, this is called the Yuk! style of coding.

Using READE, this type of loop would be written something like the following:

      /free
         setll (actnbr) custmast;
         if %EQUAL();
            reade (actnbr) custmast;
            dow not %EOF();
                 // do whatever
               reade (actnbr) custmast;
            enddo;
         endif;
      /end-free

The inherent problem with the DOW versus DOU looping and duplicating the conditional statement or duplicating the READE operation isn't the focus of this article, so I won't go into that.

By using a READE operation, you delegate the responsibility of comparing the key fields just read into the program from the file to the opcode.

These examples are in free format but also apply to traditional RPG IV syntax. However, there is a feature of the free-format syntax that is not available in traditional syntax, and that's the ad hoc keylist (which I've been using here).

Ad hoc keylists are an alternative to the traditional KLIST/KFLD opcodes. By wrapping the fields used in the keylist in parentheses, you're instructing the compiler to generate an ad hoc keylist. For example:

     C     ORDLINE       KLIST 
     C                   KFLD                    ORDNBR
     C                   KFLD                    LINENO
     C     ORDER         KLIST 
     C                   KFLD                    ORDNBR

     C                   eval      lineno = 1
     C                   eval      ordbr = 3741

     C     ORDLINE       CHAIN     ORDERFILE
     C                   if        %found()
     C                   dow       NOT %EOF()
     C                   eval      total += qtyord*price
     C     ORDER         reade     orderfile
     C                   enddo
     C                   endif

In this example, the ORDLINE keylist is used to position the file to the first record that matches the data in the fields in the keylist. Then the READE opcode is use with another keylist, ORDER, to continue to retrieve each record in the file with a key that matches the fields in this keylist.

In free format, this code would be written as follows:

      /free                      
         chain (ordnbr:lineno) orderfile;
         if %found();
           dow  not %EOF();
             total += qtyord*pric;
             reade (ordnbr) orderfile;
           enddo;
         endif;
      /end-free

Note the use of the (ordnbr:lineno) and (ordnbr) parameters of the CHAIN and the READE opcodes. This is how ad hoc keylists are specified. No read KLIST/KFLD opcode required. The READE (and CHAIN) opcodes assemble an ad hoc keylist for you by using the fields in the parentheses.

Using an ad hoc keylist, you can avoid declaring keylists in the Calc specs (which doesn't feel right when using /FREE syntax anyway).

RPG TnT: 101 Dynamic Tips 'n Techniques with RPG IV by Bob Cozzi is available now.
[2] The latest book from author Bob Cozzi is available now. This 300-page book contains 101 example RPG IV Tips and Techniques for everyday programming tasks, from date calculations, to regular express searches, to using APIs. Cozzi wrote down every cool technique he's found over the years, updated them, and consolidated them into this compact book that is a great desktop companion. And it includes full example source code. Order your copy today. [3]

%KDS Parameter

There's more to ad hoc keylists; you can also use a data structure as the keylist. If you have a data structure that contains the key fields for your READE or CHAIN access, you can use the data structure name as an ad hoc keylist. But you can't enclose it in paren; instead, you wrap it in gthe %KDS keyword, as follows:

             reade %kds(ordStruct) orderfile;

This uses the ORDSTRUCT data structure's subfield as an ad hoc keylist. If you have more fields in the data structure than are used for the keylist, then you specify a second parameter on the %KDS keyword to indicate how many subfields should be used for the keylist, as follows:

             chain %kds(ordStruct:2) orderfile;

             reade %kds(ordStruct:1) orderfile;

This causes the first two and first fields, respectively to be used as the ad hoc keylist.

So don't assume READE isn't right for you. More often than not, reading a record using the READ opcode isn't strictly applicable in many situations. Give it a try if you haven't to see what you've been missing.

Bob Cozzi, a black belt in Judo, started practicing Judo in 1974 and began to learn programming in 1975. Today, Bob runs RPG World [4], the most popular third-party, commercial RPG IV Training Event in the world. The next RPG World Conference [5] is open to all, and is coming up in May 2008.

Copyright © Penton Media

Source URL: http://systeminetwork.com/article/use-reade-opcode-please

Links:
[1] http://systeminetwork.com/author/bob-cozzi
[2] http://www.amazon.com/dp/1583041214?tag=rw0c-20&camp=14573&creative=327641&linkCode=as1&creativeASIN=1583041214&adid=0FDDKRAMASMW6SZB3462&
[3] http://www.amazon.com/dp/1583041214?tag=rw0c-20&camp=14573&creative=327641&linkCode=as1&creativeASIN=1583041214&adid=0FDDKRAMASMW6SZB3462&
[4] http://www.rpgworld.com
[5] http://www.rpgworld.com