Selecting Printer Trays

stokefc22

Member
Hi All,

We have a report that outputs data to a PDF and happily saves it away. Now we have a new printer that has multiple trays and I'm looking to control which trays are called upon for different color copies etc.

Does anyone have any experience of this? We currently use os-command or shellexecute to print documents but I can't see anyway of getting this level of control using these methods..
 
Hi All,

We have a report that outputs data to a PDF and happily saves it away. Now we have a new printer that has multiple trays and I'm looking to control which trays are called upon for different color copies etc.

Does anyone have any experience of this? We currently use os-command or shellexecute to print documents but I can't see anyway of getting this level of control using these methods..
 
Last edited:

stokefc22

Member

Hi Tom,

Sorry I'm not sure what you mean by "What is the emulations does the printer allow?". The printer is a HP laserjet p3015.

To get around this I've added the printer 3 times, given each one a different share name and changed the settings to force each one to select a different tray then I print a copy to each 'printer'.
 

Cecil

19+ years progress programming and still learning.
Historically for HP/Brother printers I've used PJL (Printer Job Language) to print PDF files to a RAW socket (9100) on the printer it self.

Example:
Code:
<ESC>%-12345X@PJL<CR><LF>
@PJL SET STAPLE=LEFTTOP<CR><LF>
@PJL    [... more PJL commands if required ...]
@PJL SET MEDIASOURCE=TRAY2<CR><LF>
@PJL ENTER LANGUAGE = PDF<CR><LF>
[... all bytes of the PDF file, starting with '%PDF-1.' ...]
[... all bytes of the PDF file ............................]
[... all bytes of the PDF file ............................]
[... all bytes of the PDF file, ending with '%%EOF' .......]
<ESC>%-12345X

Checkout my fun hack of a HP printer using PJL
http://www.progresstalk.com/threads/fun-hp-printer-hack-using-hp-pjl-control-codes.134614/
 

Cecil

19+ years progress programming and still learning.
Digging around today I found this code. I don't think is was fully implemented. Feel free to improve it. It works by using ABL sockets to send the print job directly to the Printer's RAW port (9100) thus, by passing Windows Printer Drivers and Linux CUPS.

Code:
define input parameter printerHost     AS CHARACTER NO-UNDO.
define input parameter printJobName    AS CHARACTER NO-UNDO.
define input parameter PDFDocument     AS CHARACTER NO-UNDO.
define input parameter paperType       AS CHARACTER NO-UNDO.
define input parameter paperTray       AS CHARACTER NO-UNDO.
define input parameter duplexPrint     AS Logical   NO-UNDO.
define input parameter printRenderMode AS CHARACTER NO-UNDO.
define input parameter printResolution AS INTEGER   NO-UNDO.

DEFINE VARIABLE clientSocketHandle         AS HANDLE NO-UNDO.
DEFINE VARIABLE printerPort                AS INTEGER     NO-UNDO Initial 9100.
DEFINE VARIABLE PJLData                  AS Longchar    NO-UNDO.

/* Validate the the file exists */
/** Note: Should valid the file to make sure it's actual PDF **/
IF SEARCH(PDFDocument) EQ ? THEN
    RETURN ERROR SUBSTITUTE('PDF Document not found &1', PDFDocument).

FUNCTION SendPJLtoPrinter RETURNS LOGICAL (INPUT command AS CHARACTER):

    DEFINE VARIABLE sockectData AS MEMPTR NO-UNDO.
    DEFINE VARIABLE dataLength  AS INTEGER   NO-UNDO.
    dataLength = Length(command,'RAW').
   
    SET-SIZE(sockectData)       = 0.
    SET-SIZE(sockectData)       = dataLength.
    SET-BYTE-ORDER(sockectData) = BIG-ENDIAN.
    PUT-STRING(sockectData,1, dataLength) = command.
    clientSocketHandle:WRITE(sockectData,1,dataLength) NO-ERROR.
    SET-SIZE(sockectData) = 0.
    RETURN TRUE.

