In a previous topic, you should have written a very short RPG III program
to change the first record in the CUST file.
Let's add so more statements to the program so that it will read all records
in the file and change the zip code for everyone in Tennessee.
You may want to read this very short article on data navigation first:
Your program will still reference the CUST file, so, use DSPLIBL to display your library list. If you don't see your user library in the list, use the CHGCURLIB USER999 command. This will change your current library to USER999. Remember that when I say USER999, I mean your user ID.
You can look at your data file with the command:
RUNQRY QRYFILE(CUST)
Now, use PDM to copy your old program. Start PDM (STRPDM). You should see something like:
Your screen should look like:
Remember from your PDM lesson that this is trying to show you a list of all of the RPG
Work with Members Using PDM
Before we make the changes to the program we need to discuss different ways to write
a loop. We want a loop that will read every record in the CUST file and change the
records that have TN (Tennessee) as the state.
I always think of a loop as saying:
You could write the instructions above in RPG III like this:
Then, name the first line of the Calculations READIT.
The, try to read a record (if END OF FILE, move ON to indicator# 90)
If indicator# 90 is *OFF
Move …
Move …
Update …
Go back to the first line of the program
Turn on the "magic" LR indicator
End the program
This will work. The only problem is that for about 15 years, it
has been considered bad style to use GOTO statements. This is
an industry trend that includes all languages and all computers.
The reason is that long programs are hard to understand when there
are a lot of GOTO statements. Programs with lots of GOTO's are
nicknamed spaghetti programs because the statements can be as
hard to follow as a strand of spaghetti.
SO, the industry prefers that we use DO statements. We can use
a DO WHILE or a DO UNTIL. This still leaves us with 2 good
ways to write the loop. I prefer the first because it looks a
lot like the GOTO loop but without the GOTO:
The DOWEQ statement says that as long as indicator # 90 is OFF,
execute all of the statements until the ENDDO (End DO) statement.
Then, start back at the top (a lot like a GOTO). If indicator # 90
is still OFF, execute the statements again. Eventually, the program
will read all 1,000+ records in the file. When it does, indicator # 90
will be turned ON.
When indicator # 90 is ON, the program will not update the record and
it will not continue to loop.
The other way to code the loop is with what is called a priming read
statement. This method needs 2 READ statements but does not need
the IF statement.
If looks like:
Either of these 2 methods is considered good code. I prefer the
first.
Using the first acceptable loop, add the IF statement to test to
see if the state is TN. Also, replace the code so that it changes
the ZIP to 987650000.
First, do this by putting in an IF statement like this:
In RPG, subroutines begin with a BEGSR (BEGIN SUBROUTINE) statement
which also has the name of the subroutine. They end with ENDSR
(END SUBROUTINE). They are run with the EXSR (EXECUTE SUBROUTINE)
command.
If we move the update logic to a subroutine named UPD, the program
looks cleaner. Also, we can add "COMMENTS" records. Any statement with
a * after the record type, is a "COMMENT". In fact you can even
remove the record type (the C or F in column 6).
With a few comment lines added to define the sections of the program,
we get a pretty readable program:
Then use RUNQRY QRYFILE(CUST) to see the data. If you scroll
right by hitting F20 (actually Shift and F8) you will see
that you changed the zip in all of the records with TN as CSSTE.
Are you starting to have fun? I hope so.
The next lesson will be short. It will put these statements in
the RPG ILE version. You will see how much prettier ILE code
is than RPG III.
---------------------------------------------------------------------
AS/400 Programming Development Manager (PDM)
Select one of the following:
1. Work with libraries
2. Work with objects
3. Work with members
4. Work with projects
5. Work with groups
6. Work with parts
9. Work with user-defined options
---------------------------------------------------------------------
Key in 3 and hit ENTER. Fill in the screen to look like:
Specify Members to Work With
Type choices, press Enter.
File . . . . . . . . . . QRPGSRC Name, F4 for list
Library . . . . . . . . user999 *LIBL, *CURLIB, name
Member:
Name . . . . . . . . . *ALL *ALL, name, *generic*
Type . . . . . . . . . *ALL *ALL, type, *generic*,
-----------------------------------------------------------------------
Of course, change the USER999 to your user ID. Hit ENTER now.
File . . . . . . QRPGSRC
Library . . . . USER999 Position to . . . . .
Type options, press Enter.
2=Edit 3=Copy 4=Delete 5=Display 6=Print 7=Rename
8=Display description 9=Save 13=Change text 14=Compile 15=Create module..
Opt Member Type Text
TUTR001 RPG Change the first record in CUST file
Key a 3 as the option next to TUTR001. Hit ENTER and then fill in the screen
to copy the program and name it TUTR004:
Copy Members
From file . . . . . . . : QRPGSRC
From library . . . . : USER999
Type the file name and library name to receive the copied members
To file . . . . . . . . QRPGSRC Name, F4 for list
To library . . . . . USER999
To rename copied member, type New Name, press Enter.
Member New Name
TUTR001 TUTR004
Hit ETER and you should now see the copied program in your list. You may
want to change the description of the program so you'll remember which program
does what. Your screen should look like:
File . . . . . . QRPGSRC
Library . . . . USER000 Position to . . . . .
Type options, press Enter.
2=Edit 3=Copy 4=Delete 5=Display 6=Print 7=Rename
8=Display description 9=Save 13=Change text 14=Compile 15=Create
Opt Member Type Text
TUTR001 RPG Change the first record in CUST file
TUTR004 RPG Change all TN records in CUST file
Key a 2 next to TUTR004 so you can change the source statements to the program.
Try to Read a record from the file
If there was a record then
change it
update it
Go back and try to read the next record
Remember that when RPG III reads a record, you must specify which indicator to turn on
it there are no more records; that is, it is END OF FILE.
FCUST UF E DISK
C READIT TAG
C READ CUST 90
C *IN90 IFEQ *OFF
C MOVE *BLANK CSADR1
C MOVEL'456 OAK' CSADR1
C UPDATCSREC
C GOTO READIT
C ENDIF
C MOVE *ON *INLR
C RETRN
This program says to define a file named CUST.
FCUST UF E DISK
C *IN90 DOWEQ*OFF
C READ CUST 90
C *IN90 IFEQ *OFF
C MOVE *BLANK CSADR1
C MOVEL'456 OAK' CSADR1
C UPDATCSREC
C ENDIF
C ENDDO
C MOVE *ON *INLR
C RETRN
This program defines the file and then starts a DO loop.
FCUST UF E DISK
C READ CUST 90
C *IN90 DOWEQ*OFF
C MOVE *BLANK CSADR1
C MOVEL'456 OAK' CSADR1
C UPDATCSREC
C READ CUST 90
C ENDDO
C MOVE *ON *INLR
C RETRN
Here, the first record is read before the DO begins. The
statements are executed and the READ statement is at the
end of the DO loop.
C CSSTE IFEQ 'TN'
C MOVE 987650000 CSZIP
C UPDATCSREC
C ENDIF
So, the whole program looks like:
FCUST UF E DISK
C *IN90 DOWEQ*OFF
C READ CUST 90
C *IN90 IFEQ *OFF
C CSSTE IFEQ 'TN'
C MOVE 987650000 CSZIP
C UPDATCSREC
C ENDIF
C ENDIF
C ENDDO
C MOVE *ON *INLR
C RETRN
This is considered good code by most programmers. But it really
helps to move the update logic to a separate place in the program
as a subroutine. This is done here only to help readability. It
doesn't change the outcome.
FCUST UF E DISK
*-----------------------------------------------------
C *IN90 DOWEQ*OFF
C*
C READ CUST 90
C *IN90 IFEQ *OFF
C EXSR UPD
C ENDIF
C ENDDO
C*
C MOVE *ON *INLR
C RETRN
*-----------------------------------------------------
C UPD BEGSR
C*
C CSSTE IFEQ 'TN'
C MOVE 987650000 CSZIP
C UPDATCSREC
C ENDIF
C*
C ENDSR
*------------------------------------------------------
Now, compile this (remember… option 14) and run it (CALL TUTR004).