Here is a utility that will convert any iSeries database file to CSV (Comma Seperated Values) format with a delimiter of your choice. You can choose the delimiter
because it is very possible to have a comma in a description. So choose wisely.
I was forced to write this utility and here is why. I had a project to transfer data files from the iSeries 400 to a server that was running California Software Baby 400 system.
Seems simple enough just use the CPYFRMSTMF command or the CPYFRMIMPF right?
Yeah I thought so too. Well as I tried to use these commands as I have used them before and they work just fine if you have a good database file. But IBM did not think of everything
that programmers can do to a database file.
In my case I ran across (and not in just one file) packed numeric data. So what is the problem you ask? The data length of these packed fields were 1 bytes and 2 bytes. Why would you pack a 1 byte numeric field or even a 2 byte numeric field? The above mentioned command did not stop but they did not work either. Can you guess what they did? ……. Ok times up, they took those fields and extended them by 1 byte so the 1 byte packed became 2 bytes and the 2 bytes became 3 bytes. No matter what I did I could not get the file converted correctly on iSeries.
So either I can write a 100 or so programs (which I decided not to do) or write a utility to do all the work for me. Which is what I did and I am sharing this with whoever wants to use it. Feel free to use it and to make what ever changes you need for your use.
All the work is done in QTEMP. The process creates a work file call CVFILEO and a
temporary library with QRPGLESRC and a temporary program called CVPGM. The temp library is the use name with a ‘@’ in front of it. Example: if the user name is kfoland
the library name will be @kfoland.
So we have one work file called CVFILEO.
One command called CVF2CSV. Compiled to call CV0CL.
Two CL programs CV0CL and CV1CL.
Two RPGLE programs CV1 and CV2.
The simple process is as follows:
1. Delete temp files
2. Create duplicate object CVFILEO into QTEMP
3. Display field description on the incoming file into a file called CVFILE
4. Call CV1 to get the record length and call CV1CL to build the flat file with the given
record length.
5. Create the temp library.
6. Create QRPGLESRC in the temp library
7. Add the physical file member CVPGM to QRPGLESRC in the temp library
8. Call CV2 to read the incoming file and to create the temp program CVPGM.
9. Compile CVPGM
10. Call CVPGM
11. Copy the flat file from QTEMP to the out going file.
To get started, compile the file, command and the programs.
Prompt up the command and fill out the parms or just call CV0VL with the following parms.
PARM(&FILE &LIBR &TFILE &TLIBR &DEM)
where
&FILE = database file to be converted
&LIBR = library were the database file is located
&TFILE = name you want for the converted file
&TLIBR = library where the converted file will be
&DEM = the delimiter you want to use. Choose wisely
After the process runs you can check out the temp library and the program that was created in QSYS as the library will get deleted at the beginning of the process. You can change this if you want to delete the library at the end of the process. The process will delete any files or libraries in QTEMP as it runs.
This has help me so I hope it can help others as well.
-
/********************************************/
-
/* COMMAND NAME IS CVF2CSV */
-
/* This command will call CV0CL to convert a database file*/
-
/* to CSV format with your choice of delimiter */
-
/********************************************/
-
-
CMD PROMPT(‘Convert File to CSV Format’)
-
PARM KWD(FROMFILE) TYPE(*CHAR) LEN(10) +
-
PROMPT(‘Enter File to Convert’)
-
PARM KWD(FROMLIBR) TYPE(*CHAR) LEN(10) +
-
PROMPT(‘Enter Library for Input File’)
-
PARM KWD(TOFILE) TYPE(*CHAR) LEN(10) +
-
PROMPT(‘Converted File Name’)
-
PARM KWD(TOLIBR) TYPE(*CHAR) LEN(10) +
-
PROMPT(‘Library for Converted File’)
-
PARM KWD(DELIMITER) TYPE(*CHAR) LEN(1) DFT(‘~’) +
-
PROMPT(‘Delimiter’)
-
/******************************************/
-
/* CL name is cv0cl */
-
/* CL to run the process to convert a file passed to csv */
-
/* file format */
-
/******************************************/
-
-
PGM PARM(&FILE &LIBR &TFILE &TLIBR &DEM)
-
DCL VAR(&LIBR) TYPE(*CHAR) LEN(10)
-
DCL VAR(&FILE) TYPE(*CHAR) LEN(10)
-
DCL VAR(&TLIBR) TYPE(*CHAR) LEN(10)
-
DCL VAR(&TFILE) TYPE(*CHAR) LEN(10)
-
DCL VAR(&USER) TYPE(*CHAR) LEN(10)
-
DCL VAR(&WLIBR) TYPE(*CHAR) LEN(10)
-
DCL VAR(&DEM) TYPE(*CHAR) LEN(1)
-
DCL VAR(&LENGTH) TYPE(*CHAR) LEN(5)
-
DCL VAR(&MSGID) TYPE(*CHAR) LEN(7)
-
DCL VAR(&MSG) TYPE(*CHAR) LEN(100)
-
DCL VAR(&MSGF) TYPE(*CHAR) LEN(10)
-
MONMSG MSGID(CPF0000) EXEC(GOTO CMDLBL(ERROR))
-
RTVJOBA USER(&USER)
-
CHKOBJ OBJ(&LIBR/&FILE) OBJTYPE(*FILE)
-
DLTF FILE(QTEMP/CVFILE)
-
MONMSG MSGID(CPF0000)
-
DLTF FILE(QTEMP/CVFLAT)
-
MONMSG MSGID(CPF0000)
-
DLTF FILE(QTEMP/CVFILEO)
-
MONMSG MSGID(CPF0000)
-
CRTDUPOBJ OBJ(CVFILEO) FROMLIB(KFOLAND) OBJTYPE(*FILE) +
-
TOLIB(QTEMP)
-
DSPFFD FILE(&LIBR/&FILE) OUTPUT(*OUTFILE) +
-
OUTFILE(QTEMP/CVFILE)
-
OVRDBF FILE(CVFILE) TOFILE(QTEMP/CVFILE)
-
OVRDBF FILE(CVFILEO) TOFILE(QTEMP/CVFILEO)
-
CALL PGM(CV1) PARM(&LENGTH)
-
IF COND(&LENGTH *NE ‘00000′) THEN(DO)
-
CHGVAR VAR(&WLIBR) VALUE(‘@’ *TCAT %SUBSTRING(&USER +
-
1 9))
-
-
/* create the temp library for the temp program */
-
-
DLTLIB LIB(&WLIBR)
-
MONMSG MSGID(CPF0000)
-
CRTLIB LIB(&WLIBR)
-
CRTSRCPF FILE(&WLIBR/QRPGLESRC) RCDLEN(112)
-
ADDPFM FILE(&WLIBR/QRPGLESRC) MBR(cvpgm) +
-
TEXT(‘Convert program’) SRCTYPE(RPGLE)
-
OVRDBF FILE(cvpgm) TOFILE(&WLIBR/QRPGLESRC) +
-
MBR(cvpgm)
-
OVRDBF FILE(CVFLAT) TOFILE(QTEMP/CVFLAT)
-
CALL PGM(CV2) PARM(&FILE &LENGTH &DEM)
-
DLTOVR FILE(*ALL)
-
OVRDBF FILE(&FILE) TOFILE(&LIBR/&FILE)
-
CRTBNDRPG PGM(&WLIBR/CVPGM) SRCFILE(&WLIBR/QRPGLESRC) +
-
OUTPUT(*PRINT)
-
OVRDBF FILE(&FILE) TOFILE(&LIBR/&FILE)
-
OVRDBF FILE(CVFLAT) TOFILE(QTEMP/CVFLAT)
-
CALL PGM(&WLIBR/cvpgm)
-
DLTOVR FILE(*ALL)
-
CPYF FROMFILE(QTEMP/CVFLAT) TOFILE(&TLIBR/&TFILE) +
-
MBROPT(*REPLACE) CRTFILE(*YES)
-
ENDDO
-
GOTO CMDLBL(ENDPGM)
-
/* */
-
/*—————————————*/
-
/* NORMAL PROGRAM EXIT */
-
/*—————————————*/
-
/* */
-
-
EXIT: GOTO CMDLBL(ENDPGM)
-
/* */
-
/*—————————————*/
-
/* ERROR HANDLING ROUTINE */
-
/*—————————————*/
-
/* */
-
-
ERROR: RCVMSG MSGDTA(&MSG) MSGID(&MSGID) MSGF(&MSGF)
-
MONMSG MSGID(CPF0000)
-
SNDPGMMSG MSGID(&MSGID) MSGF(&MSGF) MSGDTA(&MSG) +
-
MSGTYPE(*ESCAPE)
-
MONMSG MSGID(CPF0000)
-
GOTO CMDLBL(ENDPGM)
-
/* */
-
/* */
-
-
ENDPGM: ENDPGM
-
H OPTION(*Srcstmt : *Nodebugio)
-
A********************************************
-
A* program name IS cv1 *
-
A* figure the record length of the file being converted *
-
A********************************************
-
A*
-
fCvfile IF e Disk Usropn
-
fCvfileo o e Disk
-
A*
-
d @Total s 5 0
-
d @FIELDS s 5 0
-
d @Start s 5 0
-
d @Length s 5
-
A*
-
c *Entry Plist
-
c Parm @Length
-
A* Open AND READ the file AND figure the new length
-
A* after ALL the packed FIELDS are unpacked
-
c Open Cvfile
-
c DoU %Eof(Cvfile)
-
c READ Cvfile
-
c IF NOT %Eof(Cvfile)
-
c
-
A*
-
c Eval @FIELDS = Whnfld
-
A* IF packed then USE the unpacked length
-
c IF Whfldt = ‘P’
-
c Eval Whfldb = Whfldd
-
c EndIf
-
c IF Whfldt = ‘A’
-
c Eval @Total = @Total + 2
-
c EndIf
-
c IF Whfldp <> *Zeros
-
c Eval @Total = @Total + 2
-
c EndIf
-
A* ADD TO get the new total record length
-
c Eval @Total = @Total + Whfldb
-
A*
-
A*
-
c EndIf
-
c EndDo
-
A*
-
c Close Cvfile
-
c Eval @Total = @Total + @FIELDS
-
c Move @Total @Length
-
c IF @Total <> *Zeros
-
A* CREATE the flat file
-
c Call ‘CV1CL’
-
C Parm @Total
-
A*
-
c EndIf
-
A*
-
c Eval @Start = 0
-
A* Open AND READ the file AND output info TO work file
-
c Open Cvfile
-
c DoU %Eof(Cvfile)
-
c READ Cvfile
-
c IF NOT %Eof(Cvfile)
-
A*
-
A* IF packed then USE the unpacked length
-
c IF Whfldt = ‘P’
-
c Eval Whfldb = Whfldd
-
c Eval Whfldt = ‘S’
-
c EndIf
-
A*
-
c IF @Start = *Zeros
-
c Eval @Start = 1
-
c Eval Cvstart = 1
-
c Eval Cvend = Whfldb
-
c Else
-
c Eval Cvstart = Cvend + 1
-
c Eval Cvend = Cvend + Whfldb
-
c EndIf
-
A*
-
c Eval Cvfname = Whfile
-
c Eval Cvfield = Whfldi
-
c Eval Cvtype = Whfldt
-
c Eval Cvlength = Whfldb
-
c Eval Cvdec = Whfldp
-
c Eval Cvformat = Whname
-
c WRITE Cvrec
-
A*
-
A*
-
c EndIf
-
c EndDo
-
c Close Cvfile
-
A*
-
A*
-
c Eval *Inlr = *ON
-
/*****************************************************/
-
/* cl name is cv1cl */
-
/* cl to build a temp flat file based on parms sent */
-
/* into the program */
-
/*****************************************************/
-
-
PGM PARM(&LENGTH)
-
DCL VAR(&LENGTH) TYPE(*DEC) LEN(5 0)
-
DLTF FILE(QTEMP/CVFLAT)
-
MONMSG MSGID(CPF0000)
-
CRTPF FILE(QTEMP/CVFLAT) RCDLEN(&LENGTH)
-
END: ENDPGM
-
H OPTION(*Srcstmt : *Nodebugio)
-
A**********************************************************************
-
A* program name IS cv2 *
-
A* this program will WRITE the program needed TO convert the file *
-
A* TO CSV format *
-
A**********************************************************************
-
A*
-
fCvfileo IF e Disk Prefix(x_) Usropn
-
fCvpgm uf a f 114 Disk
-
A*
-
d Rspec Ds
-
d Rrec 112
-
A*
-
d @File s 10
-
d @Length s 5
-
d @Dem s 1
-
d @Char5 s 5
-
d @Char2 s 2
-
d @Cvfield s LIKE(x_Cvfield)
-
A*
-
A* output the first d spec record
-
c Eval %Subst(Rrec:18:1) = ‘d’
-
c Eval %Subst(Rrec:20:18) = ‘Key S ‘
-
c Eval %Subst(Rrec:50:2) = ‘10′
-
c Except Drecadd
-
c Eval %Subst(Rrec:19:93) = *Blanks
-
A* output the first d spec record
-
c Eval %Subst(Rrec:20:18) = ‘FlatDs Ds’
-
c Except Drecadd
-
c Eval %Subst(Rrec:19:93) = *Blanks
-
A*
-
A* open the file AND output the rest of the d spec
-
c Open Cvfileo
-
c DoU %Eof(Cvfileo)
-
c READ Cvfileo
-
c IF NOT %Eof(Cvfileo)
-
A*
-
c IF x_Cvtype = ‘A’
-
c Eval %Subst(Rrec:51:13) = ‘1a Inz(’‘"’‘)’
-
c Except Drecadd
-
c Eval %Subst(Rrec:19:93) = *Blanks
-
c EndIf
-
A* IF there IS a decimal then increase the length BY 2
-
A* this IS TO allow FOR the decimal IN the flat file
-
A* AND FOR the sign
-
c IF x_Cvdec > *Zeros
-
c Eval x_Cvlength = x_Cvlength + 2
-
c** Eval %Subst(Rrec:56:9) = ‘Inz ‘
-
c EndIf
-
A* the FIELD name IN the program can NOT be the same
-
A* AS the file name.
-
c IF x_Cvfield = x_Cvformat
-
c Eval x_Cvfield = ‘xx ‘
-
c EndIf
-
A*
-
c Move x_Cvlength @Char5
-
c Eval %Subst(Rrec:19:18) = x_Cvfield
-
c Eval %Subst(Rrec:47:5) = @Char5
-
c* Eval %Subst(Rrec:52:1) = x_Cvtype
-
c Eval %Subst(Rrec:52:1) = ‘a’
-
*
-
c* IF x_Cvtype = ‘S’
-
c* Move x_Cvdec @Char2
-
c* Eval %Subst(Rrec:53:2) = @Char2
-
c* Else
-
c Eval %Subst(Rrec:53:2) = ‘ ‘
-
c* EndIf
-
A*
-
c Except Drecadd
-
c Eval %Subst(Rrec:19:93) = *Blanks
-
A*
-
c IF x_Cvtype = ‘A’
-
c Eval %Subst(Rrec:51:13) = ‘1a Inz(’‘"’‘)’
-
c Except Drecadd
-
c Eval %Subst(Rrec:19:93) = *Blanks
-
c EndIf
-
A* SET the delimiter
-
c Eval %Subst(Rrec:51:13) = ‘1a Inz(’‘ ‘‘)’
-
c Eval %Subst(Rrec:61:1) = @Dem
-
c Except Drecadd
-
c Eval %Subst(Rrec:19:93) = *Blanks
-
A*
-
c EndIf
-
c EndDo
-
A* close the file FOR the c spce
-
c Close Cvfileo
-
A****************************************************************************
-
A*
-
A* output the first c spec record
-
c Eval %Subst(Rrec:18:1) = ‘c’
-
c Eval %Subst(Rrec:38:3) = ‘DoU’
-
c Eval %Subst(Rrec:48:16) = ‘%Eof( )’
-
c Eval %Subst(Rrec:53:10) = @File
-
A*
-
c Except Crecadd
-
c Eval %Subst(Rrec:19:93) = *Blanks
-
A*
-
c Eval %Subst(Rrec:38:18) = ‘ ‘
-
c Eval %Subst(Rrec:38:4) = ‘Read’
-
c Eval %Subst(Rrec:48:10) = @File
-
A*
-
c Except Crecadd
-
c Eval %Subst(Rrec:19:93) = *Blanks
-
A*
-
c Eval %Subst(Rrec:38:18) = ‘ ‘
-
c Eval %Subst(Rrec:38:3) = ‘If ‘
-
c Eval %Subst(Rrec:48:20) = ‘Not %Eof( )’
-
c Eval %Subst(Rrec:57:10) = @File
-
A*
-
c Except Crecadd
-
c Eval %Subst(Rrec:19:93) = *Blanks
-
A*
-
A* open the file AND output the rest of the c specs
-
c Open Cvfileo
-
c DoU %Eof(Cvfileo)
-
c READ Cvfileo
-
c IF NOT %Eof(Cvfileo)
-
A* save FIELD name
-
c Eval @Cvfield = x_Cvfield
-
A* the FIELD name IN the program can NOT be the same
-
A* AS the file name.
-
c IF x_Cvfield = x_Cvfname
-
c Eval x_Cvfield = ‘xx ‘
-
c EndIf
-
A*
-
A* SET up the KEY AND the chain TO CHECK FOR decimals
-
c IF x_Cvdec > *Zeros
-
A*
-
c Eval %Subst(Rrec:38:6) = ‘Clear ‘
-
c Eval %Subst(Rrec:62:10) = ‘Key ’
-
c Except Crecadd
-
c Eval %Subst(Rrec:38:6) = ‘MoveL ‘
-
c Eval %Subst(Rrec:48:1) = ””
-
c Eval %Subst(Rrec:49:10) = %subst(x_Cvfield:1:10)
-
c Eval %Subst(Rrec:59:1) = ””
-
c Eval %Subst(Rrec:62:10) = ‘Key ’
-
c Except Crecadd
-
c Eval %Subst(Rrec:19:93) = *Blanks
-
A*
-
A* do the chain
-
c Eval %Subst(Rrec:24:10) = ‘Key ’
-
c Eval %Subst(Rrec:38:6) = ‘Chain ‘
-
c Eval %Subst(Rrec:48:7) = ‘Cvfileo’
-
c Except Crecadd
-
c Eval %Subst(Rrec:19:93) = *Blanks
-
c Eval %Subst(Rrec:38:6) = ‘If ‘
-
c Eval %Subst(Rrec:48:17) = ‘Z_Cvdec <> *Zeros’
-
c Except Crecadd
-
c Eval %Subst(Rrec:19:93) = *Blanks
-
c Eval %Subst(Rrec:38:6) = ‘Eval ‘
-
c*************** Eval %Subst(Rrec:48:2) = ‘x_’
-
c Eval %Subst(Rrec:48:10) = x_Cvfield
-
c Eval %Subst(Rrec:60:9) = ‘= %Editc(’
-
c Eval %Subst(Rrec:69:2) = ‘x_’
-
c Eval %Subst(Rrec:71:10) = x_Cvfield
-
c Eval %Subst(Rrec:81:5) = ‘:’‘P’‘)’
-
c Except Crecadd
-
c Eval %Subst(Rrec:19:93) = *Blanks
-
c Eval %Subst(Rrec:38:6) = ‘Else ‘
-
c Except Crecadd
-
c Eval %Subst(Rrec:19:93) = *Blanks
-
A*
-
c EndIf
-
A*
-
c Eval %Subst(Rrec:38:6) = ‘Move ‘
-
c Eval %Subst(Rrec:48:2) = ‘x_’
-
c Eval %Subst(Rrec:50:10) = @Cvfield
-
c Eval %Subst(Rrec:62:10) = x_Cvfield
-
c Except Crecadd
-
c Eval %Subst(Rrec:19:93) = *Blanks
-
A*
-
c IF x_Cvdec > *Zeros
-
A*
-
c Eval %Subst(Rrec:38:6) = ‘EndIf ‘
-
c Except Crecadd
-
c Eval %Subst(Rrec:19:93) = *Blanks
-
c EndIf
-
A*
-
c EndIf
-
c EndDo
-
A* close the file
-
c Close Cvfileo
-
A*
-
c Eval %Subst(Rrec:38:6) = ‘Except’
-
c Eval %Subst(Rrec:48:7) = ‘Flatout’
-
c Except Crecadd
-
c Eval %Subst(Rrec:19:93) = *Blanks
-
A*
-
c Eval %Subst(Rrec:38:5) = ‘EndIf’
-
c Except Crecadd
-
c Eval %Subst(Rrec:19:93) = *Blanks
-
A*
-
c Eval %Subst(Rrec:38:5) = ‘EndDo’
-
c Except Crecadd
-
c Eval %Subst(Rrec:19:93) = *Blanks
-
A*
-
c Eval %Subst(Rrec:38:4) = ‘Eval’
-
c Eval %Subst(Rrec:48:11) = ‘*Inlr = *On’
-
c Except Crecadd
-
c Eval %Subst(Rrec:19:93) = *Blanks
-
A****************************************************************************
-
A*
-
A* output the o specs
-
c Eval %Subst(Rrec:18:1) = ‘o’
-
c Eval %Subst(Rrec:19:10) = ‘Cvflat ‘
-
c Eval %Subst(Rrec:29:4) = ‘eadd’
-
c Eval %Subst(Rrec:42:7) = ‘Flatout’
-
c Except Orecadd
-
c Eval %Subst(Rrec:19:93) = *Blanks
-
A*
-
c Eval %Subst(Rrec:19:10) = ‘ ‘
-
c Eval %Subst(Rrec:29:4) = ‘ ‘
-
c Eval %Subst(Rrec:42:7) = ‘Flatds ‘
-
c Except Orecadd
-
c Eval %Subst(Rrec:19:93) = *Blanks
-
A*
-
c Eval *Inlr = *ON
-
A*******************************************************
-
A* first time processing *
-
A*******************************************************
-
c *Inzsr Begsr
-
-
c *Entry Plist
-
c Parm @File
-
c Parm @Length
-
c Parm @Dem
-
A*
-
A* output the h spec record
-
c Eval %Subst(Rrec:18:1) = ‘h’
-
c* Eval %Subst(Rrec:20:29) =
-
c* ‘Option(*Srcstmt : *Nodebugio)’
-
c Except Hrecadd
-
c Eval %Subst(Rrec:19:93) = *Blanks
-
A*
-
A* open the file AND CHECK FOR formant name
-
c Open Cvfileo
-
c READ Cvfileo
-
c Close Cvfileo
-
A* output the f spec record
-
c Eval %Subst(Rrec:18:1) = ‘f’
-
c Eval %Subst(Rrec:19:10) = @File
-
c Eval %Subst(Rrec:29:6) = ‘if e’
-
c Eval %Subst(Rrec:48:4) = ‘Disk’
-
c Eval %Subst(Rrec:56:10) = ‘Prefix(x_)’
-
c Except Frecadd
-
c Eval %Subst(Rrec:19:93) = *Blanks
-
A*
-
c IF x_Cvfname = x_Cvformat
-
c Eval %Subst(Rrec:56:7) = ‘Rename(’
-
c Eval %Subst(Rrec:63:10) = x_Cvformat
-
c Eval %Subst(Rrec:73:3) = ‘:x)’
-
c Except Frecadd
-
c Eval %Subst(Rrec:19:93) = *Blanks
-
c EndIf
-
A*
-
A* output the f spec record
-
c Eval %Subst(Rrec:18:1) = ‘f’
-
c Eval %Subst(Rrec:19:10) = ‘Cvflat ‘
-
c Eval %Subst(Rrec:29:6) = ‘uf a f’
-
c Eval %Subst(Rrec:35:5) = @Length
-
c Eval %Subst(Rrec:48:4) = ‘Disk’
-
c Except Frecadd
-
c Eval %Subst(Rrec:19:93) = *Blanks
-
A* output the last f spec record
-
c Eval %Subst(Rrec:18:1) = ‘f’
-
c Eval %Subst(Rrec:19:10) = ‘Cvfileo ’
-
c Eval %Subst(Rrec:29:6) = ‘if e’
-
c Eval %Subst(Rrec:46:6) = ‘k Disk’
-
c Eval %Subst(Rrec:56:10) = ‘Prefix(z_)’
-
c Except Frecadd
-
c Eval %Subst(Rrec:19:93) = *Blanks
-
A*
-
A*
-
c #Inzsr Endsr
-
A*
-
oCvpgm eadd Hrecadd
-
o Rrec
-
A*
-
o eadd Frecadd
-
o Rrec
-
A*
-
o eadd Drecadd
-
o Rrec
-
A*
-
o eadd Crecadd
-
o Rrec
-
A*
-
o eadd Orecadd
-
o Rrec
-
A* FILE NAME CVFILEO
-
A* CONVERSION WORK FILE
-
A*
-
A R CVREC
-
A*
-
A CVFNAME 10A TEXT(‘FILE NAME’)
-
A CVFIELD 10A TEXT(‘FIELD NAME’)
-
A CVTYPE 1A TEXT(‘FIELD TYPE’)
-
A CVSTART 5S 0 TEXT(‘FIELD START’)
-
A CVEND 5S 0 TEXT(‘FIELD END ‘)
-
A CVLENGTH 5S 0 TEXT(‘FIELD LENGTH’)
-
A CVDEC 2S 0 TEXT(‘FIELD DEC ’)
-
A CVFORMAT 10A TEXT(‘FIELD FORMAT’)
-
A*
-
A K CVFIELD
Possible Related Links
Tip: Converting String to Number in QUERY/400PHP on iSeriesPost a Classified Ad
I came across an interesting and thought provoking post by Max Harris on his blog From Here to Modernity, where questions about I-O Strategies (when dealing with a critical table) evoked responses from more than 90 iSeries professionals.
Four options were presented as follows:
- Replacing F-specs in RPG program with SQL in all the programs or modules that use the table ( Embedded SQL ).
- Move I-O to a SRVPGM and have a procedure return the record format.
- Move I-O to a SRVPGM and have several procedures which return various data structures.
- Move I-O to a SRVPGM and have field getters and field setters (JAVA).
We all know that first option is not very efficient, but read the post and related comments and arrive at your own conclusion.
Possible Related Links
For SaleJobsAdvertise
Ever wondered about QSHELL? It is a UNIX shell on iSeries. To access QSHELL, type in STRQSH on the command line. But before you go any further, head out to Thibault Dambrine’s tutorial : Exploring iSeries QSHELL: Concepts & Tutorial.
This tutorial explains in simple language the syntax of Unix commands, where to find help, how permissions work, and the basics of how to write a QShell script.
Some background on QSHELL: To be fully Java compliant, IBM needed to supply a JDK (Java Development Kit) on its iSeries eServer that could run standard Java commands such as Java, Javac or Javadoc, the same way other (UNIX) systems could. There was only one snag, OS/400 was NOT ’a flavor of’ UNIX. The OS/400 IBM team resolved this hurdle by supplying a new ‘UNIX style shell‘ on the iSeries and appropriately named it ‘QSHELL‘.
Possible Related Links
iSeries RPG programming linksPHP on iSeriesFOR SALE: IBM iSeries Model 825
While searching for an open source software for my other project, I came across Open Source iSeries Toolkit. For those of you new to Open Source Software, it is a program in which the source code is available to the general public for use and/or modification from its original design free of charge. Open source code is typically created as a collaborative effort in which programmers improve upon the code and share the changes within the community. Open source sprouted in the technological community as a response to proprietary software owned by corporations. Learn more about it at opensource.org.
iSeries Toolkit is a bag of utilities that support Dynamic SQL, Messaging, IFS file access, User spaces, User indexes, Dynamic Native File Access, XML, and Source Generation. These RPGIV ILE and Java tools work on most recent releases of the iSeries and AS/400.
Get Involved
Apart from being a user of this toolkit, you can get involved as a developer. You can actually help developing the iSeries Toolkit by either fixing the bugs reported or adding / enhancing the utilities by checking the features requested. This open source project has a very active community that is constantly working on improving the toolkit. You can download the toolkit and try it yourself.
Here are some of the features requested:
- UDF suggestion for dates
- Include a complete list of subprocedures
- DMPSQL data from a table.
- ILE Module Information
- New feature in Seq().
- UserSpace Viewer.
- Add support for the Qp0lGetAttr API
- Update Debug info in CHGOBJ Command
- New SAVZIP Command
Are you ready to accept these challenging tasks?
If you have any comments or opinions, please click on "Comment" link below this article.
Possible Related Links
How to register for iSeries forumsConvert any iSeries database file to CSV formatiSeries Users Group Forums are now open
I am sure every RPG programmer is aware of Scott Klement’s Club Tech iSeries Programming Tips Newsletter, but do you know, he has few other goodies in his bag?
For rookie iSeries RPG programmers, he has a tutorial titled How to Learn RPG.
For iSeries programmers, who want to experiment with pointers, try having Fun with RPG pointers.
Learn about Reading and Writing from Integrated File System or if you are internet-inclined try Sockets and TCP Programming.
Possible Related Links
iSeries Users Group Forums are now openHomeIntroduction
*** The intention of these interview questions is to challenge my readers. I never intended to give out the answers. Those who seek answers, please use Google search for your quest. Google is your friend. Good Luck!
iSeries has evolved a lot since 1988, but interview questions have remained practically unchanged. Here are few of them which I came across on a forum. This post is also in the General forum. Feel free to contribute the answers to these questions either here in the comments area or in the forums area.
- How do you know if a record exists without doing a READ and CHAIN?
- What will be your approach in going either for OPNQRYF or Logical files. Which one to go for?
- How do you call procedures in ILE?
- What is the syntax of passing parameters to a procedure by value?
- How do you code file / field renames in ILE RPG?
- In ProgramB there is a SBMJOB, which is a call to program C .There is also a CALL to program D from B. How would you check the program C has been executed in D?
- How do you find whether a record is locked or not?
- What is the difference between RPG/400 and RPG4
- How do you find whether a job is a batch job or interactive?
- What you have to do in the display file when you are using message subfile?
- How to set on/off a group of indicators in a single statement?
- How can you determine the number of characters in a variable?
- Let’s consider a variable X of length 20. Move value ‘ABC’ to it.How to determine how many characters does X have?
- Suppose you have 3 members in a database file. How to read records from all the members without using CL (OVRDBF) i.e. Entire process should be handled exclusively in a RPG program?
- How do you do indexing in a physical file?
- Can an indexed file be accessed in arrival sequence in RPG?
- When will DUMP & DEBUG be ignored?
- what is the necessary command needed before OPNQRYF and why?
- Can you copy the records created by the OPNQRYF to other files and how?
- What are different ways to pass data between programs and which one is the efficient way?
- What are the necessary keywords required to code a message subfile?
- What is the purpose of FRCDTA keyword?
- What is the purpose of PUTOVR keyword?
- What is journalling and commitment control?
- What is the purpose of Panel Groups?
- How can a screen field that has changed since the last output operation be detected?
- What would be the effect on the field where reverse image, underline and high intensity?
- Can more than one subfile record be displayed on one line?
Possible Related Links
iSeries Users Group Forums are now openInput-Output StrategiesHow to register for iSeries forums
While Googling for Retrieve Job Information API ( QUSRJOBI ), I stumbled upon Collin Willam’s informative AS400 Blog. His blog is a treasure of information for all things iSeries and much more. This blog is worth residing on MMUG’s blogroll. Read more about Retrieve Job Information and other APIs here.
Possible Related Links
QSHELL on iSeriesiSeries RPG programming linksPHP on iSeries