The latest Technology Refresh for IBM i 7.3, TR 6, has seen two new subfields added to RPG's Program Data Structure. This data strucutre provides me with a wealth information about the status of the program while it is running, and when it errors.

I always add the Program Status Data Structure, PSDS , to all of my RPG programs. I can dump the program and learn a lot of what happened from the information contains within the PSDS .

Rather than manually entering the same data structure into every program, I have my PSDS in a member I just copy, or include, it into the source members of others.

Below is my definition for the PSDS . If you are creating your own you can give the data structure and subfields whatever names you like.

**free dcl-ds Pgm psds qualified ; Proc char(10) ; // Module or main procedure name StsCde zoned(5) ; // Status code PrvStsCde zoned(5) ; // Previous status SrcLineNbr char(8) ; // Source line number Routine char(8) ; // Name of the RPG routine Parms zoned(3) ; // Number of parms passed to program ExceptionType char(3) ; // Exception type ExceptionNbr char(4) ; // Exception number Exception char(7) samepos(ExceptionType) ; Reserved1 char(4) ; // Reserved MsgWrkArea char(30) ; // Message work area PgmLib char(10) ; // Program library ExceptionData char(80) ; // Retrieved exception data Rnx9001Exception char(4) ; // Id of exception that caused RNX9001 LastFile1 char(10) ; // Last file operation occurred on Unused1 char(6) ; // Unused DteEntered char(8) ; // Date entered system StrDteCentury zoned(2) ; // Century of job started date LastFile2 char(8) ; // Last file operation occurred on LastFileSts char(35) ; // Last file used status information JobName char(10) ; // Job name JobUser char(10) ; // Job user JobNbr zoned(6) ; // Job number StrDte zoned(6) ; // Job started date PgmDte zoned(6) ; // Date of program running PgmTime zoned(6) ; // Time of program running CompileDte char(6) ; // Date program was compiled CompileTime char(6) ; // Time program was compiled CompilerLevel char(4) ; // Level of compiler SrcFile char(10) ; // Source file name SrcLib char(10) ; // Source file library SrcMbr char(10) ; // Source member name ProcPgm char(10) ; // Program containing procedure ProcMod char(10) ; // Module containing procedure SrcLineNbrBin bindec(2) ; // Source line number as binary LastFileStsBin bindec(2) ; // Source id matching positions 228-235 User char(10) ; // Current user ExtErrCode int(10) ; // External error code IntoElements int(20) ; // Elements set by XML-INTO or DATA-INTO (7.3) InternalJobId char(16) ; // Internal job id (7.3 TR6) SysName char(8) ; // System name (7.3 TR6) end-ds ;

Two things to note are:

As the data structure has been written in totally free format RPG I have to start the source member with **FREE . If I don't do so when the member is copied into the other source member by the RPG compiler it copies the member starting in the seventh column of the source member. I have used the SAMEPOS keyword to combine the Exception Type and Exception Number subfields.

The two new subfields are the last two in the data structure. I have to admit I am unsure what the "Internal job id" is.

Just to give you a glimpse of the information I can see in the PSDS I wrote this program of just three lines:

01 **free 02 /include cpysrc,rpg_psds 03 *inlr = *on ;

Lines 2: I have used the /INCLUDE compiler directive to copy the contents of the PSDS into this program.

After compiling the program I started debug and put added a break point on the last line of the program. I see the following in the PSDS :

EVAL pgm PGM.PROC = 'TESTPGM ' PGM.STSCDE = 00000. PGM.PRVSTSCDE = 00000. PGM.SRCLINENBR = '00000000' PGM.ROUTINE = '*DETC ' PGM.PARMS = 000. PGM.EXCEPTION = ' ' PGM.EXCEPTIONTYPE = ' ' PGM.EXCEPTIONNBR = ' ' PGM.RESERVED1 = '0000' PGM.MSGWRKAREA = ' ' PGM.PGMLIB = 'MYLIB ' PGM.EXCEPTIONDATA = ....5...10...15...20...25...30...35...40...45...50...55...60 1 ' ' 61 ' ' PGM.RNX9001EXCEPTION = ' ' PGM.LASTFILE1 = ' ' PGM.UNUSED1 = ' ' PGM.DTEENTERED = '06122019' PGM.STRDTECENTURY = 20. PGM.LASTFILE2 = ' ' PGM.LASTFILESTS = ' ' PGM.JOBNAME = 'QPADEV0001' PGM.JOBUSER = 'SIMON ' PGM.JOBNBR = 526346. PGM.STRDTE = 061219. PGM.PGMDTE = 061219. PGM.PGMTIME = 032844. PGM.COMPILEDTE = '061219' PGM.COMPILETIME = '032826' PGM.COMPILERLEVEL = '0001' PGM.SRCFILE = 'DEVSRC ' PGM.SRCLIB = 'MYLIB ' PGM.SRCMBR = 'TESTPGM ' PGM.PROCPGM = 'TESTPGM ' PGM.PROCMOD = 'TESTPGM ' PGM.SRCLINENBRBIN = 48. PGM.LASTFILESTSBIN = 48. PGM.USER = 'SIMON ' PGM.EXTERRCODE = 0 PGM.INTOELEMENTS = 0 PGM.INTERNALJOBID = ' ? ? ?" sM´ÞmÇµ?' PGM.SYSNAME = 'DEV730 '

As I work in a multiple partition world being able to retrieve the System Name is going to help me to be able to condition code depending upon which partition the program is running on, without retrieving the network name using a CL command.

You can learn more about the Program Status Data Structure from the IBM website here.

This article was written for IBM i 7.4 and 7.3 TR6.