CVTSPLSTMF Makes Spools Cool

Article ID: 7516

(You can download NEWS/400 code for this issue,
click here.
)
Experts are constantly assuring us that we're living at the dawn of the e-commerce age — that soon we'll all do business over the Internet in a paper-free world. But try telling that to your users the next time the AS/400 report they need each morning is late.

Although many traditional AS/400 shops are gearing up for the challenge of Internet trading, many others remain dependent on traditional AS/400 spool files and paper-based reports to keep their businesses going.

But times are changing, and many of us are looking for ways to adapt our existing systems to the Internet age without having to rewrite the lot in Java. Maybe you want to keep your trusted RPG report programs and publish their resulting spool files on the Internet or your company intranet rather than printing them. Perhaps you have local users who still want printed reports and remote users who want to receive the same information via e-mail as text or Portable Document Format (PDF) files.

If any of these scenarios apply to you, my CVTSPLSTMF (Convert Spooled File to Stream File) utility may be just what you need to get started. CVTSPLSTMF lets you convert an AS/400 spool file to a stream file stored in the AS/400 integrated file system (IFS) root file system.

The data format in the stream file can be simple ASCII text, HTML, or PDF. Using Client Access shared folders, you can open the stream file in a Windows application, such as a spreadsheet, browser, or Adobe Acrobat. You can also mail the stream file to another site or publish it on the Web, your company's intranet, or your extranet for business partners to download.

However, there are a few limitations. Currently, CVTSPLSTMF doesn't support conversion of Advanced Function Printing Data Stream (AFPDS) spool files. CVTSPLSTMF will convert the fonts or form size you use in your AS/400 spool file to an A4 (portrait or landscape) document in Courier non-proportional font. I hope to enhance the utility to handle more sophisticated AS/400 spool files, but as it stands, CVTSPLSTMF still converts most traditional AS/400 reports.

CVTSPLSTMF in Action

To begin, create the objects needed for the CVTSPLSTMF command by following the instructions in "Creating CVT SPLSTMF Objects" (page 91). When you run CVTSPL STMF, you must first identify the spool file you want to convert. On the FROMFILE parameter, type the name of the spool file to be processed. Because this name probably isn't unique on your system, you can use the JOB and SPLNBR parameters to specify more fully the spool file you want to convert.

On the JOB parameter, you indicate the job name and number and user name to identify the job that created the spool file. If the spool file was created in the current job, let the JOB parameter default to the value (*). If the spool file name you entered on the FROMFILE parameter occurs only once in the job you specified on the JOB parameter, let the SPLNBR parameter default to *ONLY. However, if more than one spool file in this job has the same name, you must specify on the SPLNBR parameter the spool file to which you're referring. To do so, enter either the number of the spool file you want to convert or the special value *LAST to indicate that you want to convert the most recent spool file with this name.

Next, you must tell CVTSPLSTMF where to place the output. On the TOSTMF (To Stream File) parameter, type a valid file name up to 64 characters long; on the TODIR (To Directory) parameter, enter the name of a directory in the IFS root file system. This directory must already exist; otherwise, the command will return an error. If the directory doesn't contain the file you specified, the file will be created.

However, if the file already resides in the directory, you must specify on the STMFOPT (Stream File Option) parameter the action for the command to take. The default *NONE indicates that the command will report an error and the existing file won't be changed. However, changing the value to *REPLACE or *ADD causes the converted data from the spool file to be overwritten (*REPLACE) or appended to (*ADD) the existing data in the file.

Now the command can translate the AS/400 EBCDIC character data in the spool file to ASCII character data in the stream file so that Windows applications (e.g., browser, Adobe Acrobat Reader) can handle the data. In the EBCDIC character set, hexadecimal '40' represents a space, hex 'F1' denotes the numeric digit 1, and hex 'C1' is an uppercase A. Windows applications, however, employ a variant of the ASCII character set, where hex '20' is a space, hex '31' is a 1, and hex '41' is an A. This situation is further complicated because both of these character sets vary, depending on your national language settings. For example, on a U.S. AS/400, hex '4A' is the dollar symbol ($), but on a UK AS/400, it's the pound sign (£).

This translation depends on several factors, including:

  • the character identifier (CHRID) attribute of the spool file specified on the FROMFILE parameter
  • the existing stream file's current CCSID value
  • the value specified on the CVTSPLSTMF command's STMFCODPAG (Stream File Code Page) parameter
  • whether the stream file specified on the TOSTMF and TODIR parameters already exists

