Newsletters   Subscriptions  Forums  Store   Career  Media Kit  About Us  Contact  Search   Home 
fhg
Volume 5, Number 44 -- November 30, 2005

Selectively Deleting OS/400 Spool Files


Hey, Joe:


My users insist on saving labels and printouts after they are printed. And the worst part is that I can't just clear the output queues containing these spooled files because the company is asking me to keep the most recent spooled files for 30 days. Do you have any idea how I can selectively delete spooled files in an output queue that are more than 30 days old while leaving more recent printouts intact?

--Simon


While i5/OS and OS/400 provide options for automatically deleting system joblogs and other system output after a set number of days, there is no option for automatically deleting spooled file output stored in non-IBM output queues. To remedy this failing, I looked at the options and I came up with a quick CL program for automatically putting spooled file attribute information into a work file and then using that file to selectively delete spooled files in an output queue that meet a certain criteria. Here's how it works.

The key to selectively deleting spooled files is to generate a list of the spooled files included in that output queue and then to copy that information into an OS/400 physical file for automated deletion. To generate my work physical file, I first ran the following Work with Output Queue command (WRKOUTQ).

WRKOUTQ OUTQ(LIBRARY_NAME/OUTPUT_QUEUE_NAME)
OUTPUT(*PRINT)

This command produces a printout with a spooled file name of QPRTSPLQ. This printout contains all the file attributes of all the spooled files residing in the designated output queue. These attributes include the spooled file name, user name, job name, and job number that produced the file, as well as the spooled file number, user data, file status, and the date and time that the file was produced. Once I had that printout, I then used a Copy Spooled File command (CPYSPLF), such as the one shown below, to port that information into an OS/400 file.

CPYSPLF FILE(QPRTSPLQ) TOFILE(LIBRARY_NAME/WRKOUTQPRT)
SPLNBR(*LAST)

Although there is no OS/400 file that provides a physical file layout for the WRKOUTQPRT file that I am porting this information to, I created my own layout that codifies the information for each spooled file contained in the QPRTSPLQ report. Here is the layout for the WRKOUTQPRT file used in this article.

