fhg
Volume 7, Number 7 -- February 21, 2007

Admin Alert: Automatically Moving Printed Spooled Files Between Output Queues

Published: February 21, 2007

by Joe Hertvik

A reader recently wrote in looking for an automated technique to move spooled files between i5/OS output queues after printing. His goal was to retain spooled files in an output queue with a longer retention date than the printer output queue that the files were originally printed to. This week, I'll look at a utility program that performs this function and the benefits it can provide your shop.

The Basic Template

In my research, I found that IBM didn't seem to offer any APIs to perform a function similar to what I was looking for with this utility. This led me to create my own utility, based on another program I had previously created. In order to automatically move printed spooled files from a source output queue to a target output queue, I started with the following basic assumptions and requirements.

1.  The spooled files to be moved have already been printed and saved in the source output queue. That is, their status will be marked as 'SAV' (saved). I'm assuming that these files had been marked as saved after printing through the use of an Override with Printer File command (OVRPRTF) before creation. Working with an already printed file is the minimum requirement that must be met before a spooled file becomes eligible to be moved to the longer retention output queue.

2.  The spooled files to be moved are identifiable. The solution needs to capture all the data about all the spooled files in the source output queue, so that it can uniquely identify each file to be moved to the target output queue.

This latter requirement also allows the code to look through the queue and pick out files to move according to the content of other spooled file attributes (besides the fact that a spooled file has already been printed and saved on the system). The additional attributes that it can examine for determining spooled file moves include the spooled file name; the user name who created the file; the value in the spooled file User Data field; or the form type. Although I could add several more tests to the code for determining which spooled files to move, the code for this example will only move those spooled files with a spooled file status of 'SAV', as indicated in requirement 1.

Having these two requirements for moving a spooled file, I created a CL program to move all the printer files that meet my criteria. This program is based on another program I earlier wrote that selectively deletes spooled files from an output queue. My new CL program is called MOVSPLF and it requires two things:

  1. A work file called WRKOUTQPRT, which contains a listing of all the spooled files in the source output queue; and
  2. Four parameters that designate the source output queue and library that the spooled files will be moved from and the target output queue and library where the spooled files will be moved to

Knowing these requirements and parameters, it was fairly easy to modify my original solution to meet this need (for a more complete explanation of some of the components that make up MOVSPLF, see the article titled Selectively Deleting Spooled Files).

The Solution

To create this solution, here's the DDS code I needed for creating the WRKOUTQPRT file. WRKOUTQPRT will contain the captured spooled file information from the source output queue.

A          R QPRTSPLQ                                               
A            FILL0          1A         TEXT('FILLER')               
A            SPLFIL        10A         TEXT('SPOOLED FILE NAME')            
A            FILL1          1A         TEXT('FILLER')               
A            USER          10A         TEXT('USER NAME')            
A            FILL2          1A         TEXT('FILLER')               
A            USRDTA        10A         TEXT('USER DATA')            
A            FILL3          2A         TEXT('FILLER')               
A            STATUS         5A         TEXT('STATUS')               
A            FILL4          1A         TEXT('FILLER')               
A            PAGES          5A         TEXT('NUMBER OF PAGES')      
A            FILL5          1A         TEXT('FILLER')               
A            COPIES         5A         TEXT('NUMBER OF COPIES')     
A            FILL6          2A         TEXT('FILLER')               
A            FRMTYP        10A         TEXT('FORM TYPE')            
A            FILL7          1A         TEXT('FILLER')               
A            PTY            2A         TEXT('PRIORITY')             
A            FILL8          5A         TEXT('FILLER')               
A            FILNUM         6A         TEXT('FILE NUMBER')          
A            FILL9          5A         TEXT('FILLER')      
A            JOB           10A         TEXT('JOB NAME')    
A            FILL10         1A         TEXT('FILLER')      
A            JOBNUM         6A         TEXT('JOB NUMBER')  
A            FILL11         1A         TEXT('FILLER')      
A            JOBDTE         8A         TEXT('JOB DATE')    
A            FILL12        22A         TEXT('FILLER')      

