TechTalk: Copying a Group of Files

CL
Typography
  • Smaller Small Medium Big Bigger
  • Default Helvetica Segoe Georgia Times

CPYGRPF was originally designed to allow a quick copy of one or more files into library QTEMP. This allowed a quick program-testing area. Command CPYF didn't have the right defaults for my needs, so I wrote my own command.

The command CPYGRPF (Copy a Group of Files) allows entry of 1 to 50 file names to be copied. These file names are qualified and defined at the QFILE label. The library to copy from is defaulted as the Library List. The To library defaults to the current library. If the file already exists in the destination library, you can enter an appropriate action, just as CPYF allows. See the command definition in 5a and the CPP in 5b.

The command CPYGRPF (Copy a Group of Files) allows entry of 1 to 50 file names to be copied. These file names are qualified and defined at the QFILE label. The library to copy from is defaulted as the Library List. The To library defaults to the current library. If the file already exists in the destination library, you can enter an appropriate action, just as CPYF allows. See the command definition in Figure 5a and the CPP in Figure 5b.

The first task is to find out the number of files the user has entered. This information is contained in the first 2 bytes of parameter &FILE. Remember, when a list is fed to a program from a command, the number of elements to be processed are in binary in the first 2 bytes of the list. Command CVTBINDEC from QUSRTOOLS is borrowed to convert this binary number to a decimal number we can work with.

After we know the number of files to process, we will check to make sure each one exists in the library specified. This is handled in the loop LOOP_CHK. &TODO contains the number of files to process, &PNTR is the index to the file names. &FROMFILE and &FROMLIBR are loaded with the appropriate information and a CHKOBJ is used to validate the file. If the file or library is not found, a diagnostic message is sent and the error counter (more on it later) is incremented. If it exists, the next file is validated. The destination library is validated at label END_CHK.

If any errors were found, escape message CPF0002 is sent. This will cause the command to return to the screen and allow the user to list all of the errors it found.

If all is OK, we do another loop (LOOP_CPY) processing each file. If the destination file already exists, &MBROPT is checked for the appropriate action. If the action was *NONE, then an informational message will be sent to the user at the completion of the procedure saying the file was not copied. We keep track of the number of files copied and not copied to tell the user at job completion.

I hope you will enjoy this command as much as I have. It makes testing easier, but maybe more importantly, it will also give you experience programming commands using lists.

-- Bill Robins


TechTalk: Copying a Group of Files

Figure 5A Command CPYGRPF

 CPYGRPF: CMD PROMPT('Copy a Group of Files') PARM KWD(FILE) TYPE(QFILE) MIN(1) MAX(50) + PROMPT('File to copy') PARM KWD(TOLIB) TYPE(*SNAME) LEN(10) DFT(*CURLIB) + SPCVAL((*CURLIB)) PROMPT('To library') PARM KWD(MBROPT) TYPE(*CHAR) LEN(8) RSTD(*YES) + DFT(*NONE) VALUES(*NONE *ADD *REPLACE) + PROMPT('Replace or add records') QFILE: QUAL TYPE(*SNAME) LEN(10) MIN(1) QUAL TYPE(*SNAME) LEN(10) DFT(*LIBL) + SPCVAL((*LIBL)) PROMPT('Library') 
TechTalk: Copying a Group of Files