A          R QPRTSPLQ                                            
A            FILL0          1A         TEXT('FILLER')            
A            SPLFIL        10A         TEXT('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('# OF PAGES')   
A            FILL5          1A         TEXT('FILLER')            
A            COPIES         5A         TEXT('# 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')      

Once I worked through the mechanics of creating a spooled file information file and compiled the DDS for the WRKOUTQPRT file, I could then create a CL program that creates and reads through that file and automatically deletes any spool files that meet my criteria. Here's the code I used to create the program.

PGM        PARM(&OUTQNAME &OUTQLIB)                          
                                                             
DCL        VAR(&OUTQNAME) TYPE(*CHAR) LEN(10) 
DCL        VAR(&OUTQLIB) TYPE(*CHAR) LEN(10) 
DCL        VAR(&COUNTER) TYPE(*DEC) LEN(15 5) VALUE(1) 
DCL        VAR(&WORK) TYPE(*CHAR) LEN(1) VALUE('0') 
DCL        VAR(&WORK1) TYPE(*CHAR) LEN(1) VALUE('0') 
DCL        VAR(&ZERO) TYPE(*CHAR) LEN(1) VALUE('0') 
DCL        VAR(&COPIES1) TYPE(*CHAR) LEN(5) VALUE(' ') 
DCL        VAR(&FILNUM1) TYPE(*CHAR) LEN(6) VALUE(' ') 
DCL        VAR(&DELETE) TYPE(*CHAR) LEN(1) 
                  
DCLF       FILE(WRKOUTQPRT) 
                                      
CHKOBJ     OBJ(QTEMP/WRKOUTQPRT) OBJTYPE(*FILE) 
MONMSG     MSGID(CPF9801) EXEC(CRTDUPOBJ + 
           OBJ(WRKOUTQPRT) FROMLIB(QGPL) + 
           OBJTYPE(*FILE) TOLIB(QTEMP)) 
                                                                   
OVRDBF     FILE(WRKOUTQPRT) TOFILE(QTEMP/WRKOUTQPRT) + 
           MBR(*FIRST) 
                                                                   
WRKOUTQ    OUTQ(&OUTQLIB/&OUTQNAME) OUTPUT(*PRINT) 
                                                                   
CPYSPLF    FILE(QPRTSPLQ) TOFILE(QTEMP/WRKOUTQPRT) + 
           SPLNBR(*LAST) 
                                                                   
GETIT:      
RCVF        
MONMSG     MSGID(CPF0864) EXEC(GOTO CMDLBL(ENDPGM)) 
                
CHGVAR     VAR(&COPIES1) VALUE(' ') 

CHGVAR     VAR(&FILNUM1) VALUE(' ') 
CHGVAR     VAR(&COUNTER) VALUE(0)   
                                                         
COUNT: 

IF         COND(&COUNTER *LT 6) THEN(DO) 
CHGVAR     VAR(&COUNTER) VALUE(&COUNTER + 1) 
                                                         
IF         COND(&COUNTER *LT 6) THEN(DO) 
CHGVAR     VAR(&WORK) VALUE(%SST(&COPIES &COUNTER 1)) 
     
IF         COND(&WORK *EQ ' ') THEN(CHGVAR + 
           VAR(&COPIES1) VALUE(&COPIES1 *TCAT &ZERO)) 
ELSE       CMD(CHGVAR VAR(&COPIES1) VALUE(&COPIES1 + 
           *TCAT &WORK)) 
ENDDO 
      
CHGVAR     VAR(&WORK1) VALUE(%SST(&FILNUM &COUNTER 1)) 
IF         COND(&WORK1 *EQ ' ') THEN(CHGVAR + 
           VAR(&FILNUM1) VALUE(&FILNUM1 *TCAT &ZERO)) 
ELSE       CMD(CHGVAR VAR(&FILNUM1) VALUE(&FILNUM1 + 
           *TCAT &WORK1)) 
GOTO       CMDLBL(COUNT) 

ENDDO                    
                              

IF         COND(&COPIES1 *LE '00000') THEN(GOTO + 
           CMDLBL(GETIT)) 
                             
IF         COND(&COPIES1 *GE '99999') THEN(GOTO + 
           CMDLBL(GETIT)) 
                                                        
CHGVAR     VAR(&DELETE) VALUE(' ') 
                
/* INSERT LOGIC TO SET THE DELETE FLAG ON HERE. WHEN A + 
SPOOLED FILE MEETS THE DELETION CRITERIA, SET THE 
&DELETE + VARIABLE TO 'Y' */
                                                        
IF         COND(&DELETE *EQ 'Y') THEN(DO) 
DLTSPLF    FILE(&SPLFIL) JOB(&JOBNUM/&USER/&JOB) + 
           SPLNBR(&FILNUM1) 
ENDDO                           
                                                        
GOTO       CMDLBL(GETIT) 

ENDPGM: 
        
DLTOVR     FILE(WRKOUTQPRT) 

DLTF       FILE(QTEMP/WRKOUTQPRT)

ENDPGM 

Here's how the code works.

The program is called and submitted to batch with two parameters specifying the name and library that you want to selectively delete spooled output files from (the &OUTQNAME and &OUTQLIB variables).

I declare my variables and I also use the Declare File command (DCLF) to declare that the program is going to use the WRKOUTQPRT file shown above as its input file.


Using the Check Object command (CHKOBJ), I check to see if a copy of the WRKOUTQPRT file already resides in the job's temporary library, QTEMP. If the file is not there, I use the Create Duplicate Object command (CRTDUPOBJ) to create a copy of WRKOUTQPRT in QTEMP. Then I use the Override with Database File command (OVRDBF) to redirect any calls to the WRKOUTQPRT file to the version of the file that is now residing in my temporary library. I am using the QTEMP version of the file so that I can simultaneously run the program in two job queues without creating a conflict as two jobs try to lock the WRKOUTQPRT file at the same time.

I next populate the WRKOUTQPRT file with spooled file information from my designated job queue by using the WRKOUTQ and CPYSPLF commands as I explained above.

At the GETIT: label, the program enters the first of two loops. The GETIT: loop uses the Receive File command (RCVF) to read one record at a time from the WRKOUTQPRT file. It then performs all the processing to determine if the spooled file represented by that record should be deleted.

Inside the GETIT: loop, there is a second loop that preps two file fields for further processing. Starting at the loop defined by the COUNT: label, the program populates two work variables called &COPIES1 and &FILNUM1 with variations of the same values that are contained in the number of copies field (&COPIES) and the spooled file number fields (&FILNUM) from the WRKOUTQPRT record. The reason we have to make copies of these fields is that, because they originated from a WRKOUTQ printout, these numeric fields had their leading zeroes suppressed in the original printout. In order to again use these fields as numeric values in the program, we first have to zero-fill both fields from the left. And that's what the loop designated by the COUNT: label in the program does.

At the end of the COUNT: loop, I then use two IF commands (IF) to determine whether or not the record we are processing is a data record containing information about a spooled file in the output queue or whether it is a record containing a header or a blank line from the report it was copied from. I do this by checking to see if the information in the zero-filled &COPIES1 field (number of copies to be printed of the spooled file) is a numeric. If it's numeric (a value between '00000' and '99999'), I let the record through for deletion consideration. If it's not numeric, I send the program back to the top of the GETIT: loop to retrieve the next record for processing.

The next thing you'll notice about the code is that I have added a comment designating where you would put the logic to set the delete flag on (designated by the &DELETE variable being set to 'Y'). For your purposes, you would enter whatever code or program call that would perform your date arithmetic to determine whether &DELETE should be set to 'Y'. Date arithmetic in CL is its own adventure and that code could easily take up a good part, if not all, of this article. Date arithmetic has also been covered in IT Jungle before in an excellent article, complete with code, called Date Handling in CL Procedures, written by Ted Holt. In Ted's article, you can get plenty of ideas for how to handle the date manipulation in your program. Also, Bruce Guetzkow has just done another excellent article on date handling issues in this very edition of Four Hundred Guru.

If you wanted to, you could also set the deletion criteria according to a different standard than spooled files that are over 30 days old. My program can easily be modified to delete any spooled files in an output queue that have a status of 'SAV', that have a certain form type, or that were produced by a specific user or a specific job. So you have some flexibility in how you want to delete the spooled files.

After determining if the record represents a legitimate spooled file and whether it should be deleted, the Delete Spooled File command (DLTSPLF) will delete it as long as the &DELETE variable is set to 'Y'.

After the program finishes processing all the records in the WRKOUTQPRT file, it goes to the ENDPGM: label where it performs end of programming housekeeping. This includes deleting the WRKOUTQPRT file override and deleting the QTEMP/WRKOUTQPRT file. And then the program ends.

Hopefully, this program will help you manage your spool files. It's a home-grown solution, but I think it will effectively solve your problem.

--Joe

Sponsored By
GUILD COMPANIES

Chip Wars: Intel vs AMD, IBM vs Intel

The chip wars are on, says Brian Kelly in his new book
about the processor chip business.

There are no better kept secrets in your computer than the chip and technology that makes everything go. Most people simply look for "Intel Inside" and go no further. That paradigm has been working for years, but it is fundamentally over. Today, you can find better performance and lower prices with alternative processor chips. Intel, is the dominant chip maker in the world and a household name, but there is a question about whether the giant chipmaker is still the technology leader that it claims to be. This book answers that question and it also gives you information you need to know to understand what's inside the engine of your computer and why the old maxims no longer apply.

Buy Chip Wars at the IT Jungle Online Book Store,
value priced at only $29.95.


Technical Editors: Howard Arner, Joe Hertvik, Ted Holt,
Shannon O'Donnell, Kevin Vandever
Contributing Technical Editors: Joel Cochran, Wayne O. Evans, Raymond Everhart,
Bruce Guetzkow, 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.


THIS ISSUE
SPONSORED BY:

Advanced Systems Concepts
WorksRight Software
Guild Companies


Four Hundred Guru

BACK ISSUES

TABLE OF
CONTENTS
Everything You Ever Wanted to Know About Converting Dates

Editing Numbers in CL, Take Two

Selectively Deleting OS/400 Spool Files


The Four Hundred
Domino on the iSeries: The Empire Can Strike Back

The Once and Future OS/400 Ecosystem

International Business Server, International Business Desktop

Mad Dog 21/21: Hasta La Vista, Budget

Four Hundred Stuff
QlikTech Targets iSeries Base with Business Intelligence App

Bytware Adds Disk Monitoring to MessengerPlus

Kisco Maintains Session Integrity, Security with ScreenSafer/400

Ipedo Seeks to Bridge Web Services with Business Intelligence

Four Hundred Monitor


Copyright © 1996-2008 Guild Companies, Inc. All Rights Reserved.
Guild Companies, Inc. (formerly Midrange Server), 50 Park Terrace East, Suite 8F, New York, NY 10034
Privacy Statement