Print job: create 1 job with multiple pages instead of multiple jobs

Hi all, first of all I want to say this forum is superb: the people here are really willing to help you! Thank you!

I've a question about printing a report. I've created some tables, forms, functions to print pallet labels based on Sales Line records. I can select multiple layouts and send data via a self created form and the request form to the report. So far, this works splendid!

I've created a loop so I can print multiple labels. I use the value of 'quantity' for this: one label per product. To do this, I pass the value to an variable on the request form. But when I send this to the printer, the printer receives multiple individual print jobs. But because this label printer is on a machine and triggered by a specific process, this is not working when it are individual jobs... :neutral:

Does somebody know whether I can change this: I want to have 1 print job with multiple 'pages', instead of the multiple print jobs. Is this possible?
Extra info: if I set the number of prints on the request form to 1 and in the Printer dialogue for example to 10, I get one jobe with 10 pages.
Thanks in advance!
"Make it idiot-proof and someone will invent a better idiot..."

Best Answers

Answers

  • Slawek_GuzekSlawek_Guzek Member Posts: 1,690
    Each time you fire a report a new print job is created.

    What you need to do is to re-desing your report so it can print many records in one go, and instead of firing it in a loop, you'd need to filter required Sales Lines and pass filtered record to the report.

    Slawek

    Slawek Guzek
    Dynamics NAV, MS SQL Server, Wherescape RED;
    PRINCE2 Practitioner - License GR657010572SG
    GDPR Certified Data Protection Officer - PECB License DPCDPO1025070-2018-03
  • HannesHolstHannesHolst Member Posts: 119
    Hi,

    This depends how you call the Report in your code.

    For each Sales Order a single print job
    SalesHeader.SETRANGE("Document Type", SalesHeader."Document Type"::Order);
    SalesHeader.SETRANGE(Status, SalesHeader.Status::Released);
    IF SalesHeader.FINDSET THEN
      REPEAT
        SalesHeader2.SETRECFILTER(SalesHeader);
        REPORT.RUNMODAL(REPORT::"Order Confirmation", FALSE, FALSE, SalesHeader2);
      UNTIL SalesHeader.NEXT = 0;
    

    One print job for all Sales Orders
    SalesHeader.SETRANGE("Document Type", SalesHeader."Document Type"::Order);
    SalesHeader.SETRANGE(Status, SalesHeader.Status::Released);
    REPORT.RUNMODAL(REPORT::"Order Confirmation", FALSE, FALSE, SalesHeader);
    
  • danielbouwmeesterdanielbouwmeester Member Posts: 22
    edited 2017-10-31
    Thank you both, I think that the answer of Slawek is helping me in the right direction. The data which is passed to the report is coming from 1 Sales Line record: I need to print multiple labels based on the data from this record. The quantity of labels is determined by the value which is filled in on the request form.

    Slawek,
    The report consist of only one body section. I know how to influence reports with functions like Showoutput, but how do I repeat sections? How do I create a loop in which the body section is run multiple times, based on the value of the integer variable 'Quantity'. Can you help me out a little bit?
    "Make it idiot-proof and someone will invent a better idiot..."
  • danielbouwmeesterdanielbouwmeester Member Posts: 22
    Thanks again! I've changed the report. First data item is based on the Sales Line, second is the Integer: one level below, just as you said. I've put the content in the Integer's body and added some code to get the number of repetitions (the value of NoOfCopies is passed from the form to the report via the 'set-function' and 'get-function', which I created with your help. I've added a screenshot.

    When I run the report with the button on the form, the right amount of pages is created, with the right content, but the printer is still receiving multiple print jobs... :( ... Sometimes I have to print only a few labels, then this is not a problem, but most of the times it are 50, 60 or 70 labels and then the printer is stalling: it is printing faster than it is receiving jobs from the queu: the printer stops multiple times and the printing takes much longer than it should...

    Am I'm doing something wrong? Or is this just they way it is? Sorry for all the trouble :smile:


    mdvr3awnq32c.jpg
    "Make it idiot-proof and someone will invent a better idiot..."
  • danielbouwmeesterdanielbouwmeester Member Posts: 22
    Thanks again Slawek, double-checked everything and I think I working exactly like described above. So, to be sure, this morning I took another labelprinter: a much newer, more industrial version. Now it is working fine. So I will use another printer and things are solved!
    "Make it idiot-proof and someone will invent a better idiot..."
  • danielbouwmeesterdanielbouwmeester Member Posts: 22
    Only the Toshiba TEC labelprinter is printing continuous... All other brands have the same problem: the stop printer after every label :(...
    "Make it idiot-proof and someone will invent a better idiot..."
  • Slawek_GuzekSlawek_Guzek Member Posts: 1,690
    Post you code staring the report here please.

    Also try changing property NewPagePerRecord to Yes on CopyLoop DataItem and commenting CurrReport.PAGENO=1 line of code
    Slawek Guzek
    Dynamics NAV, MS SQL Server, Wherescape RED;
    PRINCE2 Practitioner - License GR657010572SG
    GDPR Certified Data Protection Officer - PECB License DPCDPO1025070-2018-03
  • danielbouwmeesterdanielbouwmeester Member Posts: 22
    Hello Slawek, the code when I push the button is quite extended, because I send quite some data to the report.

    Also, NewPagePerRecord is set to Yes already and I've the code in the OnAfterGetRecord-section of the Copyloop DataItem.
    // DB: Code OnPush
    // DB: Code for filtering the selected row in the tabular form
    lRecSalesLine.RESET;
    lRecSalesLine.SETVIEW(Rec.GETVIEW);
    lRecSalesLine.COPYFILTERS(Rec);
    lRecSalesLine.SETRANGE(lRecSalesLine."Document No.", "Document No.");
    lRecSalesLine.SETRANGE(lRecSalesLine."Line No.", "Line No.");
    lRecSalesLine.SETRANGE(lRecSalesLine."Sell-to Customer No.", "Sell-to Customer No.");
    
    //DB: recLabelLayoutJVDO is the variable of the Record type, referring to my table with 
    // different label layouts:
    CLEAR(recLabelLayoutJVDO);
    IF recLabelLayoutJVDO.GET("Label LayoutID JvdO") THEN;
    
    // DB: Several functions for sending the data to the report. I use the codeunit, 
    // because I have multiple layouts, so I only have to call the functions
    cduTransferParameters.fctSetQuantity(Quantity);
    cduTransferParameters.fctSetColliNo("Colli No.");
    cduTransferParameters.fctSetLabelInfoProdGrDescr("Item Category Code","Product Group Code");
    cduTransferParameters.fctSetLabelInfoTradeMDescr("Measure Code");
    cduTransferParameters.fctSetLabelInfoItemRaceDescr("Item Race Code");
    cduTransferParameters.fctSetLabelInfoProdClDescr("Product Class Code");
    cduTransferParameters.fctSetLabelInfoUnitOfMDescr("Unit of Measure Code");
    cduTransferParameters.fctSetLabelInfoUnitQuantity("No.","Unit of Measure Code");
    cduTransferParameters.fctSetLabelInfoCountryISO("Country of Origin Code");
    
    //Check: search for an EAN13 barcode 
    IF recLabelLayoutJVDO.EANinDesign THEN BEGIN
      itemCrossReferenceRec.RESET;
      itemCrossReferenceRec.SETRANGE(itemCrossReferenceRec."Item No.","No.");
      itemCrossReferenceRec.SETRANGE(itemCrossReferenceRec."Unit of Measure","Unit of Measure Code");
      itemCrossReferenceRec.SETRANGE(itemCrossReferenceRec."Cross-Reference Type",
         itemCrossReferenceRec."Cross-Reference Type"::"Bar Code");
      IF itemCrossReferenceRec.FINDFIRST THEN BEGIN
         cduTransferParameters.fctSetLabelBoolEANIncl(TRUE);
         cduTransferParameters.fctSetLabelInfoEAN13Complete(itemCrossReferenceRec."Cross-Reference No.");
      END ELSE
         ERROR(txtErrorNoEAN);
    
    END ELSE BEGIN
      cduTransferParameters.fctSetLabelBoolEANIncl(FALSE);
    END;
    
    //DB: Select right layout from table and run report
    IF recLabelLayoutJVDO.ReportID = 50008 THEN BEGIN
      CLEAR(report50008);
      report50008.SETTABLEVIEW(lRecSalesLine);
      report50008.USEREQUESTFORM(TRUE);
      report50008.RUNMODAL;
    END ELSE IF recLabelLayoutJVDO.ReportID = 50009 THEN BEGIN
      CLEAR(report50009);
      report50009.SETTABLEVIEW(lRecSalesLine);
      report50009.USEREQUESTFORM(TRUE);
      report50009.RUNMODAL;
    END ELSE IF recLabelLayoutJVDO.ReportID = 50010 THEN BEGIN
      CLEAR(report50010);
      report50010.SETTABLEVIEW(lRecSalesLine);
      report50010.USEREQUESTFORM(TRUE);
      report50010.RUNMODAL;
    END ELSE IF recLabelLayoutJVDO.ReportID = 50011 THEN BEGIN
      CLEAR(report50011);
      report50011.SETTABLEVIEW(lRecSalesLine);
      report50011.USEREQUESTFORM(TRUE);
      report50011.RUNMODAL;
    END ELSE IF recLabelLayoutJVDO.ReportID = 50012 THEN BEGIN
      CLEAR(report50012);
      report50012.SETTABLEVIEW(lRecSalesLine);
      report50012.USEREQUESTFORM(TRUE);
      report50012.RUNMODAL;
    END ELSE IF recLabelLayoutJVDO.ReportID = 50088 THEN BEGIN
      CLEAR(report50088);
      report50088.SETTABLEVIEW(lRecSalesLine);
      report50088.USEREQUESTFORM(TRUE);
        report50088.RUNMODAL;
    END ELSE
      ERROR(textNoLabel);
    
    "Make it idiot-proof and someone will invent a better idiot..."
  • Slawek_GuzekSlawek_Guzek Member Posts: 1,690
    Everything looks pretty straightforward.

    By the way - if you decided not to define any functions on your reports, and instead you're passing the parameters through a single instance codeunit, rather than repeating 4 times each for different report variable 4 the same lines of code (like this)
    CLEAR(report50088);
    report50088.SETTABLEVIEW(lRecSalesLine);
    report50088.USEREQUESTFORM(TRUE);
    report50088.RUNMODAL
    
    you could try the construct
    REPORT.RUNMODAL(recLabelLayoutJVDO.ReportID, TRUE, TRUE, lRecSalesLine)
    
    which, apart from shortening the code, is also a bit different method of invoking printing job. I am not particularly convinced that it would help in this case, but why not try to give it a go.

    On the top of that you can try few more things in NAV, playing a bit with the report by changing the paper size/orientation/source in report properties.

    You could also try to reset NewPagePerRecord to No on CopyLoop DataItem, and instead add in the CopyLoop one empty body section, after the one with the actual label, and in this new section you can add a line of code CurrReport.NEWPAGE.

    You could also instead of adding an extra body section to CopyLoop add another data item based on integer table, one level down below the CopyLoop, set the filters or properties on it to pick only one record, and add the CurrReport.NEWPAGE line in it, in the OnPostDataItem trigger.

    You could also try printing to a PDF file, and use shell commands invoked from NAV to print the PDF on your label printer.

    You could finally set the label printer to print to a binary file rather than directly to the printer, install a second label printer in your system, share it, and copy the binary file generated by printer 1 to the shared printer using COPY/b generatedprintoutfile.bin \\yourPC\shared printer - invoked from NAV using SHELL or Windows Scripting automation

    Slawek
    Slawek Guzek
    Dynamics NAV, MS SQL Server, Wherescape RED;
    PRINCE2 Practitioner - License GR657010572SG
    GDPR Certified Data Protection Officer - PECB License DPCDPO1025070-2018-03
Sign In or Register to comment.