Friday, June 20, 2014

Save Sales Confirmation Report To PDF w/o any alerts via X++/Code

Update: the controller seems to operate better when using ssrsController.runReport() vs ssrsController.startOperation(). It seems as though if we use runReport then the code afterwards will wait to execute  while startOperation doesn't seem to care if the file has been created to move on.

After researching how to run an SSRS report and save it to a PDF via code I found that a lot of them were incomplete and did not always work or required some odd parms or would display the report to the user even though you told it to create a file. Once I was able to get that working default AX will always alert the user of where the file was created. This doesn't make much since if you are executing this through x++ as you will usually need to do something with the file.

The following example will show you how to run a report for the latest sales confirmation and save it to a file without alerting the user.

static void SavePDFJob(Args _args)
{
    SrsReportRunController          ssrsController = new SrsReportRunController();
    SalesConfirmContract salesConfirmContract = new SalesConfirmContract();
    SRSPrintDestinationSettings     printerSettings;
    custConfirmJour     custInvoiceJour;
   
    //select the latest record based on create date
    select firstOnly custInvoiceJour
    order by custInvoiceJour.createdDateTime DESC
    where custInvoiceJour.salesid == '1000768';

    //tell the controller the report to run (filename, design name)
    ssrsController.parmReportName(ssrsReportStr(SalesConfirm, Report));
    //define how we want to execute the report (right now or batch style)
    ssrsController.parmExecutionMode(SysOperationExecutionMode::Synchronous);
    //hide the report dialog
    ssrsController.parmShowDialog(false);

    //we need to populate the required parms for the current sales order controller
    salesConfirmContract.parmRecordId(custInvoiceJour.RecId);
   
    //link the contract to the controller so we know how to run the dp
    ssrsController.parmReportContract().parmRdpContract(salesConfirmContract);

    //link the printer settings to the controller
    printerSettings = ssrsController.parmReportContract().parmPrintSettings();
    //print to pdf and always overwrite if the file exists
    printerSettings.printMediumType(SRSPrintMediumType::File);
    printerSettings.fileFormat(SRSReportFileFormat::PDF);
    printerSettings.overwriteFile(true);
    printerSettings.fileName(@"\\network\location\test.pdf");

    //run & save the report
    //ssrsController.startOperation();
    ssrsController.runReport() //refer to update at top of page
}




Optional:


The above job will create the file however you will notice you will get an info() message that says "The report has been successfully saved as: \\network\location\test.pdf"

In order to not show this to the user you will need to modify \Classes\SrsReportRunPrinter\toFile()
toward the bottom within the for loop you will see

filename = files.value(i);
info(strFmt("@SYS134644", filename));

You will need to comment out the info so the for loop will look like the following
for (i = 1 ; i <= files.lastIndex() ; i++)
        {
            // Display success in the infolog for the file(s) created
            filename = files.value(i);
            //commenting this out so we can call this function thru code without showing the user a msg
            //info(strFmt("@SYS134644", filename));
         
          // if print mgmt, then we need to copy over the file to the original file.
            // This will ensure a file specified in print mgmt settings is always there on disk. This was the shipped behavior and might keep external systems happy.
            if(printMgmtExecutionInfo)
            {
                // for reports saved in image format, each page is a image and the files are numbered. E.g. foo.gif, foo1.gif, foo2.gif
                // so we will preserve that during copying to the original location.
                fileNameToCopy = (i == 1) ? printMgmtExecutionInfo.parmOriginalDestinationFileName() : printMgmtExecutionInfo.parmOriginalDestinationFileName() + int2str(i-1);
                System.IO.File::Copy(filename, fileNameToCopy, true);
                info(strFmt("@SYS134644", filenameToCopy));
            }
        }


No comments:

Post a Comment