RPG Data Structures
RPG can describe storage areas for use during execution.
The IBM RPG compiler allows you to define an area in storage called a data structure. The layout of the fields, called subfields, can be used to further define the storage area.
Reading into a DS
This snippet demonstrates a method of reading from a file into a data structure. Create a pointer to reference the input data. Define a data structure or as many data structures as required to contain the data values. This allows you to reference multiple records simultaneously in the program. This would allow the user to save a copy of the original data retrieved. Before updating the record with changes, the database record could be retrieved again to be compared to the original values to determine if any of the original field values have been changed.FINPUT IF E Disk D Prt_toData S * D Ds_Input E DS extname(INPUT) D based(Ptr_toData) D Ds_Input1 E DS extname(INPUT) D prefix(D1_) D Ds_Input2 E DS extname(INPUT) D prefix(D2_) C eval Ptr_toData = %addr(Ds_Input1) C read INPUT . . . C eval Ptr_toData = %addr(Ds_Input2) C read INPUT C return PARM PRM5 5
Writing using DS
This is a simple RPG program used to create an FTP script file to push data to a server. The program reads in a database file, which contains FTP commands. The program writes a source file member out, setting the value of the replacement variable (the scan for the ampersand) with the name of the file to be transmitted. Note the use of the *OUTPUT function on the externally defined DDS. This allows the program to write the source file record directly from the data structure.FBBTSCRPF IF E K DISK FFTPSRCPF O F 112 DISK D PGMDS ESDS EXTNAME(SWPSTSP) Pgm status map D FTPSRC E DS EXTNAME(QFTPSRC:*OUTPUT) Source file map D DateFmt DS D ThisDateISO 8S 0 D ThisDateYMD 6S 0 OVERLAY(DateFmt:3) d x S 3 0 d z S 3 0 d unknownFile S n d invoiceFile S n d creditRequest S n d type S 4a inz('RT01') d BBT105RP Pr d FileName 20 d BBT105RP PI d FileName 20 ThisDateISO = %dec(%date(): *ISO); SETLL type BBTSCRPF; DOU %eof(BBTSCRPF); READE type BBTSCRPF; IF not %eof(BBTSCRPF); srcseq = scrseq; srcdat = ThisDateYMD; z = %scan('&': scrtxt: 1); IF z = 0; srcdta = scrtxt; ELSE; srcdta = %subst(scrtxt:1:z-1) + ' ' + %trim(fileName); ENDIF; write FTPSRCPF FTPSRC; ENDIF; ENDDO; *INLR = *ON; RETURN; /end-free 3
LIKEREC keyword for DS
Keyword LIKEREC is used to define a data structure, data structure subfield, prototyped return value, or prototyped parameter like a record. The subfields of the data structure will be identical to the fields in the record. The sample below illustrates using the LIKEREC keyword to create input and output data structures. The procedure reads directly into the input data structure and updates from the output data strutcure.Dcl-Proc setCSGFileName export ; dcl-pi setCSGFileName ; mailType char(25) const ; end-pi; dcl-f CSGCURPF disk(*ext) usage(*input:*update:*output) usropn; dcl-ds ifileName likerec(RCSGCUR:*input); dcl-ds oFileName likerec(RCSGCUR:*output); Dcl-S ISOdate date inz(*job) ; Dcl-S ISOChar char(8) ; Dcl-S CurrMMDD char(4) ; Dcl-S ReUseName char(4) ; Dcl-S thisValue varchar(200) ; Exec SQL select ecvalu into :thisvalue From CSGCTLPF Where ecarea = 'FILENAME' And ecname = 'REUSE' fetch first row only ; reuseName = %trimR(thisValue); Clear iFileName ; Open CSGCURPF ; chain 1 CSGCURPF iFileName ; ISOChar = %char(ISOdate:*iso0) ; // job date CurrMMDD = %subst(ISOchar:5:4) ; // current MMDD oFileName = iFileName ; oFileName.dftype = getCSGtransMode() ; If oFileName.dftype = 'T' ; // Test file ofileName.dfprfx = getCSGprefix() ; oFileName.dfsep1 = '-' ; Else ; ofileName.dfprfx = *blanks ; // Blank prefix oFileName.dfsep1 = *blank ; // for production file EndIf ; oFileName.dfmmdd = %subst(ISOchar:5:4) ; // MMDD oFileName.dftype = getCSGstatementCode() ; // CSG statement code oFileName.dfMail = getCSGmailStream(mailType) ; // mail type Select ; when ofileName.dfmmdd <> iFileName.dfmmdd ; ofileName.dfseq1 = 1 ; ofileName.dfseq2 = 1 ; When ofileName.dfmail <> iFilename.dfmail ; oFileName.dfseq1 = 1 ; ofileName.dfseq2 = 1 ; When ofileName.dfmail = iFilename.dfmail ; If reuseName = 'R' ; ofileName.dfseq2= iFilename.dfseq2 + 1 ; Else ; ofileName.dfseq1 = iFilename.dfseq1 + 1; ofileName.dfseq2 = 1 ; EndIf ; When ifileName.dfseq1 = 99 ; oFileName.dfseq1 = 1 ; ofileName.dfseq2 = 1 ; Other ; ofileName.dfseq2= iFilename.dfseq2 + 1 ; EndSL ; oFileName.dfsep2 = '.' ; oFileName.dfsep3 = '.' ; oFileName.dfextn = getCSGfileExt() ; If %found(CSGCURPF) ; Update rCSGCUR oFileName; Else ; Write rCSGCUR oFileName; EndIf ; Close CSGCURPF ; return ; End-Proc setCSGFileName ;
Each time a job is started the i OS system creates a local data area, (LDA) initialized with blanks, for a length of 1024 and type *CHAR. When a job is submitted (SBMJOB command), the value of the submitting job's local data area is copied into the submitted job's local data area, automatically. The use of the LDA isn't encouraged, though referencing the data area is easy enough. Specify *LDA for the DTAARA keyword on the CHGDTAARA, RTVDTAARA, and DSPDTAARA commands or *LDA for the substring built-in function (%SST).
Dcl-DS LDA dtaara(*lda); PER zoned(4:0) pos(501); YEAR zoned(4:0) pos(505); EYMD zoned(8:0) pos(509); End-DS ;