Figure 5B CL program GRP001CL

 GRP001CL: + PGM PARM(&FILE &TOLIB &MBROPT) DCL VAR(&BINCNT) TYPE(*CHAR) LEN(2) DCL VAR(&CNTR) TYPE(*DEC) LEN(5 0) DCL VAR(&CPYA) TYPE(*CHAR) LEN(2) DCL VAR(&CPYD) TYPE(*DEC) LEN(2 0) DCL VAR(&ERRORS) TYPE(*DEC) LEN(3 0) DCL VAR(&FILE) TYPE(*CHAR) LEN(1002) DCL VAR(&FNMS) TYPE(*CHAR) LEN(1000) DCL VAR(&FROMFILE) TYPE(*CHAR) LEN(10) DCL VAR(&FROMLIB) TYPE(*CHAR) LEN(10) DCL VAR(&MBROPT) TYPE(*CHAR) LEN(8) DCL VAR(&NCPYA) TYPE(*CHAR) LEN(2) DCL VAR(&NCPYD) TYPE(*DEC) LEN(2 0) DCL VAR(&PNTR) TYPE(*DEC) LEN(5 0) DCL VAR(&TODO) TYPE(*DEC) LEN(5 0) DCL VAR(&TOLIB) TYPE(*CHAR) LEN(10) /* Find the number of files to be copied */ CHGVAR VAR(&BINCNT) VALUE(%SST(&FILE 1 2)) CVTBINDEC FROMBIN(&BINCNT) TODEC(&TODO) /* Validate file names */ CHGVAR VAR(&FNMS) VALUE(%SST(&FILE 3 1000)) CHGVAR VAR(&CNTR) VALUE(1) LOOP_CHK: + IF COND(&CNTR *GT &TODO) THEN(GOTO CMDLBL(END_CHK)) CHGVAR VAR(&PNTR) VALUE((&CNTR * 20) - 19) CHGVAR VAR(&FROMFILE) VALUE(%SST(&FNMS &PNTR 10)) CHGVAR VAR(&PNTR) VALUE(&PNTR + 10) CHGVAR VAR(&FROMLIB) VALUE(%SST(&FNMS &PNTR 10)) CHKOBJ OBJ(&FROMLIB/&FROMFILE) OBJTYPE(*FILE) MONMSG MSGID(CPF9801) EXEC(DO) CHGVAR VAR(&ERRORS) VALUE(&ERRORS + 1) SNDPGMMSG MSG('File' *BCAT &FROMFILE *BCAT 'not found.') + MSGTYPE(*DIAG) ENDDO MONMSG MSGID(CPF9810) EXEC(DO) CHGVAR VAR(&ERRORS) VALUE(&ERRORS + 1) SNDPGMMSG MSG('Library' *BCAT &FROMLIB *BCAT 'not found.') + MSGTYPE(*DIAG) ENDDO CHGVAR VAR(&CNTR) VALUE(&CNTR + 1) GOTO CMDLBL(LOOP_CHK) /* Validate destination library */ END_CHK: + IF COND(&TOLIB *NE '*CURLIB') THEN(DO) CHKOBJ OBJ(&TOLIB) OBJTYPE(*LIB) MONMSG MSGID(CPF9801) EXEC(DO) CHGVAR VAR(&ERRORS) VALUE(&ERRORS + 1) SNDPGMMSG MSG('Destination library' *BCAT &TOLIB *BCAT + 'not found.') MSGTYPE(*DIAG) ENDDO ENDDO /* If any errors were found, stop processing */ IF COND(&ERRORS *GT 0) THEN(DO) SNDPGMMSG MSGID(CPF0002) MSGF(QCPFMSG) MSGTYPE(*ESCAPE) GOTO CMDLBL(ENDPGM) ENDDO /* Copy each of the files */ CHGVAR VAR(&CNTR) VALUE(1) LOOP_CPY: + IF COND(&CNTR *GT &TODO) THEN(GOTO CMDLBL(END_CPY)) CHGVAR VAR(&PNTR) VALUE((&CNTR * 20) - 19) CHGVAR VAR(&FROMFILE) VALUE(%SST(&FNMS &PNTR 10)) CHGVAR VAR(&PNTR) VALUE(&PNTR + 10) CHGVAR VAR(&FROMLIB) VALUE(%SST(&FNMS &PNTR 10)) /* Determine whether the destination file exists */ CHKOBJ OBJ(&TOLIB/&FROMFILE) OBJTYPE(*FILE) MONMSG MSGID(CPF9801) EXEC(GOTO CMDLBL(NEW_FILE)) /* Destination file already exists */ IF COND(&MBROPT *EQ '*NONE') THEN(DO) SNDPGMMSG MSG('File' *BCAT &FROMFILE *BCAT 'already exists + in' *BCAT &TOLIB *TCAT '. File not copied.') MSGTYPE(*INFO) CHGVAR VAR(&NCPYD) VALUE(&NCPYD + 1) GOTO CMDLBL(NXT_CPY) ENDDO CPYF FROMFILE(&FROMLIB/&FROMFILE) TOFILE(&TOLIB/&FROMFILE) + FROMMBR(*ALL) TOMBR(*FROMMBR) MBROPT(&MBROPT) CHGVAR VAR(&CPYD) VALUE(&CPYD + 1) GOTO CMDLBL(NXT_CPY) NEW_FILE: + CPYF FROMFILE(&FROMLIB/&FROMFILE) TOFILE(&TOLIB/&FROMFILE) + FROMMBR(*ALL) TOMBR(*FROMMBR) CRTFILE(*YES) CHGVAR VAR(&CPYD) VALUE(&CPYD + 1) NXT_CPY: + CHGVAR VAR(&CNTR) VALUE(&CNTR + 1) GOTO CMDLBL(LOOP_CPY) END_CPY: + CHGVAR VAR(&CPYA) VALUE(&CPYD) CHGVAR VAR(&NCPYA) VALUE(&NCPYD) SNDPGMMSG MSG('Files copied =' *BCAT &CPYA *CAT '. Files not + copied =' *BCAT &NCPYA *CAT '.') MSGTYPE(*COMP) ENDPGM: + ENDPGM 
BLOG COMMENTS POWERED BY DISQUS