MOVSPLF uses this file to create a list of all the current spooled files in the source output queue. My WRKOUTQPRT DDS is a roll your own file that was created by mapping the lines on the Work with Output queue report (QPRTSPLQ) to DDS specifications. This is necessary because IBM doesn't offer any physical file output from the WRKOUTQ command, so you should be aware that the report layout could change if and when you update your AS/400, i5, and iSeries to a newer version of the i5/OS operating system.

Here's the code for the MOVSPL program. This program automatically moves all spooled files with a status of 'SAV' from the source output queue to the target output queue.

0001.00    PGM        PARM(&OUTQNAME &OUTQLIB &TGTOUTQ &TGTOUTQLIB)   
0002.00    DCL        VAR(&OUTQNAME) TYPE(*CHAR) LEN(10)  
0003.00    DCL        VAR(&OUTQLIB) TYPE(*CHAR) LEN(10)       
0004.00    DCL        VAR(&TGTOUTQ) TYPE(*CHAR) LEN(10)     
0005.00    DCL        VAR(&TGTOUTQLIB) TYPE(*CHAR) LEN(10) 
0006.00    
0007.00    DCL        VAR(&COUNTER) TYPE(*DEC) LEN(15 5) VALUE(1) 
0008.00    DCL        VAR(&WORK) TYPE(*CHAR) LEN(1) VALUE('0')        
0009.00    DCL        VAR(&WORK1) TYPE(*CHAR) LEN(1) VALUE('0')       
0010.00    DCL        VAR(&ZERO) TYPE(*CHAR) LEN(1) VALUE('0')        
0011.00    DCL        VAR(&COPIES1) TYPE(*CHAR) LEN(5) VALUE(' ')     
0012.00    DCL        VAR(&FILNUM1) TYPE(*CHAR) LEN(6) VALUE(' ')     
0013.00    
0014.00    
0015.00    DCLF       FILE(WRKOUTQPRT)                                
0016.00    
0017.00    CHKOBJ     OBJ(QTEMP/WRKOUTQPRT) OBJTYPE(*FILE)            
0018.00    MONMSG     MSGID(CPF9801) EXEC(CRTDUPOBJ +                 
0019.00    OBJ(WRKOUTQPRT) FROMLIB(QGPL) +               
0020.00    OBJTYPE(*FILE) TOLIB(QTEMP))               
0021.00    
0022.00    OVRDBF     FILE(WRKOUTQPRT) TOFILE(QTEMP/WRKOUTQPRT) +  
0023.00    MBR(*FIRST)                                
0024.00    
0025.00    WRKOUTQ    OUTQ(&OUTQLIB/&OUTQNAME) OUTPUT(*PRINT)      
0026.00    
0027.00    CPYSPLF    FILE(QPRTSPLQ) TOFILE(QTEMP/WRKOUTQPRT) +    
0028.00    SPLNBR(*LAST)                              
0029.00    
0030.00    GETIT:                                                  
0031.00    RCVF                                                    
0032.00    MONMSG     MSGID(CPF0864) EXEC(GOTO CMDLBL(ENDPGM))     
0033.00    
0034.00    CHGVAR     VAR(&COPIES1) VALUE(' ')                     
0035.00    
0036.00    CHGVAR     VAR(&FILNUM1) VALUE(' ')                     
0037.00    CHGVAR     VAR(&COUNTER) VALUE(0)                       
0038.00    COUNT:                                                  
0039.00    
0040.00    IF         COND(&COUNTER *LT 6) THEN(DO)                 
0041.00    CHGVAR     VAR(&COUNTER) VALUE(&COUNTER + 1)             
0042.00    
0043.00    IF         COND(&COUNTER *LT 6) THEN(DO)                 
0044.00    CHGVAR     VAR(&WORK) VALUE(%SST(&COPIES &COUNTER 1))    
0045.00    
0046.00    IF         COND(&WORK *EQ ' ') THEN(CHGVAR +             
0047.00    VAR(&COPIES1) VALUE(&COPIES1 *TCAT &ZERO))  
0048.00    ELSE       CMD(CHGVAR VAR(&COPIES1) VALUE(&COPIES1 +     
0049.00         *TCAT &WORK))                               
0050.00    ENDDO                                                    
0051.00                                                                       
0052.00    CHGVAR     VAR(&WORK1) VALUE(%SST(&FILNUM &COUNTER 1))   
0053.00    IF         COND(&WORK1 *EQ ' ') THEN(CHGVAR +            
0054.00    VAR(&FILNUM1) VALUE(&FILNUM1 *TCAT &ZERO))  
0055.00    ELSE       CMD(CHGVAR VAR(&FILNUM1) VALUE(&FILNUM1 +     
0056.00                      *TCAT &WORK1))                              
0057.00    GOTO       CMDLBL(COUNT)                                 
0058.00                                                                       
0059.00    ENDDO                                                    
0060.00                                                                        
0061.00                                                                        
0062.00    IF         COND(&COPIES1 *LE '00000') THEN(GOTO +         
0063.00                CMDLBL(GETIT))                               
0064.00                                                                        
0065.00   IF         COND(&COPIES1 *GE '99999') THEN(GOTO +         
0066.00                CMDLBL(GETIT))                               
0067.00                                                                        
0068.00                                                                        
0069.00                                                                        
0070.00                                                                        
0071.00   IF         COND(&STATUS *EQ 'SAV') THEN(DO)               
0072.00   CHGSPLFA   FILE(&SPLFIL) JOB(&JOBNUM/&USER/&JOB) +        
0073.00                SPLNBR(&FILNUM1) OUTQ(&TGTOUTQLIB/&TGTOUTQ)  
0074.00   ENDDO                                                     
0075.00                                                                        
0076.00   GOTO       CMDLBL(GETIT)                                  
0077.00                                                                        
0078.00   ENDPGM:                                                     
0079.00                                                  
0080.00   DLTOVR     FILE(WRKOUTQPRT)           
0081.00                                                  
0082.00   DLTF       FILE(QTEMP/WRKOUTQPRT)     
0083.00                                                  
0084.00   ENDPGM                                

