Addendum: It is easier to do a mass delete of spool files using a SQL procedure, you can read about it here.
Have you ever wanted to delete many, many spool files with just one command? You know the scenario someone decided to print every invoice that had ever been generated, and now I have several thousand spool files in an output queue. I use the WRKSPLF command to view all of the spool files in the output queue, and starting deleting them one at a time by putting a '4' next to them. As I do this I am thinking there must be a better way?
Could I just clear the output queue? No, that's not possible as there are many other spool files in the same output queue, belonging to other users, that need to be printed or retained.
Perhaps there is a way to use the Delete Spool File command, DLTSPLF. I have used it before to delete spool files I have used in other programs, for example when I was copying multiple spool files into one:
DLTSPLF FILE(QSYSPRT) JOB(999999/user/job_name) SPLNBR(*LAST) |
But I can only delete one spool file at a time. I could create a CL program with this command within a DO loop, but that will still take some time as it is still just deleting the spool files one at a time, it will still be a lot faster me putting '4' next to all the spool file entries.
The DLTSPLF command does come to my rescue here. When I prompt the command there is a section to do with "Select files".
Delete Spooled File (DLTSPLF) Type choices, press Enter. Spooled file . . . . . . . FILE Job name . . . . . . . . . JOB * User . . . . . . . . . . Number . . . . . . . . . Spooled file number . . . SPLNBR *ONLY Job system name . . . . . JOBSYSNAME *ONLY Spooled file created: Creation date . . . . . *ONLY Creation time . . . . . Select files for: SELECT User . . . . . . . . . . *CURRENT Print device . . . . . . *ALL Form type . . . . . . . *ALL User data . . . . . . . *ALL ASP . . . . . . . . . . *ALL ASP device . . . . . . . . ASPDEV * |
I can use the command's parameters in the "Select files" to select and delete spool files. Yes more than one at a time. If I put "*SELECT" in the Spooled file parameter I can then use the "Select files" parameters.
In this scenario the thousands of invoices were generated by user JOHNQ, and they all have the user data of "INVOICE".
This is where I need to be a bit careful if I just enter:
DLTSPLF FILE(*SELECT) SELECT(JOHNQ *ALL *ALL) |
And press the Enter key all of JOHNQ's spool files will be deleted.
As I only want to delete spool files that have "INVOICE" in the user data I need to put that in the User data parameter.
DLTSPLF FILE(*SELECT) SELECT(JOHNQ *ALL *ALL INVOICE) |
Warning: This will delete all of JOHNQ's spool files that have user data of "INVOICE" regardless of which job created them. In other words if he generated invoices earlier today and he has not printed them they will also be deleted. The way to stop this is to change the user data of the spool files I do not want to delete.
Work with All Spooled Files Device or Opt File User Queue User Data 2 QSYSPRT JOHNQ QPRINT INVOICE 2 QSYSPRT JOHNQ QPRINT INVOICE _ REMIT10 JOHNQ QPRINT REMITANCE Parameters for options 1, 2, 3 or command ===> usrdta(INVOICE1) |
Now I am ready to delete those several thousand spool files JOHNQ generated:
DLTSPLF FILE(*SELECT) SELECT(JOHNQ *ALL *ALL INVOICE) |
Hey presto all of those spool files are deleted!
I am all for making these kinds of things easy for myself and others. To make this easy for myself and others to use, and remember, I made the following CL program:
01 PGM 02 DLTSPLF ?*FILE(*SELECT) ??SELECT() 03 MONMSG MSGID(CPF6801) 04 ENDPGM |
As you can see this program is very simple, with only two lines of interesting code.
Line 2: I am using selective prompting on the command. This means that only certain parameters will be displayed and only some of those will allow input.
Line 3: This line is to handle F3 or F12 being pressed.
I compile the program, and add a call to it on the Operators menu. Now when they take this option they see:
Delete Spooled File (DLTSPLF) Type choices, press Enter. Spooled file . . . . . . . FILE > *SELECT Select files for: SELECT User . . . . . . . . . . > *CURRENT Print device . . . . . . > *ALL Form type . . . . . . . > *ALL User data . . . . . . . > *ALL ASP . . . . . . . . . . > *ALL |
The FILE keyword is displayed, but does not allow input.
Only the SELECT keywords allow input.
All other keywords for the command are not displayed.
This makes it a lot easier for everyone to remember which parameters need to be entered to do a mass delete of spool files.
You can learn more about the DLTSPLF command from the IBM website here.
This article was written for IBM i 7.4, and should work for some earlier releases too.
Dude. I’m so dumb I just spend the last hour answering 4 to a spool file repository that hasn’t been touched since feb of 2019... THANK YOU FOR THIS
ReplyDeleteIf you are doing something like what you have described, and I have on many occasions, you might want to have a look at this blog post: Ooutput queue entries information via SQL
DeleteList all of the old spool files into a work table. Manually review the contents of the table and delete from it any spool files you want to keep. Then write a program to read the work table and DLTSPLF.
Once had a customer job runaway leave 1,000,004 spooled files in QPRINT. Now you would suggest: "CLROUTQ QPRINT" would you not? Or the command referenced in the tweet. BUT The poor customer had SAN storage configured with ONE disk LUN to IBM i. 1 hour deleted only 14,000!
ReplyDeleteThis is cool. One of the things that always annoyed me with amassed spoolfiles.
ReplyDeleteWhen I was a newbie about 2-ish years ago, I'd do the whole filling the entire subfile with 4's and then copy paste all them in ACS for each page. That was hella annoying. Sometime last year, I found
DLTSPLF FILE(*SELECT) SELECT(USERNAME)
and I was so happy.
As I mentioned about by using just the user name you delete all of the user's spool files. That might not be what you want, so check what I have said above.
DeleteSimon, this is Very useful . Thanks for sharing
ReplyDeleteWas doing this today actually. DLTSPLF with *SELECT saved me lotta time. So less tedious too.
ReplyDeleteThank you for this article. I had a mass amount of spoolfiles create out of an out of control job resubmitted itself. 32566 spool files to name just a few...I got tired of copying and pasting when with everyone knows the AS400 use PF4 to find out more that you need..the perfect command dltsplf...OMG 30 years on this system...LOL 4 was not what I needed. Mass 4 is what I needed.
ReplyDeletePlaying with the command with several attempts/fails...I said google....and found this article. the simple command with 2 parm changes. Whalah!!! :)
Clean spoolfile again. Thank you for this article.
DLTSPLF FILE(*SELECT) SELECT(????? *ALL *ALL ?????) ????? was all I changed and it worked. First ????? my spoolfile name and second ????? was the user data. Thank you so much!!!!
Thanks for posting
ReplyDeleteHave been using this since 1989 to remove all job-logs
ReplyDeleteVery helpful. I will definitely add this to my "How to..." list.
ReplyDeleteI appreciate it. Thank you so much for that.
ReplyDeleteGreat article, Thank you.
ReplyDelete