On the STMFCODPAG parameter, you can specify the code-page value the command assigns to the stream file, which CVTSPLSTMF uses to translate the data. Typically, if you run OS/400 V4R3 or higher and you intend to view the resulting stream file in a Windows program (e.g., browser, Acrobat), you can let this value default to *PCASCII. Doing so tells CVTSPLSTMF to convert the data from AS/400 ECBDIC to the equivalent Windows ASCII characters. But systems running V4R2 or earlier don't support the default value, so you'll need to specify an appropriate code-page value. Note that an error will occur if you specify *PCASCII or a code-page value for an existing stream file with a different code page value. (For more information about *PCASCII support on V4R2 and earlier, see "Running CVTSPLSTMF on V4R2," below.)

Running CVTSPLSTMF on V4R2

OS/400 doesn't support the *PCASCII option on the CPYTOSTMF (Copy to Stream File) command's STMFCODPAG parameter before V4R3. CVTSPLSTMF (Convert to Spooled Stream File) uses the CPYTOSTMF command, so if you intend to use CVTSPLSTMF on an AS/400 running V4R2 or earlier, you must perform two additional steps once you've created your objects (see "Creating CVTSPLSTMF Objects," page 91). These steps let you tell CVTSPLSTMF how to convert your EBCDIC spool files so they will appear correctly in a Windows application.

First, you must determine the correct stream file code-page value for converting your EBCDIC data for Windows. You can find your system's default Coded Character Set Identifier (CCSID) by displaying system value QCCSID as follows:

DSPSYSVAL QCCSID

If your QCCSID system value is set to 37 (U.S.), the correct code page is 01250 (Windows — Latin 2). If it is set to 285 (UK), you need code page 01252 (Windows — Latin 1). If it's anything else, you'll need to choose the appropriate code page, depending on your language and international settings. (For more information about CCSID values, see International Application Development (SC41-5603).)

Second, you make this value the default for the CVTSPLSTMF command's STMFCODPAG parameter using the CHGCMDDFT (Change Command Default) command as follows:

