Dynamics AX Blog - Microsoft Dynamics AX (Axapta) - Page 23
In recent years, i spent a lot of time in developing in the environment of Microsoft Dynamics AX (formerly Axapta). During this time i created a lot of code, from which I could imagine, that it might be very useful for other AX developers too. But I will present also tips and tricks round the powerful ERP system.
Subscribe to RSS feed of this categoryControl editing form fieldsIf you want to control which of the fields on a form are editable, you can use the property allowEdit of the datasource fields. If you have large tables containing a lot of fields, this could be a time-consuming process. So, if you have a form, where the user should only be able to edit one field - in particular case a field from table salesLine -, you could use the following code-example which should be included in the init-method of the datasource. The snippet disallows editing for all fields exept for one field. public void init()
{ sqlDictionary sqlDictionary; ; super(); while select sqlDictionary where sqlDictionary.tabId == tableNum(salesLine) && sqlDictionary.fieldId != 0 { if(sqlDictionary.name != "dataareaid" && sqlDictionary.name != "recversion" && sqlDictionary.name != "recId" ) { salesline_ds.object(sqlDictionary.fieldId).allowEdit(false); } } salesline_ds.object(fieldNum(salesLine, blocked)).allowEdit(true); } Tested in AX 3.0 |
Be careful when duplicating companyThat we can duplicate a company is known. The experience of the past few weeks has taught me the following:
|
Working with the calling object of a form (Caller)The following method contains some snippets that can be used to call various functions/methods of the calling object (form). If you change element.args() to e.g. _args and pass the arguments to the method, you can use the code within a class as well. void workWithCallingRecord() { common common; object object; formDataSource formDataSource; formRun formRun; inventDim inventDim; salesTable salesTable; int i; ; // Call method from calling record if( element.args() && element.args().record() ) { common = element.args().record(); if(common.isFormDataSource()) { info(tableId2Name(common.TableId)); if(formDataSourceHasMethod(common.dataSource(), identifierStr("someMethod"))) { object = common.dataSource(); object.someMethod(); } } } // Call method from calling form if(element.args() && element.args().caller() && element.args().caller().handle() == className2Id('formRun')) { formRun = element.args().caller(); if(sysFormRun::hasMethod(formRun, identifierStr("someFormMethod"))) { object = formRun; object.someFormMethod(); } } // Get value from calling record if( element.args() && element.args().record() ) { common = element.args().record(); if(common.TableId == tableNum(salesTable)) { info(common.(fieldNum(salesTable, salesId))); } } // Get value from calling datasource (form with multiple datasources) if(element.args() && element.args().caller() && element.args().caller().handle() == className2Id('formRun')) { formRun = element.args().caller(); for (i = 0; i <= formRun.dataSourceCount(); i++) { formDataSource = formRun.datasource(i); if (formDataSource && formDataSource.table() == tablenum(inventDim)) // Search for specific table { inventDim = formDataSource.cursor(); break; } } if(inventDim) { info(inventDim.InventLocationId); } } // Change data in calling datasource if(element.args() && element.args().caller() && element.args().caller().handle() == className2Id('formRun')) { formRun = element.args().caller(); for (i = 0; i <= formRun.dataSourceCount(); i++) { formDataSource = formRun.datasource(i); if (formDataSource && formDataSource.table() == tablenum(salesTable)) // Search for specific table { salesTable = formDataSource.cursor(); break; } } if(salesTable) { // Update data salesTable.PurchOrderFormNum = "Some value"; salesTable.update(); } } // Refresh calling datasource if( element.args() && element.args().record() ) { common = element.args().record(); if(common.isFormDataSource()) { formDataSource = common.dataSource(); formDataSource.research(true); } } } |
Dynamics AX: Import Excel fileRecently I was forced to deal with how to read data from an Excel file into AX. Therefore in the following a job with a kind of basic structure, how to solve something like this in X++. static void importFromExcel(Args _args) { Filename fileNameExcel = "C:\temp\file.xls"; SysExcelApplication sysExcelApplication; SysExcelWorkbooks sysExcelWorkbooks; SysExcelWorksheets sysExcelWorksheets; SysExcelWorksheet sysExcelWorksheet; SysExcelRange sysExcelRange; SysExcelCells sysExcelCells; SysExcelWorkbooks sysExcelWorkBooksCollection; str column_a; str column_b; str column_c; str column_d; int i = 0; #Excel ; sysExcelApplication = SysExcelApplication::construct(); sysExcelWorkbooks = sysExcelApplication.workbooks(); sysExcelWorkbooks.open(fileNameExcel); sysExcelWorksheets = sysExcelApplication.worksheets(); sysExcelWorksheet = sysExcelWorksheets.itemFromNum(1); sysExcelRange = sysExcelWorksheet.rows(); sysExcelCells = sysExcelWorksheet.cells(); try { ttsbegin; while (sysExcelCells.item(i+1, 1).value().variantType() != ComVariantType::VT_EMPTY) // In der Annahme, dass die erste Spalte nicht leer ist { i++; column_a = sysExcelCells.item(i, 1).value().bStr(); column_b = sysExcelCells.item(i, 2).value().bStr(); column_c = sysExcelCells.item(i, 3).value().bStr(); column_d = sysExcelCells.item(i, 4).value().bStr(); // ... do something ... } ttscommit; info("Finished"); sysExcelApplication.quit(); sysExcelApplication = null; } catch (Exception::Error) { sysExcelApplication.quit(); sysExcelApplication = null; } } |
Dynamics AX: Illegal property valueIf you try to change the AllowDuplicates-Property of a table index from No to Yes, the following error message may occur: Illegal property value In this case, presumably, the affected index is registered as PrimaryIndex or ClusteredIndex of the table. |
Dynamics AX: Print SalesInvoice through codeUsing the following code you can easily print sales invoice through code. With slight modifications to the code, this is also true for all other sales- and purchase-sided documents. Short example in AX 2009 static void PrintSalesInvoice(Args _args) { custInvoiceJour custInvoiceJour; SalesFormLetter salesFormLetter = SalesFormLetter::construct(DocumentStatus::Invoice, false); PrintJobSettings printJobSettings = new PrintJobSettings(); Args args = new Args(); boolean prompt = true; boolean printIt = true; ; if (prompt) { // Dialog printIt = printJobSettings.printerSettings('SysPrintForm'); } else { // Printjobsettings printJobSettings.setTarget(PrintMedium::File); printJobSettings.format(PrintFormat::PDF); printJobSettings.fileName(@'c: empmyfile.pdf'); } if (!printIt) { return; } salesFormLetter.updatePrinterSettingsFormLetter(printJobSettings.packPrintJobSettings()); select firstOnly custInvoiceJour where custInvoiceJour.salesid == '100001'; args.record(custInvoiceJour); args.caller(salesFormLetter); new MenuFunction(menuitemoutputstr(SalesInvoice), MenuItemType::Output).run(args); } Short example in AX 4.0 static void PrintSalesInvoice(Args _args) { custInvoiceJour custInvoiceJour; SalesFormLetter salesFormLetter = SalesFormLetter::construct(DocumentStatus::Invoice, false); PrintJobSettings printJobSettings = new PrintJobSettings(); Args args = new Args(); boolean prompt = true; boolean printIt = true; salesPrintSetup salesPrintSetup; ; if (prompt) { // Dialog printJobSettings = new PrintJobSettings(salesPrintSetup.PrintJobSettings); printIt = printJobSettings.printerSettings('SysPrintForm'); salesPrintSetup.PrintJobSettings = printJobSettings.packPrintJobSettings(); } else { // Printjobsettings printJobSettings.setTarget(PrintMedium::File); printJobSettings.format(PrintFormat::PDF); printJobSettings.fileName(@'c: empmyfile.pdf'); } if (!printIt) { return; } salesFormLetter.updatePrinterSettingsFormLetter(printJobSettings.packPrintJobSettings()); select firstOnly custInvoiceJour where custInvoiceJour.salesid == '100001'; args.record(custInvoiceJour); args.caller(salesFormLetter); new MenuFunction(menuitemoutputstr(SalesInvoice), MenuItemType::Output).run(args); } |
|
|
|
|
|
|
If you want to run specific forms or classes when Dynamics AX is started, you could use the command-line-param autorun. This parameter awaits a xml-file containing the objects, which should be launched.
The corresponding xml-file startup.xml looks like this:
Additional information are available at MSDN: http://msdn.microsoft.com/en-us/library/aa870082.aspx