MOVSPLF works in the following way.

  1. The source and target output queues and their libraries are passed in as parameters with the program call (statement 1.00).
  2. MOVSPLF creates a temporary copy of the WRKOUTQPRT file in the QTEMP library and uses the Work with Output Queue command (WRKOUTQ) to create a printout containing information about all the spooled files in the source output queue (statements 17.00 through 26.00). It then uses the Copy Spooled File command (CPYSPLF) to copy the WRKOUTQ information from the QPRTSPLQ report into the temporary WRKOUTQPRT file, providing a physical file record of all the spooled files residing in that output queue (statements 27.00-28.00).
  3. The program reads all the records in the WRKOUTQPRT file to determine whether or not the spooled files they represent should be moved to the target output queue. Before MOVSPLF can evaluate the records, it needs to zero-fill two numeric fields that will be used in the logic. The code zero-fills the number of copies field and the spooled file number field (statements 34.00-60.00). The full fields will be used in later sections of the code.
  4. Because the populated WRKOUTQPRT file essentially contains a line by line copy of the QPRTSPLQ report, this means that not every record in that report will describe an actual spooled file. Some of the records will contain the report header and other report line information that was used to create the report. To determine which records list off information on spooled files that I may want to move, I look for records where the number of copies field contains a literal between '00000' and '99999' (statements 62.00-66.00). If the program is looking at a record that does not have a numeric value in this field, it doesn't evaluate that record for moving a spooled file. That's why the program zero-filled the number of copies field in statements 34.00-60.00.
  5. The file looks to see if the current record's spooled file status is 'SAV', which means that the spooled file listed in this record has been printed. If it's been printed, the code uses the Change Spool File Attributes command (CHGSPLFA) to move the file to the target output queue (statements 71.00-74.00). Notice that CHGSPLFA uses the zero-filled job number field to help identify which spooled file to move.
  6. The program ends and cleans up after itself by deleting the file override it used to read the WRKOUTQPRT file in QTEMP. It then deletes the temporary copy of WRKOUTQPRT that it created in the QTEMP library (statements 78.00-84.00).

