New Ranks & Badges For The Community!
Notice something different? The ranks and associated badges have gone "Star Fleet". See what they all mean HERE
Highlighted
Absent Member.
Absent Member.
4664 views

Printer Redirection

Jump to solution

I'm starting the progress of migrating RM Cobol (Linux) to RM Cobol/Visual Cobol(Linux) with Eclipse (Windows)


The problem I've encountered is if the Cobol Code has the "ASSIGN TO PRINTER" clause the program in RM/VC redirects the report to a file called "LPT1", which I know is a throwback to the older Parallel printers. Normally "ASSIGN TO PRINTER" just directs the report to the file name specified before the ASSIGN clause, which we could handle via redirection in Linux. That doesn't appear to work with RM/VC. I've even tried using "ASSIGN" to a file, but the file only had 6 of the 80+ lines the report should've had. I should mention that the LPT1 is the complete report, but I really need to control where this file is created and what it is called.

Any Ideas?

0 Likes
1 Solution

Accepted Solutions
Highlighted
Micro Focus Expert
Micro Focus Expert

Oh right.  I read that you are using Linux but then forgot.

The first thing that you should realize is that you can put the file name after the PRINTER in the SELECT:

select filename-1 assign to printer data-name-1

Another thing to look at is the ASSIGN-PRINTER directive.  Here's a bit from the documentation:

This directive has no effect if you specify a filename as part of the ASSIGN TO PRINTER clause.

ASSIGN-PRINTER"filename" causes the output to be directed to the filename specified. The filename can be fully specified, including a path-name, base-name, and extension.

ASSIGN-PRINTER() results in the same behavior as including the following COBOL statement:

select filename-1 assign to printer filename-1

That is, the filename used in your COBOL program is also used as the filename for your output. If the internal filename is too long for your operating system to handle, it is truncated to the maximum length the operating system allows.

By default, the filename does not include an extension, but you can specify an extension by using the PRINT-EXT directive.

Hope this helps!

Michael Schultz
Software System Developer - Senior Principal

View solution in original post

0 Likes
9 Replies
Highlighted
Micro Focus Expert
Micro Focus Expert

There are several solutions:

1) The simple short term solution is to use a NET USE command to associate LPT1 with a network printer, such as:

net use lpt1 \\usauv-print01\usaup-rndprinter

The major problem with this solution is that it communicates directly with the printer, bypassing Windows print spooling.

2) In order to use the print spooler with VisualCOBOL, there are two, possibly three, solutions.  One requires that the standard COBOL I/O verbs be replaced with calls to a set of standard COBOL subprograms.  For example, the following sequence:

          OPEN  OUTPUT PRINTCAL.

          WRITE PRINTF-R FROM TEST-RECORD.

          CLOSE PRINTCAL.

Would be replaced with:

     *    OPEN   OUTPUT PRINTCAL.

          CALL "PC_PRINTER_OPEN" USING PRINT-HANDLE, DOCUMENT-TITLE,

              by value 4, by value 0 RETURNING STATUS-CODE.

     *    WRITE PRINTF-R FROM TEST-RECORD.

          CALL "PC_PRINTER_WRITE" USING PRINT-HANDLE, TEST-RECORD,

              by value 23 RETURNING STATUS-CODE.

     *    CLOSE       PRINTCAL.

          CALL "PC_PRINTER_CLOSE" USING PRINT-HANDLE.

The only troubling part about this solution is that the length of the record must be passed to the PC_PRINTER_WRITE routine.  We probably already know this for fixed length records, but variable length ones will be more difficult.

3) Another solution is to use the printer_redirection tunable.  To do this, we would need to create a configuration file with the following contents:

set printer_redirection=TRUE

Then an environment variable needs to be set to indicate that this configuration file is to be read at start up:

Set COBCONFIG_= C:\Dev\KenlygenTests\TestPrinter22\TestPrinter22\print.cfg

The documentation says that this will work in both native and managed code, although setting the COBCONFIG_ environment variable will not be necessary using managed code.  

4) Finally, the documentation on printer_redirection states that the COBOL callable subprogram PC_PRINTER_REDIRECTION_PROC can be used to change the printer redirection to the spooler, but I have not attempted to verify this.

