Here is a utility to help you quickly locate jobs in your system.
The Work with Job (WRKJOB) command allows you to work with one job at a time. If you supply a valid qualified job name, it will present you with the job you requested. However, if you provide only a partial job name, and your system contains more than one job with that name, then the system rejects the command. WRKJOB issues an error message for each duplicate job that it finds. This can be a frustrating experience when you only know a partial job name.
I have always thought that there should be a way to view these "duplicate" jobs on the screen and select the one you want to work with. After searching for a solution to this problem, I found a way to do it. The solution, which I am about to present to you, is the basis for this article.
The Command Overview
The new utility I wrote to resolve the limitation is called Work with Jobs (WRKJOBS). Notice that this command contains an "S" at the end (as opposed to the WRKJOB command) to signify its ability to work concurrently with multiple jobs. At the heart of this utility is a system API called List Jobs (QUSLJOB). This API outputs a list of jobs into a user space based on the job information which is passed to it. By building the utility as a front-end to this powerful API, I came up with a way to work with multiple jobs based on a job name.
The main advantage of this utility is its ability to present you with a list of jobs based on a partial job name. In fact, you can even use this utility to locate jobs by generic job name. Like the Work with User Jobs (WRKUSRJOB) command, you can use this utility to produce a list of all of the jobs on your system. But the command's most useful feature is its ability to limit the number of jobs you want to work with by supplying job information in the optional parameters. Generally, the more information you supply, the shorter the list will be.
A Close Look at the Command
Let's take a closer look at the WRKJOBS command to see how we can use it to find jobs in the system. This command has three optional parameters which are as follows:
JOB
Specify the name or generic name (i.e., AR*) of the jobs to be worked with.
*ALL: Display all jobs currently in the system.
*CURRENT: Display jobs with the same name as the current job.
USER
Specify the name or generic name of the user profile whose jobs are to be worked with.
*ALL: Displays jobs for all user profiles.
*CURRENT: Display jobs with the current user profile.
STATUS
Specify the status of the jobs to be worked with.
*ALL: Displays jobs of any status.
*ACTIVE: Displays only those jobs that are active.
*JOBQ: Displays those jobs that are on job queues.
*OUTQ: Displays only jobs that have completed running but still have output on an output queue.
Think of these parameters as filters. You can use these filters separately or in combination with each other. Once you have selected the jobs you want to work with, you are presented with the Work with Jobs screen, as shown in 1. From this screen you can select option 5 to work with a job or option 8 to work with the spooled files for a job. Notice that the top portion of the screen shows the parameters which were selected as well as the number of jobs which met the selection criteria. In this case, all jobs with the job name PAYROLLRUN were selected, resulting in seven jobs found.
Think of these parameters as filters. You can use these filters separately or in combination with each other. Once you have selected the jobs you want to work with, you are presented with the Work with Jobs screen, as shown in Figure 1. From this screen you can select option 5 to work with a job or option 8 to work with the spooled files for a job. Notice that the top portion of the screen shows the parameters which were selected as well as the number of jobs which met the selection criteria. In this case, all jobs with the job name PAYROLLRUN were selected, resulting in seven jobs found.
How It Works
The WRKJOBS command (2) passes three parameters (job, user and status) to the CL program JOB007CL (3). JOB007CL first checks to see if the user space JOB007US exists in the library QTEMP. If the user space does not exist, then the program creates it using the Create User Space (QUSCRTUS) API. JOB007CL then calls the RPG program JOB007RG (5, page 51), passing it the same three parameters.
The WRKJOBS command (Figure 2) passes three parameters (job, user and status) to the CL program JOB007CL (Figure 3). JOB007CL first checks to see if the user space JOB007US exists in the library QTEMP. If the user space does not exist, then the program creates it using the Create User Space (QUSCRTUS) API. JOB007CL then calls the RPG program JOB007RG (Figure 5, page 51), passing it the same three parameters.
JOB007RG begins by executing the Build Subfile (BLDSFL) subroutine. This subroutine starts out by clearing the subfile used to display the list of jobs. Next, the subroutine calls the List Jobs (QUSLJOB) API, which creates a list of jobs in the user space JOB007US in QTEMP. The Retrieve User Space (QUSRTVUS) API is called to retrieve the user space "header," which is the first 140 bytes of the user space. This header contains the offset, count and length of the "list data" section. The list data section contains the actual job information which we are retrieving from the user space. A loop is then performed for each list entry. For each iteration, the QUSRTVUS API is called to retrieve the next entry in the list. Each of these entries is written as a subfile record to the display file JOB007DF (4).
JOB007RG begins by executing the Build Subfile (BLDSFL) subroutine. This subroutine starts out by clearing the subfile used to display the list of jobs. Next, the subroutine calls the List Jobs (QUSLJOB) API, which creates a list of jobs in the user space JOB007US in QTEMP. The Retrieve User Space (QUSRTVUS) API is called to retrieve the user space "header," which is the first 140 bytes of the user space. This header contains the offset, count and length of the "list data" section. The list data section contains the actual job information which we are retrieving from the user space. A loop is then performed for each list entry. For each iteration, the QUSRTVUS API is called to retrieve the next entry in the list. Each of these entries is written as a subfile record to the display file JOB007DF (Figure 4).
Having built the subfile, the program then drops into the main program loop until the user presses F3 or F12 to end the program. Within this loop, the Work with Jobs screen is displayed. If the user presses the F5 key, then the BLDSFL subroutine is executed again to refresh the subfile. If the user presses Enter, the program then executes the Check Subfile (CHKSFL) subroutine that reads any subfile records that have been changed. If the user has selected a valid option, then a WRKJOB command string is built using the RPG Concatenate (CAT) operation. The resulting command string is passed to the QCMDEXC system program, which executes the OS/400 WRKJOB command to display the details the user requested.
A Typical Example
For some insight into how you might use the WRKJOBS command to find a job, let's look at a hypothetical situation. Suppose for example, that you run a payroll job once a week, and that this job could have been run by any one of several users at any one of several terminals. You know that the name of the job is PAYROLLRUN, but you don't know the user name or the job number. How would you find this job?
Let's look at our options. You could enter the command:
WRKUSRJOB USER(*ALL)
But then you would be presented with every job on the system. Since there could easily be hundreds of jobs, you would have to page through them to locate the job you want.
Instead, you would probably go to a command entry screen and enter the following command:
WRKJOB JOB(PAYROLLRUN)
If there is more than one job with this name, the command fails. You then look through the duplicate job messages and write down the full qualified name of the job you think is correct. You then re-enter the WRKJOB command, this time giving it the full qualified job name. If you discover that the job you selected is not the one you want, then you have to repeat this process until you find the one you're looking for.
Although you can find this job using the WRKUSRJOB or the WRKJOB command, you have to admit that both of these methods can be rather time-consuming. Using the same example, my new WRKJOBS command makes it much easier to find the job you're looking for. Since you can supply a partial job name, you enter the following command:
WRKJOBS JOB(PAYROLLRUN)
You are then presented with a screen containing the duplicate job names from which you can make one or more selections. If you select the wrong one the first time, it's no problem. You can select another one from the same screen until you find the job you're looking for.
To Sum it Up
As you can see, the WRKJOBS command helps you to find those jobs that would otherwise be difficult to locate. Unlike the WRKUSRJOB command, it allows you to filter the jobs you want to see by job name. It also resolves the annoying "duplicate job" problem inherent in the WRK-JOB command. So when you need to locate a job in your system, give the WRKJOBS command a try. Chances are you'll locate the jobs you're looking for-quickly and easily.
Robin Klima is a senior technical editor for Midrange Computing.
A Better Command to Work with Jobs
Figure 1 The Work with Jobs Screen
Work with Jobs Job: PAYROLLRUN User: *ALL Status: *ALL Jobs found: 7 Type options, press Enter. 5=Work with job 8=Work with spooled files Opt Job User Number Status PAYROLLRUN JONES 070202 *OUTQ PAYROLLRUN JONES 070924 *OUTQ PAYROLLRUN SMITH 071647 *OUTQ PAYROLLRUN SMITH 072369 *OUTQ PAYROLLRUN SMITH 073092 *OUTQ PAYROLLRUN CLARK 073814 *OUTQ PAYROLLRUN CLARK 074537 *OUTQ Bottom F3=Exit F5=Refresh F12=Cancel
A Better Command to Work with Jobs
Figure 2 Command WRKJOBS
/*==================================================================*/ /* To compile: */ /* */ /* CRTCMD CMD(XXX/WRKJOBS) PGM(XXX/JOB007CL) + */ /* SRCFILE(XXX/QCMDSRC) */ /* */ /*==================================================================*/ WRKJOBS: CMD PROMPT('Work with Jobs') PARM KWD(JOB) TYPE(*GENERIC) DFT(*ALL) + SPCVAL((*ALL) (*CURRENT)) PROMPT('Job name') PARM KWD(USER) TYPE(*GENERIC) DFT(*ALL) + SPCVAL((*ALL) (*CURRENT)) PROMPT('User name') PARM KWD(STATUS) TYPE(*CHAR) LEN(7) RSTD(*YES) + DFT(*ALL) VALUES(*ALL *ACTIVE *JOBQ + *OUTQ) PROMPT('Status of jobs')
A Better Command to Work with Jobs
Figure 3 CL Program JOB007CL
/*==================================================================*/ /* To compile: */ /* */ /* CRTCLPGM PGM(XXX/JOB007CL) SRCFILE(XXX/QCLSRC) */ /* */ /*==================================================================*/ JOB007CL: + PGM PARM(&JOBNM &USRNM &STAT) DCL VAR(&JOBNM) TYPE(*CHAR) LEN(10) DCL VAR(&USRNM) TYPE(*CHAR) LEN(10) DCL VAR(&STAT) TYPE(*CHAR) LEN(7) DCL VAR(&USRSPC) TYPE(*CHAR) LEN(20) VALUE('JOB007US + QTEMP') DCL VAR(&ATR) TYPE(*CHAR) LEN(10) DCL VAR(&SIZE) TYPE(*DEC) LEN(10 0) VALUE(1024) DCL VAR(&INIT) TYPE(*CHAR) LEN(1) DCL VAR(&AUT) TYPE(*CHAR) LEN(10) VALUE('*CHANGE') DCL VAR(&TEXT) TYPE(*CHAR) LEN(50) VALUE('Work with Jobs') DCL VAR(&MSGID) TYPE(*CHAR) LEN(7) DCL VAR(&MSGF) TYPE(*CHAR) LEN(10) DCL VAR(&MSGFLIB) TYPE(*CHAR) LEN(10) DCL VAR(&MSGDTA) TYPE(*CHAR) LEN(80) MONMSG MSGID(CPF0000) EXEC(GOTO CMDLBL(ERROR)) CHKOBJ OBJ(QTEMP/JOB007US) OBJTYPE(*USRSPC) MONMSG MSGID(CPF9801) EXEC(CALL PGM(QUSCRTUS) PARM(&USRSPC &ATR + &SIZE &INIT &AUT &TEXT)) CALL PGM(JOB007RG) PARM(&JOBNM &USRNM &STAT) RETURN ERROR: + RCVMSG MSGTYPE(*EXCP) MSGDTA(&MSGDTA) MSGID(&MSGID) MSGF(&MSGF) + MSGFLIB(&MSGFLIB) SNDPGMMSG MSGID(&MSGID) MSGF(&MSGFLIB/&MSGF) MSGDTA(&MSGDTA) + MSGTYPE(*ESCAPE) ENDPGM: + ENDPGM
A Better Command to Work with Jobs
Figure 4 Display File JOB007DF
*=============================================================== * To compile: * * CRTDSPF FILE(XXX/JOB007DF) SRCFILE(XXX/QDDSSRC) * *=============================================================== *. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... A DSPSIZ(24 80 *DS3) A PRINT A ERRSFL A CA03(03) A CA12(03) A CA05(05) A R SFL SFL A 80 SFLNXTCHG A OPT 1A B 9 3VALUES(' ' '5' '8') A 80 DSPATR(RI) A 80 DSPATR(PC) A JOB 10A O 9 8 A USR 10A O 9 19 A NBR 6A O 9 30 A STS 7A O 9 40 A R SFLCTL SFLCTL(SFL) A SFLSIZ(0014) A SFLPAG(0013) A SETOF(60) A OVERLAY A 25 SFLCLR A 26 SFLDSP A SFLDSPCTL A N03 SFLEND(*MORE) A 70 SFLMSG('Job not found.' 70) A SRN 4S 0H SFLRCDNBR(CURSOR) A 1 34'Work with Jobs' A DSPATR(HI) A 3 2'Job:' A JOBNM 10A O 3 7 A 3 20'User:' A USRNM 10A O 3 26 A 3 39'Status:' A STAT 7A O 3 47 A 3 57'Jobs found:' A RN 4Y 0O 3 69EDTCDE(3) A 5 2'Type options, press Enter.' A COLOR(BLU) A 6 4'5=Work with job' A COLOR(BLU) A 6 23'8=Work with spooled files' A COLOR(BLU) A 8 2'Opt' A DSPATR(HI) A 8 8'Job' A DSPATR(HI) A 8 19'User' A DSPATR(HI) A 8 30'Number' A DSPATR(HI) A 8 40'Status' A DSPATR(HI) A R FKEYS A 23 2'F3=Exit' A COLOR(BLU) A 23 13'F5=Refresh' A COLOR(BLU) A 23 27'F12=Cancel' A COLOR(BLU) A R NOJOBS A OVERLAY A 10 4'(No jobs to display)' *. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+...
A Better Command to Work with Jobs
Figure 5 RPG Program JOB007RG
*=============================================================== * To compile: * * CRTRPGPGM PGM(XXX/JOB007RG) SRCFILE(XXX/QRPGSRC) * *=============================================================== *. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... FJOB007DFCF E WORKSTN F RN KSFILE SFL IUSRSPC DS I I 'JOB007US ' 1 10 SPCNAM I I '*LIBL ' 11 20 SPCLIB I DS I 1 26 QJOBI I 1 10 JOBNMI I 11 20 USRNMI I I '*ALL ' 21 26 JOBNOI I 27 36 STATI I DS I B 1 40STRPOS I B 5 80STRLEN IHEADER DS I B 125 1280OFFSET I B 133 1360COUNT I B 137 1400LENGTH ILIST DS I 1 10 JOBNML I 11 20 USRNML I 21 26 JOBNOL I 43 52 STATL I SDS I 244 253 CURJOB I 254 263 CURUSR I 'OPTION(*SPLF)' C SPL *=============================================================== C *ENTRY PLIST C PARM JOBNM C PARM USRNM C PARM STAT * C EXSR BLDSFL * C *IN03 DOUEQ*ON C *IN60 OREQ *OFF C WRITEFKEYS C *IN26 IFEQ *OFF C WRITENOJOBS C ENDIF C EXFMTSFLCTL * C *IN03 IFEQ *OFF C *IN05 IFEQ *ON C EXSR BLDSFL C ELSE C *IN26 IFEQ *ON C EXSR CHKSFL C ENDIF C ENDIF C ENDIF C ENDDO * C MOVE *ON *INLR *=============================================================== C BLDSFL BEGSR * C MOVE *ON *IN25 C WRITESFLCTL C MOVE *OFF *IN25 * C MOVE *OFF *IN26 C MOVE *ON *IN60 C Z-ADD0 RN C Z-ADD1 SRN * C CALL 'QUSLJOB' C PARM USRSPC C PARM 'JOBL0100'FORMAT 8 C PARM QJOBI C PARM STATI * C CALL 'QUSRTVUS' C PARM USRSPC C PARM 1 STRPOS C PARM 140 STRLEN C PARM HEADER * C OFFSET ADD 1 STRPOS C Z-ADDLENGTH STRLEN * C DO COUNT C CALL 'QUSRTVUS' C PARM USRSPC C PARM STRPOS C PARM STRLEN C PARM LIST * C MOVE *BLANKS OPT C MOVELJOBNML JOB C MOVELUSRNML USR C MOVELJOBNOL NBR C MOVELSTATL STS C MOVE *ON *IN26 C ADD 1 RN C WRITESFL C ADD LENGTH STRPOS C ENDDO * C ENDSR *=============================================================== C CHKSFL BEGSR * C READCSFL 99 C *IN99 DOWEQ*OFF C MOVE *ON *IN60 * C OPT IFNE *BLANKS C MOVE *BLANKS CMD 50 C MOVEL'WRKJOB' CMD C CMD CAT NBR:1 CMD C CMD CAT '/':0 CMD C CMD CAT USR:0 CMD C CMD CAT '/':0 CMD C CMD CAT JOB:0 CMD C OPT IFEQ '8' C CMD CAT SPL:1 CMD C ENDIF C CALL 'QCMDEXC' 98 C PARM CMD C PARM 50 LEN 155 C *IN98 IFEQ *ON C MOVE *ON *IN70 C MOVE *ON *IN80 C ELSE C MOVE *BLANKS OPT C ENDIF C ENDIF * C UPDATSFL C MOVE *OFF *IN80 C Z-ADDRN SRN C READCSFL 99 C ENDDO * C ENDSR *=============================================================== C *INZSR BEGSR * C JOBNM IFEQ '*CURRENT' C MOVELCURJOB JOBNMI C ELSE C MOVELJOBNM JOBNMI C ENDIF * C USRNM IFEQ '*CURRENT' C MOVELCURUSR USRNMI C ELSE C MOVELUSRNM USRNMI C ENDIF * C MOVELSTAT STATI * C ENDSR *. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+...
LATEST COMMENTS
MC Press Online