× The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.


  • Subject: Re: Another CL Question - RCVF
  • From: "Simon Coulter" <shc@xxxxxxxxxxxxxxxxx>
  • Date: Fri, 31 Dec 99 10:31:03 +1100


Hello Kirwin,

Well, I'd think that questions not specific to a particular list go in the 
general 
bucket and therefore belong on the MIDRANGE-L list.  David may want to consider 
a CL 
list but I don't think that is necessary.

Now to your specific problem:

There are two rules to understand about CL and file processing.
        1/ You can only process one file per CL program
        2/ Once EOF is reached you cannot process that file any further.

You cannot break these rules at all but you can work around them

The most common technique to defeat rule 1 is to use multiple CL programs -- 1 
program 
per file.  So for instance, if you need to process a list of files and for each 
file 
process a list of fields, you would need one CL program to process a list of 
files 
created using the DSPOBJD or DSPFD commands and a second CL program to process 
a list of 
fields created using the DSPFFD command (or you could stop messing around with 
CL and 
process both files in a HLL).  But you can use a little-known trick of 
transferring 
control to yourself which effectively ends the invocation and allows you to 
reprocess 
the file.

Rule 2 is harder to break because the code behind a CL program sets a flag when 
EOF is 
reached and it really doesn't matter what you do after that.  Any I/O to the 
file will 
result in EOF.  CLOF and OPNDBF doesn't help.  POSDBF doesn't help either.  The 
EOF flag 
is not reset until the CL program ends.