The end result of this program is that it moves all printed and saved spooled files from the source output queue to the target output queue. If you want to further refine the files that are moved, you could also pass in additional qualifiers to be used in statements 71.00-74.00, which would allow you to compare the spooled files by user name (versus the USER field in the WRKOUTQPRT file), spooled file name (versus WRKOUTQPRT's SPLFIL field), the spooled file's user data field (the USRDTA field), form type (FRMTYP), or job name (JOB). You can get more versatile with this code and pass in any number of fields to determine whether or not you want to move a particular spooled file to the target output queue.

The other nice thing that you could do with this program is to turn it into a server job, where it can run as an infinitely looping batch job that evaluates and moves spooled files as they enter the source output queue and are printed. To do that, I would first put a LOOP: label in front of the WRKOUTQ statement on statement 22.00. Then, to allow the program to loop through its evaluation every half-hour, I would place the following lines after statement 78.

0078.01              CLRPFM     FILE(QTEMP/WRKOUTQPRT)  
0078.02              DLYJOB     DLY(1800)               
0078.03              GOTO       CMDLBL(LOOP)            

Statement 78.01 clears the WRKOUTQPRT work file after usage, statement 78.02 delays the job for a half-hour before beginning processing again, and statement 78.03 sends the job back to the beginning of the loop where WRKOUTQPRT can be reloaded and re-evaluated for new spooled files that can be moved to the target output queue.

Adding these statements would allow the program to act as a server. If you do this, however, you may also want to add some code to end the program after a certain number of iterations. If you don't want MOVSPLF to function as a server job, you could also set it up in the i5 job scheduler to run several times a day.

About Our Testing Environment

All configurations described in this article were tested on an i5 box running i5/OS V5R3. However, most of these commands and features are also available on i5/OS V5R4 and most earlier versions of OS/400 V4R5 and below running on AS/400 and iSeries machines.


RELATED STORY

Selectively Deleting Spooled Files



                     Post this story to del.icio.us
               Post this story to Digg
    Post this story to Slashdot


Sponsored By
RPG & DB2 Summit

Take it to the SUMMIT!

 

On March 20-22, the leading RPG & DB2
minds will convene at the RPG & DB2 Summit
in Las Vegas to offer three days of intensive
education. Learn the latest in practical tips and
techniques from gurus Jon Paris, Susan
Gantner
, Paul Tuohy, Skip Marchesani,
Scott Klement and others in a highly
interactive, focused, fun environment.

 

Learn more about the best training
value of 2007
and register today!

 

SystemiDeveloper.com


Senior Technical Editor: Ted Holt
Technical Editors: Howard Arner, Joe Hertvik, Shannon O'Donnell, Kevin Vandever
Contributing Technical Editors: Joel Cochran, Wayne O. Evans, Raymond Everhart,
Bruce Guetzkow, Brian Kelly, Marc Logemann, David Morris
Publisher and Advertising Director: Jenny Thomas
Advertising Sales Representative: Kim Reed
Contact the Editors: To contact anyone on the IT Jungle Team
Go to our contacts page and send us a message.

Sponsored Links

Aldon:  ALM solutions to accelerate your application development
COMMON:  Join us at the 2007 conference, April 29 – May 3, in Anaheim, California
Maximum Availabilty:  Secure, cost-effect, real-time iSeries replication software


Books on Sale at the IT Jungle Store: 30 Percent Off for 30 Days

The System i Pocket RPG & RPG IV Guide: List Price, $69.95; Sale Price, $49.00
The iSeries Pocket Database Guide: List Price, $59.00; Sale Price, $41.00
The iSeries Pocket Developers' Guide: List Price, $59.00; Sale Price, $41.00
The iSeries Pocket SQL Guide: List Price, $59.00; Sale Price, $41.00
The iSeries Pocket Query Guide: List Price, $49.00; Sale Price, $34.00
The iSeries Pocket WebFacing Primer: List Price, $39.00; Sale Price, $27.00
Migrating to WebSphere Express for iSeries: List Price, $49.00; Sale Price, $34.00
iSeries Express Web Implementer's Guide: List Price, $59.00; Sale Price, $41.00
Getting Started with WebSphere Development Studio for iSeries: List Price, $79.95; Sale Price, $56.00
Getting Started With WebSphere Development Studio Client for iSeries: List Price, $89.00; Sale Price, $62.00
Getting Started with WebSphere Express for iSeries: List Price, $49.00; Sale Price, $34.00
WebFacing Application Design and Development Guide: List Price, $55.00; Sale Price, $38.00
Can the AS/400 Survive IBM?: List Price, $49.00; Sale Price, $34.00
The All-Everything Machine: List Price, $29.95; Sale Price, $21.00
Chip Wars: List Price, $29.95; Sale Price, $21.00

 

The Four Hundred
In Formation: Q&A with Infor Chairman Jim Schaper

GST Says Buy Cheaper i5 Disk Controllers and Lots of Disks

Chip Makers Strut Their Stuff at ISSCC

Mad Dog 21/21: Paved With Good Intentions

The Linux Beacon
Chip Makers Strut Their Stuff at ISSCC

AMD Delivers Faster and Cooler Rev F Opteron Chips

Zend Upgrades Commercial Add-Ons for Its PHP Engine

As I See It: Measuring What Counts

Four Hundred Stuff
Lawson Brings Former Intentia ERP Suite Closer to Landmark

iSeries Web Adventures Call with iSafari

Valid Tech Assimilates Biometric Authentication Into the Enterprise

Gumbo's Dumpster Dives Into i5/OS Spool Files

Big Iron
IBM Previews Future z/OS, z/VM Mainframe Operating Systems

Top Mainframe Stories From Around the Web

Chats, Webinars, Seminars, Shows, and Other Happenings

System i PTF Guide
February 17, 2007: Volume 9, Number 7

February 10, 2007: Volume 9, Number 6

February 3, 2007: Volume 9, Number 5

January 27, 2007: Volume 9, Number 4

January 20, 2007: Volume 9, Number 3

January 13, 2007: Volume 9, Number 2

The Windows Observer
Microsoft Moves Forward on Post Vista Windows OSes

Microsoft Issues a Dozen Security Patches, Fixes Security Tools

Chip Makers Strut Their Stuff at ISSCC

Microsoft Launches Windows Mobile 6

The Unix Guardian
HP Adds Entry Itanium Servers, Finally Delivers HP-UX 11i v3

Unix Is Dead? It Isn't Even Sick. . .

Chip Makers Strut Their Stuff at ISSCC

As I See It: Measuring What Counts

Four Hundred Monitor
Four Hundred Monitor's
Full iSeries Events Calendar

THIS ISSUE SPONSORED BY:

SEQUEL
WorksRight Software
RPG & DB2 Summit



TABLE OF CONTENTS
Get Connected with Remote Systems Explorer

A Handy Tip for Testing Batch Job Streams

Admin Alert: Automatically Moving Printed Spooled Files Between Output Queues

Four Hundred Guru

BACK ISSUES

From the IT Jungle Forums
'Piping' output from OS400 commands

iSociety

RSTOBJ to a specific library

SQL Function, Not Procedure

Entry parms getting overlayed--RPG





 
Subscription Information:
You can unsubscribe, change your email address, or sign up for any of IT Jungle's free e-newsletters through our Web site at http://www.itjungle.com/sub/subscribe.html.

Copyright © 1996-2008 Guild Companies, Inc. All Rights Reserved.
Guild Companies, Inc., 50 Park Terrace East, Suite 8F, New York, NY 10034

Privacy Statement