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));
}
}
Friday, June 20, 2014
Wednesday, June 18, 2014
Accessing a customers contact list through x++
So I working on something where I need to access a customer contacts list through x++ however I found out that the linkage between CustTable and LogisticsElectronicAddress is far and few between so I figured I would post how I was able to regenerate the contact list that is displayed on the CustTable form
The key is to go from CustTable -> DirPartyTable -> DirPartyLocation. Once you have this you need a combination of DirPartyTable and DirPartyLocation to go to LogisticsElectronicAddress
static void findEmailAckTest(Args _args)
{
CustTable custTable;
DirPartyTable dirParty;
LogisticsElectronicAddress electronicAddress;
DirPartyLocation dirPartyLoc;
//find the customer
custTable = CustTable::find("21356");
//find the party for the customer
dirParty = DirPartyTable::findRec(custTable.Party);
//find all of the contacts for the current customer
while SELECT * FROM electronicAddress
EXISTS JOIN * FROM dirPartyLoc
WHERE electronicAddress.Location == dirPartyLoc.Location && dirParty.RecId==dirPartyLoc.Party
{
info(electronicAddress.Locator);
}
}
The key is to go from CustTable -> DirPartyTable -> DirPartyLocation. Once you have this you need a combination of DirPartyTable and DirPartyLocation to go to LogisticsElectronicAddress
static void findEmailAckTest(Args _args)
{
CustTable custTable;
DirPartyTable dirParty;
LogisticsElectronicAddress electronicAddress;
DirPartyLocation dirPartyLoc;
//find the customer
custTable = CustTable::find("21356");
//find the party for the customer
dirParty = DirPartyTable::findRec(custTable.Party);
//find all of the contacts for the current customer
while SELECT * FROM electronicAddress
EXISTS JOIN * FROM dirPartyLoc
WHERE electronicAddress.Location == dirPartyLoc.Location && dirParty.RecId==dirPartyLoc.Party
{
info(electronicAddress.Locator);
}
}
Subscribe to:
Posts (Atom)