Dynamics AX Blog - report - Microsoft Dynamics AX (Axapta)

In den letzten Jahren, in denen ich mich fast hauptsächlich mit der Entwicklung im Umfeld von Microsoft Dynamics AX (vormals Axapta) beschäftigt habe, ist das eine oder andere Code-Fragment entstanden, von dem ich mir vorstellen könnte, daß es auch für andere AX-Entwickler ganz nützlich sein könnte. Aber auch Tips und Tricks zu dem mächtigen ERP-System werde ich in dieser Kategorie präsentieren.
RSS-Feed dieser KategorieDesigns eines SSRS-Berichtes auslesenWer einmal die Notwendigkeit hat, die verfügbaren Designs eines SSRS-Reports auslesen zu müssen, dem kann der nachstehende Job als Beispiel dienen. static void listDesignsOfSSRSReport(Args _args) { TreeNode treeNode; TreeNode treeNodeDesign; #aot treeNode = TreeNode::findNode(#SSRSReportsPath + #AOTRootPath); treeNode = treeNode.AOTfindChild("SalesPackingSlip"); treeNodeDesign = treeNode.AOTfindChild("Designs"); treeNodeDesign = treeNodeDesign.AOTfirstChild(); while(treeNodeDesign) { info(treeNodeDesign.AOTname()); treeNodeDesign = treeNodeDesign.AOTnextSibling(); } } |
Debuggen von SSRS-DataproviderBei der Entwicklung bzw. Anpassung von Dataprovidern eines SSRS-Reports hatte ich in der Vergangenheit immer wieder das Thema, daß das Aufrufen/Testen des SSRS-Reports oft mehr Zeit beansprucht, als die eigentliche Anpassung im Code. Deshalb ist folgender Job entstanden, der mir lediglich den Inhalt der vom Dataprovider erstellten (temporären) Tabelle als einfaches Infolog ausgibt. Das ist vor allem dann hilfreich, wenn man den Dataprovider (abgeleitet von SRSReportDataProviderBase) zur Fehleranalyse debuggen möchte, das aber aufgrund seiner Programmierung aber vielleicht nicht so ohne weiteres möglich ist. Im Beispiel handelt es sich um den Bericht "Arbeitsbeschreibung" aus dem Service-Modul. static void testSSRSDatProvider(Args _args) { SMAWorkNoteTmp tempTable; SMAWorkNoteDP dataProvider = new SMAWorkNoteDP(); SMAWorkNoteContract contract = new SMAWorkNoteContract(); Query query = new Query(identifierStr(SMAWorkNote)); try { SysQuery::findOrCreateRange( query.dataSourceTable( tableNum(SMAServiceOrderTable)), fieldNum(SMAServiceOrderTable, ServiceOrderId)).value("00018"); contract.parmItemConsumption(true); contract.parmItemRequirement(true); contract.parmExpense(true); contract.parmFee(true); contract.parmAdditionalNotes(true); contract.parmLineText(true); if( !contract.validate()) { throw error(error::missingParameter(contract)); } dataProvider.parmDataContract(contract); dataProvider.parmQuery(query); dataProvider.processReport(); tempTable = dataProvider.getSMAWorkNoteTmp(); while select tempTable { info(tempTable.otServiceOrderId); } } catch (Exception::Break) { info("Aborted"); } } |
Lieferschein per Code druckenDer nachstehende Job demonstriert, wie man in Dynamics AX 2012 einen vorhandenen (Ausgangs-)Lieferschein per Code (nach-)drucken kann. Im Beispiel erfolgt die Ausgabe am Bildschirm. static void printSalesPackingSlipThroughCode(Args _args) { SalesPackingSlipJournalPrint salesPackingSlipJournalPrint; Set set = new Set(Types::Record); SRSPrintDestinationSettings srsPrintDestinationSettings; // Add record set.add(CustPackingSlipJour::findRecId(5637161120)); // Set printer settings srsPrintDestinationSettings = new SRSPrintDestinationSettings(); srsPrintDestinationSettings.fileFormat(SRSReportFileFormat::Screen); // Initalize salesPackingSlipJournalPrint = SalesPackingSlipJournalPrint::construct(); salesPackingSlipJournalPrint.parmPrintFormletter(NoYes::Yes); salesPackingSlipJournalPrint.parmUsePrintManagement(false); salesPackingSlipJournalPrint.parmPrinterSettingsFormLetter(srsPrintDestinationSettings.pack()); // Print salesPackingSlipJournalPrint.printJournal(set); } Ändert man die Parameter der SRSPrintDestinationSettings kann man den Bericht natürlich auch an einen Drucker senden, eine Datei erstellen oder den Bericht per Mail versenden. static void printSalesPackingSlipThroughCode(Args _args) { SalesPackingSlipJournalPrint salesPackingSlipJournalPrint; Set set = new Set(Types::Record); SRSPrintDestinationSettings srsPrintDestinationSettings; // Add record set.add(CustPackingSlipJour::findRecId(5637161120)); // Set printer settings srsPrintDestinationSettings = new SRSPrintDestinationSettings(); srsPrintDestinationSettings.fileFormat(SRSReportFileFormat::PDF); srsPrintDestinationSettings.fileName(@'c:\temp\packingslip.pdf'); srsPrintDestinationSettings.printMediumType(SRSPrintMediumType::File); srsPrintDestinationSettings.numberOfCopies(1); srsPrintDestinationSettings.overwriteFile(true); // Initalize salesPackingSlipJournalPrint = SalesPackingSlipJournalPrint::construct(); salesPackingSlipJournalPrint.parmPrintFormletter(NoYes::Yes); salesPackingSlipJournalPrint.parmUsePrintManagement(false); salesPackingSlipJournalPrint.parmPrinterSettingsFormLetter(srsPrintDestinationSettings.pack()); // Print salesPackingSlipJournalPrint.printJournal(set); } Weiters kann man auf diese Art & Weise auch mehrere Lieferscheine auf einmal drucken, dazu muss man lediglich die entsprechenden CustPackingSlipJour-Datensätze dem Set "set" hinzufügen: ... // Add record set.add(CustPackingSlipJour::findRecId(5637155842)); set.add(CustPackingSlipJour::findRecId(5637145354)); ... Wer den Lieferschein zusätzlich noch im Druckarchiv speichern möchte, kann dies durch folgende Zeile erreichen: ... srsPrintDestinationSettings.parmPrintToArchive(true); ... |
Rechnung per Code druckenDer nachstehende Job demonstriert, wie man in Dynamics AX 2012 eine vorhandene Rechnung/Ausgangsrechnung per Code (nach-)drucken kann. Im Beispiel erfolgt die Ausgabe am Bildschirm. static void printSalesInvoiceThroughCode(Args _args)
{ SalesInvoiceJournalPrint salesInvoiceJournalPrint; Set set = new Set(Types::Record); SRSPrintDestinationSettings srsPrintDestinationSettings; // Add record set.add(CustInvoiceJour::findRecId(5637188088)); // Set printer settings srsPrintDestinationSettings = new SRSPrintDestinationSettings(); srsPrintDestinationSettings.fileFormat(SRSReportFileFormat::Screen); // Initalize salesInvoiceJournalPrint = SalesInvoiceJournalPrint::construct(); salesInvoiceJournalPrint.parmPrintFormletter(NoYes::Yes); salesInvoiceJournalPrint.parmUsePrintManagement(false); salesInvoiceJournalPrint.parmPrinterSettingsFormLetter(srsPrintDestinationSettings.pack()); salesInvoiceJournalPrint.printJournal(set); } |
AX 2012: Dokument per Code druckenMit dem folgenden Job kann man per Code eine Auftragsbestätigung nachdrucken und diese dabei als PDF-Datei ausgeben lassen. Mit Hilfe von ähnlich benannten Klassen wie der hier verwendeten SalesConfirmJournalPrint sollten auch andere Dokumente wie Rechnung oder Lieferschein nachdruckbar sein. static void printSalesConfirmThroughCode(Args _args) { SalesConfirmJournalPrint SalesConfirmJournalPrint; set set = new set(Types::Record); SRSPrintDestinationSettings SRSPrintDestinationSettings; // Add record set.add(CustConfirmJour::findRecId(5637150827)); // Set printer settings SRSPrintDestinationSettings = new SRSPrintDestinationSettings(); SRSPrintDestinationSettings.fileFormat( SRSReportFileFormat::PDF); SRSPrintDestinationSettings.fileName(@'c:\ab.pdf'); SRSPrintDestinationSettings.printMediumType( SRSPrintMediumType::File); SRSPrintDestinationSettings.numberOfCopies(1); SRSPrintDestinationSettings.overwriteFile(true); // Initalize SalesConfirmJournalPrint = SalesConfirmJournalPrint::construct(); SalesConfirmJournalPrint.parmPrintFormletter(NoYes::Yes); SalesConfirmJournalPrint.parmUsePrintManagement(false); SalesConfirmJournalPrint.parmPrinterSettingsFormLetter( SRSPrintDestinationSettings.pack()); // Print SalesConfirmJournalPrint.printJournal(set); } |
Druckeinstellungen und Filterkriterien eines Reports vorbelegen II
08.05.2011Microsoft Dynamics AX (Axapta)
Wie startet man einen Bericht, bei dem eine von RunBaseReport abgeleitete Klasse vorgeschalten ist, per X++ und gibt diesem Bericht bereits den Query und die Druckeinstellungen vor? Wer sich diese Frage schon einmal stellen musste, für den liefert dieser Blogbeitrag vielleicht einen Lösungsansatz: static void setPrintJobSettingsQuery4ReportClass_II(Args _args) { custReport custReport = new custReport(); printJobSettings printJobSettings = new printJobSettings(); ; custReport.makeReportRun(); // Modify Query sysQuery::findOrCreateRange(custReport.reportRun().query().dataSourceTable(tableNum(custTable)), fieldNum(custTable, custGroup)).value(queryValue('10')); custReport.reportRun().query().interactive(false); // Create printJobSettings printJobSettings.setTarget(PrintMedium::File); printJobSettings.format(PrintFormat::PDF); printJobSettings.fileName(@"C:\Temp\CustTableReport.pdf"); // Apply printJobSettings custReport.reportRun().printJobSettings(printJobsettings.packPrintJobSettings()); custReport.reportRun().report().interactive(false); // Disable default printer-dialog custReport.reportRun().run(); } Obiger Code instanziiert ein Objekt der Klasse custReport, deren wesentliche Methoden wie folgt aussehen: class CustReport extends runBaseReport { }
public identifiername lastValueElementName() { identifiername ret; //ret = super(); ret = reportStr(Cust); return ret; }
static ClassDescription description() { return "Custreport"; }
static void main(Args args) { CustReport CustReport; ; CustReport = new CustReport(); if (CustReport.prompt()) { CustReport.run(); } } |
|
|
|
|
|
|
In diesem Beitrag habe ich schon einmal beschrieben, wie man einen DataProvider "debuggen" kann, der von SRSReportDataProviderBase abgeleitet ist.
Der folgende Job macht prinzipiell das gleiche, allerdings für vorverarbeitete Reports, also welche wo der DataProvider von SrsReportDataProviderPreProcess abgeleitet ist. Im Beispiel verwende ich den DataProvider einer Ausgangsrechnung (SalesInvoice).