CHGCMDDFT   CMD(YourObjlib/CvtSplStmf) 
            NEWDFT('STMFCODPAG        + 
                  (YourCodePage)')

where YourCodePage is the value established in the first step.

— P.C.

The final STMFCODPAG parameter option — *STMF — indicates that the existing stream file's code-page value will determine how conversion occurs. If the stream file doesn't exist, CVTSPLSTMF uses the spool file's CHRID.

Finally, we use the TOFMT (To Format) parameter to tell CVTSPLSTMF the format to which to convert the spool file data. The options are

  • TEXT (Plain ASCII text) — Each line of the spool file is represented by a single record in the text file and terminated by a carriage return or line feed pair. Blank lines in the spool file won't appear in the text file.
  • *HTML — The program formats a report in a browser to appear the same as the original spool file when printed. Wherever the spool file contains instructions to space or skip a number of lines, CVTSPLSTMF inserts the appropriate number of blank lines into the text, places horizontal lines between pages, and creates basic HTML headings.
  • *PDF (Adobe Acrobat PDF) — Users can view these documents using the free Adobe Acrobat Reader program, which you can download from many Internet sites (e.g., from Adobe's Web site at http://www.adobe .com/products/acrobat/readstep.html). Again, where possible, a report in the Acrobat Reader will appear the same as the original paper report.

The HTML and PDF Options

Selecting the *HTML or *PDF option makes available several other parameters. The TITLE parameter lets you define title text for either HTML or PDF files. If you specify TOFMT(*HTML), the text you key in the TITLE parameter will appear in your browser's title bar when you view the output from CVTSPLSTMF. If you specify TOFMT(*PDF), the text in the TITLE parameter appears in Adobe Acrobat Reader by selecting File, Document Info, and General from the menu. The default *NONE indicates that the document has no title. The remaining option — *STMFILE — gives the report the same name as that of the stream file CVTSPLSTMF creates.

The remaining parameters apply only to the TOFMT (*PDF) option. These parameters let you create bookmarks (a.k.a. outlines) in your document. Bookmarks let readers index a PDF file so they can go directly to a particular section of a document. By creating bookmarks, you make it quicker and easier for users to navigate the document that CVTSPLSTMF generates from your spool file.

CVTSPLSTMF creates bookmarks using one of three options, which you specify on the BOOKMARK parameter. All the options let you create a set of bookmarks that identify and target particular pages.

The first and simplest option is the default BOOKMARK (*PAGNBR). This option creates an outline based on the page numbers in the document. In itself, this isn't particularly useful to your users because Acrobat provides other ways to easily find a specific page. Moreover, users are unlikely to know which page includes the information they want. Although they could use Acrobat's text search facilities, you can make it simpler for users to navigate the document by using either the BOOKMARK(*POS) or BOOKMARK (*KEY) option.

By specifying BOOKMARK(*POS) with the BMARKPOS parameter, you can create a set of bookmarks based on a piece of text that appears at a particular position on each page of the report. For example, if you know that an item of user interest — such as an order number, a customer name, or a product code — appears regularly at position 3 of line 4 on every page and is up to 20 characters long, you can generate your bookmarks by specifying

CVTSPLSTMF ... BOOKMARK(*POS) BMARKPOS(4 3 20)

However, the item you want to use as the basis for your bookmarks may not predictably appear at the same position on each page. In such cases, if you can identify some key text on the same line of each page, you can still create an outline tree using the final option BOOKMARK(*KEY).

This option relies on associating a label with the text you want to use as the basis for the bookmarks. For example, you might want to use the customer name field on a report to create an index. You can't use BOOKMARK(*POS) because the customer name can appear on any line on the report. But if the name text is always preceded by the label 'Customer name:', you can create bookmarks as follows:

CVTSPLSTMF...BOOKMARK(*KEY)             + 
             BMARKKEY                 + 
              ('Customer name:' 1 16 30)

The BMARKKEY parameter consists of four elements:

  • the key text itself
  • the occurrence on the page (e.g., first occurrence, second occurrence)
  • the offset to the text to be used for the bookmark (i.e., the number of characters counting from the first character of the key to the first character of the bookmark text — this number can be negative if the label is to the right of the bookmark text)
  • the length of the bookmark text

The actual customer name text in the above code is the basis for the outline tree. Notice that the text is 30 characters long and appears 16 characters to the right of the first character of the label 'Customer name:' on each page. Let's look at some examples of how CVTSPLSTMF can spruce up your old reports.

Suppose you run a regular job on your system to display all the libraries' contents so you can monitor library sizes. You might want to mail this data to your users as an Acrobat document. To do this, you'd run your job as usual and then run the following command against the spool file created:

CVTSPLSTMF 	FROMFILE(QPDSPLIB)     + 
TOSTMF(DSPLIB.PDF)     + 
TODIR('/reports')      + 
SPLNBR(*LAST)          + 
TOFMT(*PDF)            + 
STMFOPT(*REPLACE)      + 
BOOKMARK(*POS)         + 
BMARKPOS(3 40 10)

This approach assumes that the DSPLIB (Display Library) command was run in the current job. The output from the command is directed to a stream file called DSPLIB.PDF in directory called reports. The BOOKMARK parameter retrieves the library name, which appears at position 40 on line 3 of each page and is 10 characters long.

This stream file can then be mailed and viewed in Adobe Acrobat Reader, as Figure 1 shows. The Bookmark list on the left side of the screen lets you easily select the library in which you're interested.

To publish the results on your intranet, you'd convert the spool file to HTML instead. To do this, run the following command:

CVTSPLSTMF	FROMFILE(QPDSPLIB)      + 
TOSTMF(DSPLIB.HTML)     + 
TODIR('/reports')       + 
SPLNBR(*LAST)           + 
TOFMT(*HTML)            + 
STMFOPT(*REPLACE)       + 
TITLE('Library Contents + 
  Report 22 April 2000')

As Figure 2 shows, you can view the output in Internet Explorer.

How CVTSPLSTMF Works

ILE CL program CVTSPLSTMF is the command processing program for command CVTSPLSTMF. Figure 3 shows the source for this program. The program starts by interpreting the parameters passed to it and translating them from the values passed by the command to the values the processing program needs (at A, B, and C).

Next, at D and E, CVTSPLSTMF creates the work file(s) it needs for converting the spool file data. The program uses a work file stored in library QTEMP named CVTSPLWRK1. A second work file called CVTSPLWRK2 is also used to convert data to HTML or PDF format. If we're converting data to simple text, the spool file data is placed directly into work file CVTSPLWRK1. If we're converting data to HTML or PDF formats, the data is first copied into CVTSPLWRK2 and then converted by an RPG program into CVTSPLWRK1.

CVTSPLSTMF uses the CPYSPLF (Copy Spooled File) command to extract data from the spool file. This is one limitation of the command because CPYSPLF can't handle Advanced Function Printing (AFP) data. It's also the reason that program CVTSPLSTMF needs to manipulate the system reply list (at F and G).

When processing spool files with certain attributes, CPYSPLF sends message CPA3311 ("Attributes of file &1 not supported. (G C)") to the program message queue if CPYSPLF is running interactively or to the System Operator message queue if its running in batch. CPYSPLF must receive a reply before it will continue. This is clearly inconvenient, especially if you want to run CVTSPLSTMF when your system is unattended (e.g., during your overnight or weekend batch processing).

For this reason, CVTSPLSTMF ensures that this message, if sent, will be replied to automatically. To do this, it first sets the job attribute INQMSGRPY (Inquiry Message Reply) to the value *SYSRPYL (at F). This tells OS/400 that if the job sends an inquiry message such as CPA3311, it should check the system reply list for an automatic reply to that message. The system reply list is a system table that lets you define the automatic reply to give for particular messages.

The program adds a temporary entry to the system reply list for message CPA3311 at G. It searches for the first unused system reply list entry sequence number, starting at 9999 and working back to 1, until it finds an available slot. If the reply list is modified successfully, CVTSPLSTMF removes the temporary entry before the program ends. Job attribute INQMSGRPY is also restored to its original value before the command is finished.

To convert data to HTML or PDF formats, we'll need to determine which blank lines have been omitted from the data in the work file, as extracted by CPYSPLF. We do this at H by setting up a variable to be used on the CPYSPLF command's CTLCHAR (Control Character) parameter. Selecting the *PRTCTL (Print Control) option for this parameter ensures that the data in the work file is prefixed by two control fields. These fields indicate the number of blank lines to be spaced over or the line number to which the program should skip before printing the next text line.

At I, the program sets up the title text if either special value *STMFILE or *NONE is specified for the TITLE parameter. The CPYSPLF command (at J) extracts the data from the spool file we want to convert into our work file in library QTEMP. The &ToFile variable determines the work file CPYSPLF will target. Recall that at D and E we set the &ToFile variable to either CVTSPLWRK1 or CVTSPLWRK2, depending on whether we want to convert our data to simple text.

If the output format is to be anything other than simple ASCII text (i.e., the TOFMT parameter is something other than *TEXT), we must obtain additional information about the spool file. For this, the program calls the QUSRSPLA (Retrieve Spooled File Attributes) API (at K). For HTML, we need to know only the page length, but for PDF, we need to know about other items, such as the job and program that opened the spool file and the date and time it was created.

CVTSPLSTMF then calls either RPG program CVTSPLHTML (at L) or CVTSPLPDF (at M) to convert the data held in work file CVTSPLWRK2 and write it to CVTSPLWRK1, where it will appear in HTML or Adobe Acrobat PDF format, respectively. I won't go into detail about the CVTSPLPDF program in this article. The PDF specification is a large and complex subject that I hope to cover in a future article.

Our data is now converted in work file CVTSPLWRK1 in the format we selected. All that remains is to convert it from EBCDIC data in an AS/400 database file to ASCII data in an IFS stream file. To do this, we use the CPYTOSTMF (Copy to Stream File) command. First, at N, we set up the correct value of the stream file code-page parameter. Next, we run CPYTOSTMF to create our stream file (at O).

After sending a completion message to confirm that the spool file has been processed successfully (at P), the program deletes the QTEMP work files (at Q), removes the reply list entry added earlier, and resets the job attributes (at R) before returning to the caller.

Although CVTSPLSTMF has some limitations, I believe you'll find it a useful tool to help you move your company out of the paper-report era and into the new world of electronic documents.

Peter Cliffordis a data consultancy manager at Endsleigh Insurance Services Ltd., a major U.K. Insurance company. You can reach him at Peter@Cliffords.f9.co.uk.

Creating CVTSPLSTMF Objects

Here's how to create the objects you need to use the CVTSPLSTMF (Convert Spooled File to Stream File) command. You must first download the code (see page 4 for instructions on obtaining the code). The four objects you must use are

ObjectTypeComments
CVTSPLPDF*PGMILE RPG program for PDF
CVTSPLHTML*PGMILE RPG program for HTML
CVTSPLSTMF*PGMCL command processing program
CVTSPLSTMF*CMDThe command itself

To create these objects, execute the following commands, where YourObjLib is the name of the library into which you want to create the program command, and YourSrcLib is the name of the library containing the source (use the standard source files names for ILE RPG, CL, and command sources QRPGLESRC, QCLSRC, and QCMDSRC).

  1. Create ILE RPG program CVTSPLPDF:
    CRTBNDRPG   YourObjlib/CvtSplPDF          +
                SRCFILE(YourSrcLib/qrpglesrc) +
                DFTACTGRP(*no)
  2. Create ILE RPG program CVTSPLHTML:
    CRTBNDRPG   YourObjlib/CvtSplHTML          +
                SRCFILE(YourSrcLib/qrpglesrc)  +
                DFTACTGRP(*no)
  3. Create ILE CL program CVTSPLSTMF:
    CRTBNDCL   YourObjlib/CvtSplStmf          +
               SRCFILE(YourSrcLib/qclsrc)
  4. Create command CVTSPLSTMF:
    CRTCMD   YourObjlib/CvtSplStmf          +
             PGM(CvtSplStmf)                +
             SRCFILE(YourSrcLib/qcmdsrc)

    — P.C.

ProVIP Sponsors

ProVIP Sponsors