Michael Schultz
Software System Developer - Senior Principal

0 Likes
Highlighted
Absent Member.
Absent Member.

We are using a 3rd Party Spooler in Linux, and use ENV variables to allow our users to choose which of 64 printers they would like their reports on ... so most of your ideas really don't fit.

I tried using the "set printer_redirection=TRUE", unfortunately the report still ended up in the file LPT1.

I just need to set it so that "ASSIGN TO PRINTER" writes to a file of my choosing, which I normally control with Linux scripts.

Thanks for the quick response!

Eric Boatman

0 Likes
Highlighted
Micro Focus Expert
Micro Focus Expert

Oh right.  I read that you are using Linux but then forgot.

The first thing that you should realize is that you can put the file name after the PRINTER in the SELECT:

select filename-1 assign to printer data-name-1

Another thing to look at is the ASSIGN-PRINTER directive.  Here's a bit from the documentation:

This directive has no effect if you specify a filename as part of the ASSIGN TO PRINTER clause.

ASSIGN-PRINTER"filename" causes the output to be directed to the filename specified. The filename can be fully specified, including a path-name, base-name, and extension.

ASSIGN-PRINTER() results in the same behavior as including the following COBOL statement:

select filename-1 assign to printer filename-1

That is, the filename used in your COBOL program is also used as the filename for your output. If the internal filename is too long for your operating system to handle, it is truncated to the maximum length the operating system allows.

By default, the filename does not include an extension, but you can specify an extension by using the PRINT-EXT directive.

Hope this helps!

Michael Schultz
Software System Developer - Senior Principal

View solution in original post

0 Likes
Highlighted
Absent Member.
Absent Member.

The assign-printer() compiler directive will cause the behavior of "assign to printer" to match RM/COBOL behavior, that is, the access name for the file will be the same as the COBOL file-name.  To map this file name with an environment variable, use the environment variable name "dd_file-name", where file-name is your COBOL file name.  For example,  if pf01 is your COBOL file name, set the environment variable name "dd_pf01" to the value of the printer file access name.

0 Likes
Highlighted
Absent Member.
Absent Member.

I forgot to mention that on Linux, the parentheses may need to be escaped (assign-printer\(\)) or replaced with quotes to resolve shell issues.

0 Likes
Highlighted
Absent Member.
Absent Member.

Another good solution for shell issues with parentheses would to be to embed the assign-printer() directive in the source program with a $SET statement.  That way, you won't forget to specify it on future compilations and completely avoid the shell interactions.

0 Likes
Highlighted
Absent Member.
Absent Member.

Thanks for all your suggestions ...

I could not get, $set assign-printer($Linux.Environment.Variable), to work.

But I did get , ASSIGN TO PRINTER"$Linux.Environment.Variable", to work.

I'm probably going to use the "ASSIGN TO PRINTER" method, just because I know we have reports that print multiple documents to multiple printers, and that will give me that degree of control.

I'm not sure what I did wrong with the compiler directive method, hopefully this thinking won't come back to haunt me later.

0 Likes
Highlighted
Absent Member.
Absent Member.

I'm not sure you understood that the text between the parentheses in "$set assign-printer()" should be empty.  That is what causes RM/COBOL-like behavior.  That is, when there's no suggested name, the COBOL file-name is implied as is normal behavior for RM/COBOL without a file-access-name (literal or data-name) after the word PRINTER.  The other part of converting to Visual COBOL is knowing that a "dd_" prefix is needs to be added to the file access name to compose the environment variable name used to map the name to a different value.

0 Likes
Highlighted
Absent Member.
Absent Member.

I tired it both ways ... leaving it empty and by trying to set it to a specific filename or environment variable. It was almost like the set command wasn't working. But I know it can work, because I use set ($set idxformat"21") to let the compiler know that I'm using RM DataFiles.

0 Likes
The opinions expressed above are the personal opinions of the authors, not of Micro Focus. By using this site, you accept the Terms of Use and Rules of Participation. Certain versions of content ("Material") accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company. As of September 1, 2017, the Material is now offered by Micro Focus, a separately owned and operated company. Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.