Sometimes technical support problems are a lot like jigsaw puzzles. When a user calls in with a problem, I have to put together several different pieces of information to find out what's going on. Fortunately, on the AS/400 I can get a lot of the pieces I need just by using the Display Job (DSPJOB) command. However, one important piece has always been missing, a piece that could have saved me a lot of time and trouble. Many times I knew that, if I could only see what was displayed on the user's workstation, I would have a much clearer picture of the problem. IBM does provide the Start Copy Screen (STRCPYSCN) command to do this, but it has several drawbacks limiting its usefulness: you can only look at one job at a time; it requires the user to respond to a message; only one person can look at a particular screen at a time; and what you see is always one screen behind what the user is looking at. Because of these problems, I found that it didn't help me very much. That's why I wrote my own utility, which I call Display User Screen (DSPUSRSCN).
The DSPUSRSCN utility allows you to easily look at screens from as many jobs as you want, and the screens are always current, right up to the last keystroke. In addition, there is no limit to the number of people who can look at the same screen, making consultations much easier.
When you issue the DSPUSRSCN command, a list of currently active jobs is presented in a subfile (see 1). To display the screen for a job, simply place a 5 beside the job name, and you see what the user is looking at right now. A message appears at the bottom of the screen indicating the job information of the job you're displaying. It's that simple. The user is not required to answer a message or even be at the workstation (however, the screen does blink briefly). Press F5 if you want to refresh the screen; press Enter to view the next job if you've selected more than one; or return to the list and select another job if you're displaying the last one you selected.
When you issue the DSPUSRSCN command, a list of currently active jobs is presented in a subfile (see Figure 1). To display the screen for a job, simply place a 5 beside the job name, and you see what the user is looking at right now. A message appears at the bottom of the screen indicating the job information of the job you're displaying. It's that simple. The user is not required to answer a message or even be at the workstation (however, the screen does blink briefly). Press F5 if you want to refresh the screen; press Enter to view the next job if you've selected more than one; or return to the list and select another job if you're displaying the last one you selected.
2 illustrates the DSPUSRSCN command being used to display the current screen for job 120060/SHARIC/QPADEV0004. As you can see, the user has received an error message (one he most likely wouldn't understand). Since you can view the message so easily, you can figure out what the problem is much sooner than if you had to ask the user to describe what he is seeing.
Figure 2 illustrates the DSPUSRSCN command being used to display the current screen for job 120060/SHARIC/QPADEV0004. As you can see, the user has received an error message (one he most likely wouldn't understand). Since you can view the message so easily, you can figure out what the problem is much sooner than if you had to ask the user to describe what he is seeing.
The source code for this utility is shown in Figures 3-12. (You can also download it from MC's Web page at www.as400.com or from the MC-BBS.) Compile each member according to the instructions at the beginning of each source member.
The DSPUSRSCN utility uses a variety of techniques to perform its magic. First, each job that will allow its screen to be displayed must call the setup program SCN004CL. This program creates a unique message queue using 'DSPM' plus the six-digit job number in the QRPLOBJ library (I use this library because it is cleared on a periodic basis, but you can use any library except QTEMP). It then assigns the program SCN005CL as a break message handling program (more about this later). I simply added SCN004CL to the standard sign-on routine for all users.
The DSPUSRSCN command executes the program SCN001CL, which creates a unique data queue in QRPLOBJ and calls the RPG program SCN001RG. To get the list of jobs, SCN001RG calls the CL program SCN002CL, which uses the Display Object Description (DSPOBJD) command to load a work file in QTEMP with a list of 'DSPM*' message queues in QRPLOBJ. Before loading the work file, SCN002CL attempts to delete all 'DSPM*' message queues in order to eliminate jobs that have ended (active jobs have a lock on the message queue so SCN002CL can't delete their message queues). SCN001RG then loads this list into a subfile and displays it.
When you select a job with option 5, the data queue name and selected job number are passed to the CL program SCN003CL. SCN003CL sends the data queue name to the message queue assigned to the job and then waits for a response to come back in the data queue. Sending the message causes the break message handling program SCN005CL to automatically start up at the user's workstation. SCN005CL retrieves the data queue name from the message queue, executes user-defined data stream (UDDS) commands to retrieve the current screen and cursor location, and then puts this information in the data queue. (UDDS commands allow you to take control and process the 5250 display data stream, something normally handled by the system. For more information on UDDS, see the OS/400 Application Display Programming V3R1 manual. ) SCN003CL receives the information from the data queue and passes it back to SCN001RG, which displays the screen.
To start using DSPUSRSCN, you only need to add SCN004CL as a startup program for those users whose screens you want to be able to see. Those users must also be authorized to QRPLOBJ library (they must have at least Read, Add, Delete, and Execute data authority).
This version of DSPUSRSCN does have some limitations, due to publishing constraints. It's limited to a 24 x 80 screen, so, if the user is looking at a 27 x 132 screen, you will get only the first 1,920 bytes. Additional code would be required to determine whether your workstation is capable of displaying the additional information and then choose the correct format to display.
If you try to look at a suspended group job, the break message handling program, SCN005CL, can't execute until the job resumes. If this happens, SCN003CL will "time out" after one minute, and you'll see a blank screen.
You may also find some limitations with some terminal emulation applications. For example, with a certain Telnet emulation application, I found that the user's cursor position wasn't reflected at my workstation. This was because this Telnet application didn't return the cursor position to my program.
These are small limitations, however, considering what an improvement DSPUSRSCN is over STRCPYSCN.
The DSPUSRSCN utility fills in a missing piece for me. It quickly and easily provides me or my help desk personnel with the additional information we need to solve technical support puzzles.
Albert York is the manager of Systems Development for the Infinitinet Division at Nissan. He has been a S/38 and AS/400 consultant since 1981.
REFERENCE
OS/400 Application Display Programming V3R1 (SC41-3715, CD-ROM QBKAUK00).
The Display User Screen Utility
Figure 1: Subfile of Eligible Interactive Jobs Presented by DSPUSRSCN
The Display User Screen Utility
Figure 2: Viewing Another Job's Display with DSPUSRSCN
The Display User Screen Utility
Figure 3: DSPUSRSCN Command Definition
/*==================================================================*/ /* To compile: */ /* */ /* CRTCMD CMD(XXX/DSPUSRSCN) PGM(XXX/SCN001CL) + */ /* SRCFILE(XXX/QCMDSRC) */ /* */ /*==================================================================*/ DSPUSRSCN: CMD PROMPT('Display User Screen')
The Display User Screen Utility
Figure 4: Program SCN001CL
/*==================================================================*/ /* To compile: */ /* */ /* CRTCLPGM PGM(XXX/SCN001CL) SRCFILE(XXX/QCLSRC) */ /* */ /*==================================================================*/ SCN001CL: PGM DCL VAR(&NBR) TYPE(*CHAR) LEN(6) DCL VAR(&DTAQ) TYPE(*CHAR) LEN(10) MONMSG MSGID(CPF0000) /* Create data queue using current job number for screen transfers */ RTVJOBA NBR(&NBR) CHGVAR VAR(&DTAQ) VALUE('DSPD' *CAT &NBR) CRTDTAQ DTAQ(QRPLOBJ/&DTAQ) MAXLEN(1922) AUT(*ALL) OVRDBF FILE(QADSPOBJ) TOFILE(QTEMP/QADSPOBJ) CALL PGM(SCN001RG) PARM(&DTAQ) DLTDTAQ DTAQ(QRPLOBJ/&DTAQ) ENDPGM: ENDPGM
The Display User Screen Utility
Figure 5: Display File SCN001DF
A*=============================================================== A* To compile: A* A* CRTDSPF FILE(XXX/SCN001DF) SRCFILE(XXX/QDDSSRC) A* A*=============================================================== A*. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 A DSPSIZ(24 80 *DS3) A CA03 A CA05 A PRINT * List of jobs A R SCN001S1 SFL A S1OPT 1 B 6 3VALUES(' ' '5') A S1JOB 10 O 6 7 A S1USER 10 O 6 19 A S1JOBN 6 O 6 31 A* A R SCN001C1 SFLCTL(SCN001S1) A SFLSIZ(0018) A SFLPAG(0017) A 21 SFLCLR A SFLDSPCTL A 22 SFLDSP A OVERLAY A 1 31'Display User Screen' A DSPATR(HI) A 2 2'Type option, press Enter.' A COLOR(BLU) A 3 3'5=Display screen' A COLOR(BLU) A 5 2'Opt' A DSPATR(HI) A 5 7'Job name ' A DSPATR(HI) A 5 19'User ' A DSPATR(HI) A 5 31'Job # ' A DSPATR(HI) * Footer A R SCN001F1 A 23 2'F3=Exit F5=Refresh' A COLOR(BLU) * Format for displaying user's screen A R SCN001R1 A CSRLOC(ROW COLUMN) A ROW 3 0H A COLUMN 3 0H A SCNDTA 1919 1 2 * Format for displaying job infor on line 24 A R SCN001F2 OVERLAY CLRL(1) A INFO 78 24 2DSPATR(HI)
The Display User Screen Utility
Figure 6: RPG Program SCN001RG
*=============================================================== * To compile: * * CRTRPGPGM PGM(XXX/SCN001RG) SRCFILE(XXX/QRPGSRC) * *=============================================================== *. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 FSCN001DFCF E WORKSTN F S1RRN KSFILE SCN001S1 FQADSPOBJIF E DISK UC E SDTA 1919 1 ISCNDTA DS 1919 IDQDATA DS I 21920 SDTA I 19211921 BINROW I 19221922 BINCOL IODOBTX DS I 1 10 JOBNAM I 11 20 USERID I 21 26 JOBNUM I DS I B 1 20BINVAL I 2 2 BINCHR I 'Job displayed:' C BTXT I 'F3=Exit F5=Refresh -C ETXT I ' Enter=Continue' I 'No qualified interac-C NJMSG I 'tive jobs found.' * C *ENTRY PLIST C PARM DQNAME 10 * Load list of active jobs C EXSR LOAD * Continue until F3 is pressed C *INKC DOUEQ*ON C WRITESCN001F1 C WRITESCN001F2 C EXFMTSCN001C1 C *INKC CASEQ*ON EOJ C *INKE CASEQ*ON LOAD C CAS PROCRQ C ENDCS * C MOVEL*BLANKS INFO C ENDDO ***************************************************************** * Load subfile with list of active jobs C LOAD BEGSR * C MOVE *ON *IN21 C MOVE *OFF *IN22 C WRITESCN001C1 C MOVE *OFF *IN21 C MOVE *ZEROS S1RRN 30 * * Load file with list C CALL 'SCN002CL' C PARM '0' NORCDS 1 C NORCDS IFEQ *OFF C OPEN QADSPOBJ * * Read list and load subfile C *IN90 DOUEQ*ON C READ QADSPOBJ 90 C *IN90 IFNE *ON C MOVE *ON *IN22 C MOVELJOBNAM S1JOB C MOVELUSERID S1USER C MOVELJOBNUM S1JOBN C ADD 1 S1RRN C WRITESCN001S1 C ENDIF C ENDDO * C CLOSEQADSPOBJ C ELSE C MOVELNJMSG INFO C ENDIF C ENDSR ***************************************************************** C PROCRQ BEGSR * Process requests C *IN90 DOUEQ*ON C READCSCN001S1 90 * C *IN90 IFNE *ON * Option 5 = display screen C S1OPT IFEQ '5' C NORCDS ANDEQ*OFF C EXSR DSPSCN C MOVE *BLANK S1OPT C UPDATSCN001S1 C ENDIF C ENDIF C ENDDO * C ENDSR ***************************************************************** * Display user screen C DSPSCN BEGSR * Continue as long as F5 is pressed C *INKE DOUNE*ON * Retrieve the screen C CALL 'SCN003CL' C PARM S1JOBN C PARM DQNAME C PARM *BLANKS DQDATA * * Format data for output C MOVEASDTA SCNDTA * * The text field contains the job information C MOVELBTXT INFO P C INFO CAT S1JOBN:1 INFO C INFO CAT '/':0 INFO C INFO CAT S1USER:0 INFO C INFO CAT '/':0 INFO C INFO CAT S1JOB:0 INFO C INFO CAT ETXT:1 INFO * * Convert row and column from binary C MOVE *ZEROS BINVAL C MOVE BINROW BINCHR C Z-ADDBINVAL ROW C MOVE BINCOL BINCHR C Z-ADDBINVAL COLUMN * * Display the screen C WRITESCN001R1 C EXFMTSCN001F2 * F3 = Exit C *INKC IFEQ *ON C EXSR EOJ C ENDIF C ENDDO C ENDSR ***************************************************************** C EOJ BEGSR C MOVE *ON *INLR C RETRN C ENDSR
The Display User Screen Utility
Figure 7: CL Program SCN002CL
/*==================================================================*/ /* To compile: */ /* */ /* CRTCLPGM PGM(XXX/SCN002CL) SRCFILE(XXX/QCLSRC) */ /* */ /*==================================================================*/ SCN002CL: PGM PARM(&NORCDS) DCL VAR(&NORCDS) TYPE(*CHAR) LEN(1) /* Remove jobs which are inactive (active jobs will lock the MSGQ */ DLTMSGQ MSGQ(QRPLOBJ/DSPM*) MONMSG MSGID(CPF0000) /* Create list of DSPM* MSGQs in QTEMP library */ DSPOBJD OBJ(QRPLOBJ/DSPM*) OBJTYPE(*MSGQ) + OUTPUT(*OUTFILE) OUTFILE(QTEMP/QADSPOBJ) + OUTMBR(*FIRST *REPLACE) MONMSG MSGID(CPF2123) EXEC(CHGVAR VAR(&NORCDS) + VALUE('1')) ENDPGM: ENDPGM
The Display User Screen Utility
Figure 8: CL Program SCN003CL
/*==================================================================*/ /* To compile: */ /* */ /* CRTCLPGM PGM(XXX/SCN003CL) SRCFILE(XXX/QCLSRC) */ /* */ /*==================================================================*/ SCN003CL: PGM PARM(&JOBNBR &DTAQ &DQDATA) DCL VAR(&JOBNBR) TYPE(*CHAR) LEN(6) DCL VAR(&DQDATA) TYPE(*CHAR) LEN(1922) DCL VAR(&DTAQ) TYPE(*CHAR) LEN(10) DCL VAR(&DQSIZE) TYPE(*DEC) LEN(5 0) DCL VAR(&DQWAIT) TYPE(*DEC) LEN(5 0) VALUE(60) DCL VAR(&MSGQ) TYPE(*CHAR) LEN(10) /* Send message to job to get screen */ CHGVAR VAR(&MSGQ) VALUE('DSPM' *CAT &JOBNBR) SNDMSG MSG(&DTAQ) TOMSGQ(QRPLOBJ/&MSGQ) /* Wait (up to a minute) for the response */ CALL PGM(QRCVDTAQ) PARM(&DTAQ 'QRPLOBJ' &DQSIZE + &DQDATA &DQWAIT) ENDPGM: ENDPGM
The Display User Screen Utility
Figure 9: CL Program SCN004CL
/*==================================================================*/ /* To compile: */ /* */ /* CRTCLPGM PGM(XXX/SCN004CL) SRCFILE(XXX/QCLSRC) */ /* */ /*==================================================================*/ SCN004CL: PGM DCL VAR(&MSGQ) TYPE(*CHAR) LEN(10) DCL VAR(&NBR) TYPE(*CHAR) LEN(6) DCL VAR(&TEXT) TYPE(*CHAR) LEN(50) DCL VAR(&USER) TYPE(*CHAR) LEN(10) DCL VAR(&JOB) TYPE(*CHAR) LEN(10) /* Unique message queue name is 'DSPM' plus job number */ RTVJOBA JOB(&JOB) USER(&USER) NBR(&NBR) CHGVAR VAR(&MSGQ) VALUE('DSPM' *CAT &NBR) /* Put job info in text field */ CHGVAR VAR(&TEXT) VALUE(&JOB *CAT &USER *CAT &NBR) /* Create message queue in QRPLOBJ */ CRTMSGQ MSGQ(QRPLOBJ/&MSGQ) TEXT(&TEXT) AUT(*ALL) /* Set break handling program */ CHGMSGQ MSGQ(QRPLOBJ/&MSGQ) DLVRY(*BREAK) PGM(SCN005CL) ENDPGM: ENDPGM
The Display User Screen Utility
Figure 10: Display File SCN005DF
*=============================================================== * To compile: * * CRTDSPF FILE(XXX/SCN005DF) SRCFILE(XXX/QDDSSRC) * *=============================================================== *. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ** Dummy display file for compiling SCN005CL A R SCN005R1 A R1DATA1 1782 B 1 2 A R1DATA2 1782 B 1 2
The Display User Screen Utility
Figure 11: CL Program SCN005CL
/*==================================================================*/ /* To compile: */ /* */ /* CRTCLPGM PGM(XXX/SCN005CL) SRCFILE(XXX/QCLSRC) */ /* */ /*==================================================================*/ SCN005CL: PGM PARM(&MSGQ &MSGQLIB &MSGREF) DCL VAR(&MSGQ) TYPE(*CHAR) LEN(10) DCL VAR(&MSGQLIB) TYPE(*CHAR) LEN(10) DCL VAR(&MSGREF) TYPE(*CHAR) LEN(4) DCL VAR(&DTAQ) TYPE(*CHAR) LEN(10) DCL VAR(&DQSIZE) TYPE(*DEC) LEN(5 0) VALUE(1922) DCL VAR(&SCREENDATA) TYPE(*CHAR) LEN(1920) DCL VAR(&DQDATA) TYPE(*CHAR) LEN(1922) DCLF FILE(SCN005DF) /* Receive and remove the data queue name from the message queue */ RCVMSG MSGQ(&MSGQLIB/&MSGQ) RMV(*YES) MSG(&DTAQ) /* If this is a group job the data queue may not exist any more */ CHKOBJ OBJ(QRPLOBJ/&DTAQ) OBJTYPE(*DTAQ) MONMSG MSGID(CPF9801) EXEC(RETURN) /* Retrieve current screen using a UDDS command */ OVRDSPF FILE(SCN005DF) TOFILE(SCN006DF) LVLCHK(*NO) CHGVAR VAR(&R1DATA1) VALUE(X'00021518730462') SNDRCVF RCDFMT(SCN005R1) CHGVAR VAR(&SCREENDATA) VALUE(&R1DATA1 *CAT + &R1DATA2) /* Retrieve cursor location using a UDDS command */ CHGVAR VAR(&R1DATA1) VALUE(X'00021518730472') SNDRCVF RCDFMT(SCN005R1) CHGVAR VAR(&DQDATA) VALUE(&SCREENDATA *CAT &R1DATA1) /* Send the screen to the data queue */ CALL PGM(QSNDDTAQ) PARM(&DTAQ 'QRPLOBJ' &DQSIZE + &DQDATA) ENDPGM: ENDPGM
The Display User Screen Utility
Figure 12: Display File SCN006DF
*=============================================================== * To compile: * * CRTDSPF FILE(XXX/SCN006DF) SRCFILE(XXX/QDDSSRC) * *=============================================================== *. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ** Display file for reading current screen * * User defined data streams A R SCN005R1 USRDFN * * Dummy format so buffer size will be correct in file A R SCN005R2 A FILLER1 1782 B 1 2 A FILLER2 1782 B 1 2
LATEST COMMENTS
MC Press Online