Printing without pain: a guide to output queues

Log in to save

On IBM i no program actually prints: it produces a spooled file, which lands in a queue. Then a writer takes spooled files from the queue and sends them to the printer. Three pieces in a row — spooled file, queue, writer — and diagnosing "it will not print" means working out which of the three you got stuck on.

The two-minute diagnosis

First: does the spooled file exist?

WRKSPLF

If nothing appears, the program produced nothing: the problem is in the application, not in printing. If the spooled file is there, look at the status column:

  • RDY — ready, waiting for the writer.
  • HLD — held, it will not come out until somebody releases it.
  • SAV — already printed and kept.
  • WTR — the writer is processing it right now.

Second: which queue did it land in? The queue column often reveals the problem immediately: the spooled file is in a different queue from the one you are looking at, typically the user profile's default rather than the application's.

Third: is the writer running?

WRKWTR WTR(*ALL)

If the queue's writer does not appear, the spooled files will stay in RDY forever. Start it with:

STRPRTWTR DEV(PRINTER01) OUTQ(MYLIB/OUTQINV)

In practice, "it will not print" breaks down as: writer stopped, spooled file held, spooled file in the wrong queue. In that order of frequency.

How a spooled file decides where to go

This is the point that causes most confusion, because the levels are different and the one closest to the program wins:

  1. The printer file (*PRTF) used by the program, with the queue named when it was created.
  2. The job description (JOBD), which applies to every spooled file that job produces.
  3. The user profile, which applies when none of the others has said anything.
  4. An OVRPRTF issued before printing, which overrides everything.

When a spooled file "always goes to the wrong place", the answer is almost always level 3: the program specifies nothing, and everybody gets their own profile's queue.

To direct a print without touching the program:

OVRPRTF FILE(INVOICES) OUTQ(MYLIB/OUTQINV) HOLD(*NO)
CALL PGM(MYLIB/PRTINV)
DLTOVR FILE(INVOICES)

Do not forget the DLTOVR: an override stays active for the rest of the job, and the next print would end up there too.

Reordering spooled files in the queue

Every spooled file has a priority from 1 to 9, where 1 comes out first. An urgent print sitting behind a three-thousand-page report can be moved without stopping anything:

CHGSPLFA FILE(INVOICES) JOB(123456/USER/PRTINV)
         SPLNBR(3) OUTPTY(1)

To move a spooled file to another queue you use the same command with OUTQ.

Reserving pre-printed stationery

FORMTYPE stops a print meant for pre-printed forms coming out on plain paper:

STRPRTWTR DEV(PRINTER01) OUTQ(MYLIB/OUTQINV)
          FORMTYPE(INVOICES) MSG(*INQMSG)

With MSG(*INQMSG) the writer, on meeting a spooled file with a different form type, stops and asks the operator to change the paper instead of just printing.

From spooled file to PDF

This is the most frequent request of recent years. The main routes:

Built-in transformation. Recent releases include functions for converting spooled files to PDF, with the option of delivering them to an IFS folder or by mail. What is available depends on the version and on the products installed, so it is worth checking what is on your machine before looking for outside solutions.

Copy the spooled file into a file and process it afterwards:

CPYSPLF FILE(INVOICES) TOFILE(MYLIB/INVTEXT)
        JOB(123456/USER/PRTINV) SPLNBR(3)
        MBROPT(*REPLACE)

From there the content is plain text, readable by a program or a script.

ACS, for the one-off case: the Printer Output entry shows spooled files from the PC and lets you save them as PDF without going near the 5250. It is the quickest way when you need a single copy to email.

Queues do not empty themselves

A spooled file stays until somebody deletes it, and on many installations there are tens of thousands going back years. They take up space and slow down opening the queues themselves.

It is worth checking the situation periodically:

SELECT OUTPUT_QUEUE_LIBRARY_NAME, OUTPUT_QUEUE_NAME,
       NUMBER_OF_FILES
  FROM QSYS2.OUTPUT_QUEUE_INFO
 WHERE NUMBER_OF_FILES > 1000
 ORDER BY NUMBER_OF_FILES DESC;

Before deleting, though, ask a question that sounds obvious and is not: are those spooled files the only copy of something? In several companies the printed invoices exist only there. If that is the case, the clean-up has to be preceded by an extraction, not done instead of one.


Which versions this works on

WRKSPLF, WRKOUTQ, WRKWTR, STRPRTWTR, CHGSPLFA, CPYSPLF, OVRPRTF, DLTOVR — long-standing commands, present on every release in use.

QSYS2.OUTPUT_QUEUE_INFO — reading queue status in SQL is an IBM i Service, so it depends on the release and the database PTF group level, and it was extended on 7.4 and 7.5. There is also QSYS2.OUTPUT_QUEUE_ENTRIES, which returns one row per individual spooled file.

If those views are not on your machine, the same count can be obtained with:

WRKOUTQ OUTQ(*ALL) OUTPUT(*PRINT)

or, to get it into a queryable file, with DSPOBJD over *OUTQ objects. It is clumsier, but it works everywhere.

Converting spooled files to PDF is where releases differ most. The possibilities depend on the version and on the products installed — Transform Services is a separate product, and the built-in functions have been extended over time. Before anything integrated existed, conversion was done with third-party products or by copying the spooled file to a text file with CPYSPLF and generating the PDF off the system. It is worth checking what is already installed before looking for outside solutions: there is often more there than people expect.

Sources

← Back to blog

Comments

No comments yet. Be the first to comment!

You need an account to comment. Log in · Sign up