END FUNCTION.

FUNCTION SendPDFtoPrinter RETURNS LOGICAL (INPUT sockectData AS memptr):
   
    DEFINE VARIABLE dataLength AS INTEGER NO-UNDO.
    SET-BYTE-ORDER(sockectData) = BIG-ENDIAN.
    dataLength                  = get-size(sockectData).
    clientSocketHandle:WRITE(sockectData,1,dataLength) NO-ERROR.
   
    SET-SIZE(sockectData) = 0.
    RETURN TRUE.
   
END FUNCTION.                                                   

PROCEDURE PrintPJLData:

    DEFINE VARIABLE PDFBLOB AS MEMPTR      NO-UNDO.
       
    /** Start of Print Job **/       
    SendPJLToPrinter('~033%-12345X@PJL~r~n':U).
   
    /** JOB Name and Display  **/
    /** Display a job message on the control panel display.. **/
    SendPJLToPrinter( SUBSTITUTE('@PJL JOB="&1" DISPLAY="&1"~r~n':U, printJobName) ).
   
    /** Paper Type **/                       
    IF LOGICAL(LOOKUP(paperType,'A4,A3,Letter,Executive,Legal,Folio')) THEN
        SendPJLToPrinter( SUBSTITUTE('@PJL SET PAPER=&1~r~n':U, paperTray) ).
   
    /** Printer Tray **/                                                                                                                                           
    IF LOGICAL(LOOKUP(paperTray,'TRAY1,TRAY2,TRAY3,TRAY4,TRAY5')) THEN
        SendPJLToPrinter( SUBSTITUTE('@PJL SET MEDIASOURCE="&1"~r~n':U, paperTray) ).
       
    /** Print Resolution **/                                                                   
    IF printResolution EQ 300 OR printResolution EQ 600 THEN
        SendPJLToPrinter( SUBSTITUTE('@PJL SET RESOLUTION=&1~r~n':U, printResolution) ).
       
    /** Duplex Print Job **/                                           
    IF duplexPrint THEN
        SendPJLToPrinter( '@PJL SET DUPLEX=ON~r~n':U ).
                                       
    /** Set the document TYPE TO PDF **/
    SendPJLToPrinter( '@PJL ENTER LANGUAGE=PDF~r~n':U ).
   
    /** Send print PDF to the printer.**/
    /** Note this could be better handled. **/
    SET-SIZE(PDFBLOB) = 0.
    COPY-LOB FROM FILE PDFDocument TO OBJECT PDFBLOB.
    SendPDFToPrinter(INPUT PDFBLOB).
    SET-SIZE(PDFBLOB) = 0.
   
    /** END OF PRINT JOB **/
    SendPJLToPrinter('~033%-12345X':U).
   
END.

/** Overide the default port number if specified.. **/
IF Num-Entries(printerHost,':') EQ 2 THEN
DO:
    ASSIGN
        printerPort = INTEGER(ENTRY(2,printerHost,':'))
        printerHost = ENTRY(1,printerHost,':')
        NO-ERROR.
   
    /** If error default back to the default portnumber**/                                   
    if error-status:error then
        printerPort = 9100. 
END.