One solution is to count the number of records processed and never reach EOF.  
Then you 
can use POSDBF to reposition.  The code looks something like this -- using your 
code as 
a starting point:

           DCLF       FILE(QSYS/QADSPOBJ)
           DSPOBJD    OBJ(LIB1/*ALL) OBJTYPE(*FILE) +
                      OUTPUT(*OUTFILE) OUTFILE(QTEMP/FILE) +
                      OUTMBR(*FIRST *REPLACE)
           OVRDBF     FILE(QADSPOBJ) TOFILE(QTEMP/FILE)
           RTVMBRD    FILE(QTEMP/FILE) MBR(*FIRST) +
                        NBRCURRCD(&RCDCOUNT)
           CHGVAR     &LOOPCOUNT 0
LOOP1:     IF         (&RCDCOUNT *LT &LOOPCOUNT) THEN(DO)
             RCVF       DEV(*FILE) RCDFMT(*FILE) WAIT(*YES)
             /*  Code...  */
             CHGVAR     &LOOPCOUNT (&LOOPCOUNT + 1)
             GOTO       CMDLBL(LOOP1)
           ENDDO
EOF1:
           DSPOBJD    OBJ(LIB2/*ALL) OBJTYPE(*FILE) +
                      OUTPUT(*OUTFILE) OUTFILE(QTEMP/FILE) +
                      OUTMBR(*FIRST *REPLACE)
           RTVMBRD    FILE(QTEMP/FILE) MBR(*FIRST) +
                        NBRCURRCD(&RCDCOUNT)
           POSDBF     OPNID(FILE) POSITION(*START)
           CHGVAR     &LOOPCOUNT 0
LOOP2:     IF         (&RCDCOUNT *LT &LOOPCOUNT) THEN(DO)
             RCVF       DEV(*FILE) RCDFMT(*FILE) WAIT(*YES)
             /*  Code...  */
             CHGVAR     &LOOPCOUNT (&LOOPCOUNT + 1)
             GOTO       CMDLBL(LOOP2)
           ENDDO
EOF2:
LOOP3      RCVF
           MONMSG     MSGID(CPF0864) EXEC(DO)
             RCVMSG     MSGTYPE(*EXCP) /* Cleanup joblog */
             DLTF       FILE(QTEMP/FILE)
             RCVMSG     MSGTYPE(*LAST) /* Cleanup joblog */
             GOTO CMDLBL(EXIT)
           ENDDO
           GOTO       CMDLBL(LOOP3)

EXIT:      RETURN

Also pay attention to the DCLF and OVRDBF statements which are the proper way 
to handle 
IBM outfiles.  And also the code to cleanup the joblog -- we don't all have to 
write CL 
like HelpSystems.  There is no need to delete the file just to replace it -- 
that's what 
the OUTMBR keyword is for.  The LOOP3 code is to ensure that EOF is reached 
otherwise 
the DLTF will fail with an in-use message.

A second solution is build the outfile with all the records before processing 
and test 
the library name to condition processing.  That looks something like:

           DCLF       FILE(QSYS/QADSPOBJ)
           DSPOBJD    OBJ(LIB1/*ALL) OBJTYPE(*FILE) +
                      OUTPUT(*OUTFILE) OUTFILE(QTEMP/FILE) +
                      OUTMBR(*FIRST *REPLACE)
           DSPOBJD    OBJ(LIB2/*ALL) BJTYPE(*FILE) +
                      OUTPUT(*OUTFILE) OUTFILE(QTEMP/FILE) +
                      OUTMBR(*FIRST *ADD)   /* <=================== */
           OVRDBF     FILE(QADSPOBJ) TOFILE(QTEMP/FILE)
LOOP1:     RCVF       DEV(*FILE) RCDFMT(*FILE) WAIT(*YES)
           MONMSG     MSGID(CPF0864) EXEC(DO)
             RCVMSG     MSGTYPE(*EXCP) /* Cleanup joblog */
             GOTO CMDLBL(EOF1)
           ENDDO
           IF (&ODLBNM *EQ 'LIB1') THEN(DO)
             /*  Code...  */
           ELSE  DO
             /*  Code...  */
           ENDDO
           GOTO       CMDLBL(LOOP1)
EOF1:
           DLTF       FILE(QTEMP/FILE)

A third solution is to transfer control to the same CL program effectively 
calling 
yourself but without increasing the invocation stack.  Pass a counter variable 
in as a 
parameter with an initial value of zero.

           PGM        PARM(&COUNTER)
           DCL        VAR(&COUNTER) TYPE(*DEC) LEN(5 0)
           DCLF       FILE(QSYS/QADSPOBJ)
           IF         (&COUNTER *EQ 0) THEN(DO)
             CHGVAR     &LIB 'LIB1'
           ENDDO
           ELSE IF         (&COUNTER *EQ 1) THEN(DO)
             CHGVAR     &LIB 'LIB2'
           ENDDO
           ELSE IF         (&COUNTER *EQ 2) THEN(RETURN)
           DSPOBJD    OBJ(&LIB/*ALL) OBJTYPE(*FILE) +
                      OUTPUT(*OUTFILE) OUTFILE(QTEMP/FILE) +
                      OUTMBR(*FIRST *REPLACE)
           OVRDBF     FILE(QADSPOBJ) TOFILE(QTEMP/FILE)
LOOP1:     RCVF       DEV(*FILE) RCDFMT(*FILE) WAIT(*YES)
           MONMSG     MSGID(CPF0864) EXEC(DO)
             RCVMSG     MSGTYPE(*EXCP) /* Cleanup joblog */
             GOTO CMDLBL(EOF1)
           ENDDO
           /*  Code...  */
           GOTO       CMDLBL(LOOP1)
EOF1:
           CHGVAR     &COUNTER (&COUNTER + 1)
           TFRCTL     PGM(THISPGM) PARM(&COUNTER)

I have used this technique to accept a list as a parameter and iteratively 
process the 
list by TFRCTL for each item in the list.  It is especially useful when the 
information 
about the item comes from an outfile.

Regards,
Simon Coulter.

«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»
«» FlyByNight Software         AS/400 Technical Specialists       «»
«» Eclipse the competition - run your business on an IBM AS/400.  «»
«»                                                                «»
«» Phone: +61 3 9419 0175      Mobile: +61 0411 091 400           «»
«» Fax:   +61 3 9419 0175      mailto: shc@flybynight.com.au      «»
«»                                                                «»
«» Windoze should not be open at Warp speed.                      «»
«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»

Date: Thu, 30 Dec 1999 14:31:13 -0600
From: "Kerwin Crawford" <crawfork@toastmaster.com>
To: RPG400-L@midrange.com
Reply-To: RPG400-L@midrange.com
Subject: Another CL Question - RCVF
 know this is a RPG list but I don't know of a CLP list.

I have a CLP that is basically the following.  The main process is to read all 
of the files in a library do some things with it and then read all of the files 
from a related library and do some things.  See example:

           DCLF       FILE(QTEMP/FILE)
           DSPOBJD    OBJ(LIB1/*ALL) OBJTYPE(*FILE) +
                      OUTPUT(*OUTFILE) OUTFILE(QTEMP/FILE) +
                      OUTMBR(*FIRST *REPLACE)
LOOP1:     RCVF       DEV(*FILE) RCDFMT(*FILE) WAIT(*YES)
           MONMSG     MSGID(CPF0864) EXEC(GOTO CMDLBL(EOF1))
           /*  Code...  */
           GOTO       CMDLBL(LOOP1)
EOF1:
           DLTF       FILE(QTEMP/FILE)
           DSPOBJD    OBJ(LIB2/*ALL) OBJTYPE(*FILE) +
                      OUTPUT(*OUTFILE) OUTFILE(QTEMP/FILE) +
                      OUTMBR(*FIRST *REPLACE)
LOOP2:     RCVF       DEV(*FILE) RCDFMT(*FILE) WAIT(*YES)
           MONMSG     MSGID(CPF0864) EXEC(GOTO CMDLBL(EOF2))
           /*  Code...  */
           GOTO       CMDLBL(LOOP2)
EOF2:
           DLTF       FILE(QTEMP/FILE)

My problem is that when it gets to the second rcvf it acts as if it has hit the 
EOF before processing the first record.  I have tried putting in ovrdbf in 
several ways, but never got it to work.  There has to be a way to reset the 
pointer or message to allow for the second rcvf.

I ended up splitting this up into two CLP's and doing it that way.

Any thoughts?

Kerwin S. Crawford
Toastmaster Inc.
System Analyst

I know this is a RPG list but I don't know of a CLP list.
 
I have a CLP that is basically the following.  The main process is to read all of the files in a library do some things with it and then read all of the files from a related library and do some things.  See example:
 
           DCLF       FILE(QTEMP/FILE)
           DSPOBJD    OBJ(LIB1/*ALL) OBJTYPE(*FILE) +
                      OUTPUT(*OUTFILE) OUTFILE(QTEMP/FILE) +
                      OUTMBR(*FIRST *REPLACE)
LOOP1:     RCVF       DEV(*FILE) RCDFMT(*FILE) WAIT(*YES)
           MONMSG     MSGID(CPF0864) EXEC(GOTO CMDLBL(EOF1))
           /*  Code...  */
           GOTO       CMDLBL(LOOP1)
EOF1:
           DLTF       FILE(QTEMP/FILE)
           DSPOBJD    OBJ(LIB2/*ALL) OBJTYPE(*FILE) +
                      OUTPUT(*OUTFILE) OUTFILE(QTEMP/FILE) +
                      OUTMBR(*FIRST *REPLACE)
LOOP2:     RCVF       DEV(*FILE) RCDFMT(*FILE) WAIT(*YES)
           MONMSG     MSGID(CPF0864) EXEC(GOTO CMDLBL(EOF2))
           /*  Code...  */
           GOTO       CMDLBL(LOOP2)
EOF2:
           DLTF       FILE(QTEMP/FILE)
 
My problem is that when it gets to the second rcvf it acts as if it has hit the EOF before processing the first record.  I have tried putting in ovrdbf in several ways, but never got it to work.  There has to be a way to reset the pointer or message to allow for the second rcvf.
I ended up splitting this up into two CLP's and doing it that way.
 
Any thoughts?

Kerwin S. Crawford
Toastmaster Inc.
System Analyst

As an Amazon Associate we earn from qualifying purchases.

This thread ...


Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].

Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.