Return to the Query Tips
Trapping A Canceled RUNQRY Command
Hey Ted:
Is there a way to determine in a CL program when a user has pressed F3 or F12 to cancel the Run Query (RUNQRY) command?
There sure is. In fact, here are two methods, courtesy of Tom Liotta of PowerTech Group (http://www.400security.com) and Carsten Flensburg.
Pressing F3 or F12 places a character 1 in byte 103 or 104 respectively. To test for the use of these keys, Tom uses the QUSRJOBI (Retrieve Job Information) API. Tom provided his code, which I have modified slightly. First, I shortened the lines that were too long for the format of this newsletter. Second, I added the return commands to the do groups. Third, I added the OUTTYPE(*PRINTER) parameter to the RUNQRY command. That's not necessary, but trapping a cancel request probably makes more sense when output is to be sent to a printer, since OUTTYPE(*DISPLAY) causes RUNQRY to be prompted repeatedly until the operator cancels it. In other words, the test will always prove true with OUTTYPE(*DISPLAY), so why bother to test it?
Tom had separate tests for F3 and F12. If you don't care which key the operator pressed, you can combine the two conditions under one IF statement and have only one do group.
Tom adds, "This code can be used in many cases for functions that do not send messages when canceled. I believe this is standard for UIM-based functions."
dcl &a_len *char 4 /* Bin Data/Entry length */ dcl &a_rcv *char 1000 /* Receiver Variable, the */ /* length is variable. It */ /* must be in &A_LEN. */ dcl &msgdta *char 256 dcl &Action *char 20 + value( 'RUNQRY RCDSLT(*YES)' ) Qsys/runqry Range1 outtype(*PRINTER) rcdslt(*YES) /* ---------------------------------------------------*/ /* Test for cancel */ /* ---------------------------------------------------*/ chgvar %bin( &a_len 1 4 ) 307 Qsys/call QUSRJOBI ( + &a_rcv + &a_len + 'JOBI0600' + '*' + ' ' + ) /* Test job status for *CANCEL (F12) */ if ( %sst( &a_rcv 104 1 ) *eq '1' ) do chgvar &msgdta ( + 'Action' *bcat + &Action *bcat + 'cancelled.' + ) Qsys/sndpgmmsg msgid( CPF9897 ) + msgf( QSYS/QCPFMSG ) + msgdta( &msgdta ) + msgtype( *INFO ) return enddo /* Test job status for *EXIT (F3) */ if ( %sst( &a_rcv 103 1 ) *eq '1' ) do chgvar &msgdta ( + 'Action' *bcat + &Action *bcat + 'cancelled.' + ) Qsys/sndpgmmsg msgid( CPF9897 ) msgf( QSYS/QCPFMSG ) + msgdta( &msgdta ) + msgtype( *INFO ) return enddo /* ---------------------------------------------------*/ /* RUNQRY was not canceled */ /* ---------------------------------------------------*/The second method comes from Carsten Flensburg. He uses the QWCRTVCA (Retrieve Current Attributes) API to query the two attributes holding the flags for F3 and F12, then resets the two job attributes using the QWCCCJOB (Change Current Job) API.
Load the following code into an RPGLE source member named GETXIT. Compile it using the Create Bound RPG Program (CRTBNDRPG) command. (You can recompile it as a module and, if you wish, add it to a service program.)
**-- Parameter: -------------------------------------------- D Fkey s 3 **-- QWCRTVCA API: ---------------------------------------- D CurAtr Ds D AtNbrAtrRtn 10i 0 D AtAtrLen1 10i 0 D AtAtrKey1 10i 0 D AtAtrDtaTyp1 1a D 3a D AtAtrDtaLen1 10i 0 D F12 1n D 3a D AtAtrLen2 10i 0 D AtAtrKey2 10i 0 D AtAtrDtaTyp2 1a D 3a D AtAtrDtaLen2 10i 0 D F3 1n D 3a ** D CurAtrLen s 10i 0 Inz( %Len( CurAtr )) D FmtNam s 8a Inz( 'RTVC0100' ) D KeyFldNbr s 10i 0 Inz( 2 ) D KeyFlds Ds D 10i 0 Inz( 301 ) D 10i 0 Inz( 503 ) **-- QWCCCJOB API: ---------------------------------------- D ChgAtr Ds D CaAtrFldNbr 10i 0 Inz( 2 ) D CaAtrKey1 10i 0 Inz( 1 ) D CaAtrLen1 10i 0 Inz( 1 ) D CaAtrVal1 1a Inz( '0' ) D CaAtrKey2 10i 0 Inz( 2 ) D CaAtrLen2 10i 0 Inz( 1 ) D CaAtrVal2 1a Inz( '0' ) ** D ApiError Ds D AeBytAvl 10i 0 Inz( 8 ) D AeBytRtn 10i 0 Inz( 0 ) ** C *Entry Plist C Parm Fkey ** C Call 'QWCRTVCA' C Parm CurAtr C Parm CurAtrLen C Parm FmtNam C Parm KeyFldNbr C Parm KeyFlds C Parm ApiError ** C Call 'QWCCCJOB' C Parm ChgAtr C Parm ApiError ** C Select C When F3 C review Fkey = 'F3' C When F12 C review Fkey = 'F12' C Other C review Fkey = *Blanks C EndSl ** C Return To test this routine, create a CL program called QRY001CL from the following source code: Dcl &Fkey *Char 3 Runqry Q1 RcdSlt( *YES ) OutType( *PRINTER ) Call GETXIT &Fkey If ( &Fkey *GT ' ' ) GoTo EndPgm /* ...continue processing */ Endpgm: EndPgmQRY001CL executes the RUNQRY command specifying that the record select panel should be presented before execution. Then it calls the GETXIT RPG/IV program to have it check if the Exit or Cancel key was pressed.
Thanks to Carsten and Tom for sharing these useful techniques with Midrange Guru and your fellow readers.
-- Ted
[report a broken link by clicking here]