IF printJobName EQ '' THEN
DO:

    CASE TRUE:
        WHEN r-index(PDFDocument,'/') GT 0 THEN
            printJobName = SUBSTRING(PDFDocument, r-index(PDFDocument,'/') ).       
        WHEN r-index(PDFDocument,'\') GT 0 THEN
            printJobName = SUBSTRING(PDFDocument, r-index(PDFDocument,'\') ).       
        OTHERWISE           
            printJobName = PDFDocument.
    END CASE.           
END.
   
/**    
Main Block   
**/
   
CREATE SOCKET clientSocketHandle.
clientSocketHandle:CONNECT(SUBSTITUTE('-H &1 -S &2':U,printerHost, printerPort)) NO-ERROR.

IF NOT clientSocketHandle:CONNECTED() THEN
    RETURN ERROR 'Unable to Connect'.
ELSE 
DO:

    RUN PrintPJLData.      

    REPEAT ON STOP UNDO, LEAVE ON QUIT UNDO, LEAVE:
        IF clientSocketHandle:connected() THEN
            WAIT-FOR READ-RESPONSE OF clientSocketHandle PAUSE 5.
        ELSE
            LEAVE.
    END.
    /*--------------------------------------------------------*/
    /* At this point, you have exited the repeat block above, */
    /* so you disconnect the socket, clean up the socket */
    /* handle, release any memory allocations and then exit */
    /* the program */
    /*--------------------------------------------------------*/
    clientSocketHandle:DISCONNECT() NO-ERROR.
    
    DELETE OBJECT clientSocketHandle.
   

END.
 

stokefc22

Member
Digging around today I found this code. I don't think is was fully implemented. Feel free to improve it. It works by using ABL sockets to send the print job directly to the Printer's RAW port (9100) thus, by passing Windows Printer Drivers and Linux CUPS.

Code:
define input parameter printerHost     AS CHARACTER NO-UNDO.
define input parameter printJobName    AS CHARACTER NO-UNDO.
define input parameter PDFDocument     AS CHARACTER NO-UNDO.
define input parameter paperType       AS CHARACTER NO-UNDO.
define input parameter paperTray       AS CHARACTER NO-UNDO.
define input parameter duplexPrint     AS Logical   NO-UNDO.
define input parameter printRenderMode AS CHARACTER NO-UNDO.
define input parameter printResolution AS INTEGER   NO-UNDO.

DEFINE VARIABLE clientSocketHandle         AS HANDLE NO-UNDO.
DEFINE VARIABLE printerPort                AS INTEGER     NO-UNDO Initial 9100.
DEFINE VARIABLE PJLData                  AS Longchar    NO-UNDO.

/* Validate the the file exists */
/** Note: Should valid the file to make sure it's actual PDF **/
IF SEARCH(PDFDocument) EQ ? THEN
    RETURN ERROR SUBSTITUTE('PDF Document not found &1', PDFDocument).

FUNCTION SendPJLtoPrinter RETURNS LOGICAL (INPUT command AS CHARACTER):

    DEFINE VARIABLE sockectData AS MEMPTR NO-UNDO.
    DEFINE VARIABLE dataLength  AS INTEGER   NO-UNDO.
    dataLength = Length(command,'RAW').
  
    SET-SIZE(sockectData)       = 0.
    SET-SIZE(sockectData)       = dataLength.
    SET-BYTE-ORDER(sockectData) = BIG-ENDIAN.
    PUT-STRING(sockectData,1, dataLength) = command.
    clientSocketHandle:WRITE(sockectData,1,dataLength) NO-ERROR.
    SET-SIZE(sockectData) = 0.
    RETURN TRUE.

END FUNCTION.

FUNCTION SendPDFtoPrinter RETURNS LOGICAL (INPUT sockectData AS memptr):
  
    DEFINE VARIABLE dataLength AS INTEGER NO-UNDO.
    SET-BYTE-ORDER(sockectData) = BIG-ENDIAN.
    dataLength                  = get-size(sockectData).
    clientSocketHandle:WRITE(sockectData,1,dataLength) NO-ERROR.
  
    SET-SIZE(sockectData) = 0.
    RETURN TRUE.
  
END FUNCTION.                                                  

PROCEDURE PrintPJLData:

    DEFINE VARIABLE PDFBLOB AS MEMPTR      NO-UNDO.
      
    /** Start of Print Job **/      
    SendPJLToPrinter('~033%-12345X@PJL~r~n':U).
  
    /** JOB Name and Display  **/
    /** Display a job message on the control panel display.. **/
    SendPJLToPrinter( SUBSTITUTE('@PJL JOB="&1" DISPLAY="&1"~r~n':U, printJobName) ).
  
    /** Paper Type **/                      
    IF LOGICAL(LOOKUP(paperType,'A4,A3,Letter,Executive,Legal,Folio')) THEN
        SendPJLToPrinter( SUBSTITUTE('@PJL SET PAPER=&1~r~n':U, paperTray) ).
  
    /** Printer Tray **/                                                                                                                                          
    IF LOGICAL(LOOKUP(paperTray,'TRAY1,TRAY2,TRAY3,TRAY4,TRAY5')) THEN
        SendPJLToPrinter( SUBSTITUTE('@PJL SET MEDIASOURCE="&1"~r~n':U, paperTray) ).
      
    /** Print Resolution **/                                                                  
    IF printResolution EQ 300 OR printResolution EQ 600 THEN
        SendPJLToPrinter( SUBSTITUTE('@PJL SET RESOLUTION=&1~r~n':U, printResolution) ).
      
    /** Duplex Print Job **/                                          
    IF duplexPrint THEN
        SendPJLToPrinter( '@PJL SET DUPLEX=ON~r~n':U ).
                                      
    /** Set the document TYPE TO PDF **/
    SendPJLToPrinter( '@PJL ENTER LANGUAGE=PDF~r~n':U ).
  
    /** Send print PDF to the printer.**/
    /** Note this could be better handled. **/
    SET-SIZE(PDFBLOB) = 0.
    COPY-LOB FROM FILE PDFDocument TO OBJECT PDFBLOB.
    SendPDFToPrinter(INPUT PDFBLOB).
    SET-SIZE(PDFBLOB) = 0.
  
    /** END OF PRINT JOB **/
    SendPJLToPrinter('~033%-12345X':U).
  
END.

/** Overide the default port number if specified.. **/
IF Num-Entries(printerHost,':') EQ 2 THEN
DO:
    ASSIGN
        printerPort = INTEGER(ENTRY(2,printerHost,':'))
        printerHost = ENTRY(1,printerHost,':')
        NO-ERROR.
  
    /** If error default back to the default portnumber**/                                  
    if error-status:error then
        printerPort = 9100.
END.

IF printJobName EQ '' THEN
DO:

    CASE TRUE:
        WHEN r-index(PDFDocument,'/') GT 0 THEN
            printJobName = SUBSTRING(PDFDocument, r-index(PDFDocument,'/') ).      
        WHEN r-index(PDFDocument,'\') GT 0 THEN
            printJobName = SUBSTRING(PDFDocument, r-index(PDFDocument,'\') ).      
        OTHERWISE          
            printJobName = PDFDocument.
    END CASE.          
END.
  
/**   
Main Block  
**/
  
CREATE SOCKET clientSocketHandle.
clientSocketHandle:CONNECT(SUBSTITUTE('-H &1 -S &2':U,printerHost, printerPort)) NO-ERROR.

IF NOT clientSocketHandle:CONNECTED() THEN
    RETURN ERROR 'Unable to Connect'.
ELSE
DO:

    RUN PrintPJLData.     

    REPEAT ON STOP UNDO, LEAVE ON QUIT UNDO, LEAVE:
        IF clientSocketHandle:connected() THEN
            WAIT-FOR READ-RESPONSE OF clientSocketHandle PAUSE 5.
        ELSE
            LEAVE.
    END.
    /*--------------------------------------------------------*/
    /* At this point, you have exited the repeat block above, */
    /* so you disconnect the socket, clean up the socket */
    /* handle, release any memory allocations and then exit */
    /* the program */
    /*--------------------------------------------------------*/
    clientSocketHandle:DISCONNECT() NO-ERROR.
   
    DELETE OBJECT clientSocketHandle.
  

END.
Once again, thanks Cecil. This should enable me to at least make a start.
 
Top