Skip to main content

Posts

Showing posts from November, 2011

Fetching Records Using Query Object

In my previous post “Playing with data”, I have made you guys learn how to retrieve data using the select query which you can write anywhere. You just need to declare the table buffer for that. However, there are some cases where it is not recommended to use the select statement to retrieve data for example it is not recommended to use select statement at Form level methods. So, what could be used to retrieve data? The answer is Using Query Object. Normally queries are stored in AOT (see Queries Node in AOT), but they can also be created from code dynamically. The Query object is used when a user interaction is required, like user wants to add range or sort the data. In order to create query from code, the objects that needs to be created are, Query: The query class object defines the structure of the query. Objects of this type are not used for fetching records from the database. Instead, use a QueryRun object that may be assigned a query object. QueryBuildDataSource : T he Qu...

Working with Multiple Datasource on a single Form

Today we will discuss how we can display records from multiple datasources in a single form. Data sources on a form allow the form to display the data from the table specified on the data source. A table in a data source can be sorted and filtered by the user, which is an important feature of Microsoft Dynamics AX. Forms can have multiple data sources, and each data source can be joined to another data source on the form using the defined relations between the tables. Relations or Dynalinks can also be added in the form code. A form data source produces a query that can be manipulated in the same way as any other query in the system. If you wish to display records from two tables on one form, you can limit the records in one of the tables to the related records in the other table. You can do this by specifying a join between the two tables. The join is specified on the JoinSource property of the second or joined table. Here you should enter the data source name of the main data sour...

Passing Parameters to a Report in Dynamics AX

Creating reports in AX is generally ‘a walk in the park’ even for the new developers not fully acquaint with the syntax of X++. However, it sometimes becomes challenging to understand how the parameters could be passed to a report when you want to initiate that report from a form. Let’s look at an example where you may want to create a ‘Purchase Requisition Report’ that the users could generate to see the status of each purchase requisition and the associated workflow entries for that Purchase Requisition. I will not go into the details of how to develop this report, but you should know that such a report do not exist in the out-of-the-box functionality within AX 2009. So let’s say that you have developed this report and now when you generate this report you can pass on the required ‘Purchase Requisition ID’ in the ‘Parameter Prompt’ of the report to view the particular PR details accordingly. However, now in the next step you want to call this report from the ‘Purchase Requisition...

How to: Print a Range of Pages from a Report

static void printToPDF(Args _args) {     Args                args;     ReportRun           rr;     str reportName = 'Cust';     ;     args = new Args(reportName);     rr = new ReportRun(args,'');         rr.setTarget(Printmedium::File);     rr.printJobSettings().format(PrintFormat::PDF);     rr.printJobSettings().fileName("C:\\Cust_ReportRange.pdf");         rr.printJobSettings().allPages(false);     rr.printJobSettings().from(2);     rr.printJobSettings().to(4);     // Disables forms that enable users to modify     // the report query and print settings.     rr.query().interactive(false); ...

How to create InventBatchId for an item by Code.

I have table VTVSheetingOrderLine that has 2 fields InventBatchID & ItemId. And table VTVSheetingOrderLine related to InventDim, InventTrans, InventBatch. The relations will be like: InventDim.InventDimId     = InventTrans.InventDimId InventTrans.InventTransId = VTVSheetingOrderLine .InventTransId InventDim.InventBatchId  = InventBatch.InventBatchId. I create form B from table VTVSheetingOrderLine . Add a button "Create Batch Id" on that form. I wrote codes but it seem not enough, because I don't know how to create the relations between those table void clicked() {     InventNumGroup inventNumGroup;     Num                     _num;     int                        increment; ...

Send a report, but change the filename according to caller

My customers has grown tired by the filename 'Axapta report' in class Info -> method reportsend().  I need to change the filename to the name of the caller. But how do I find the caller in class Info -> Method reportsend() ? I need to change the filename "online" and not in batch. MBS has suggested the following place to modify the filename: AOT\Class\Classes\Info\reportSendMail() But at runtime i cant really find anything about the caller from inside the reportSendMail() method. There seems to be no args. So maybe its impossible to get the caller form from this method? ======== Let's see if it works this time.... (it's only the SIXTH time that I try to post this answer :( ) There seems to be no way to get a reference to the ReportRun object; the method PrintJobSettings.ReportRun always seems to return null in reportSendMail. You could set a property of PrintJobSettings in your report and use that to fill the filename. Another po...

transfer Images to Word from AX

I need to transfer the employee`s image to an automatic generated word document. It is possible to transfer Text to COM word object with [bookmark, bookmarkValue] = ['EmplTable_FullName', LtabDirParty.Name]; if (this.gotoBookmark(bookmark)) this.insertValue(bookmarkValue, 0); whereby Textmarker within Word = EmplTable_FullName Method gotoBookmark() COMrange = COMdocument.goTo(#wdGotoBoomark,COMArgument::NoValue,COMArgument::NoValue,bookmark); Method inertValue() COMrange.insertAfter(value); Does anybody know how to transfer the Empl-Image (as an image) from AX to word? binData.setData( CompanyImage::find(LtabEmpl.dataareaId, LtabEmpl.TableId, LtabEmpl.RecId).Image; binData.base64Encode() transfers a binary string which will be displayed as a binary text. But how can I display the image as real Image? Take a look at Task Recorder - it is able to generate Word documents with screenshots. Class SysTaskRecorderDocStandardWord and its method insertS...

To read an Excel file

static void ExcelIoTest ( Args _args ) {     ExcelIo io;     #Excel     dialogField dialogFilename;     Dialog dialog = new Dialog ( "Excel Upload" ) ;     container con;     ;     dialogFilename = dialog. addField ( typeId ( FilenameOpen ) ) ;     dialog. filenameLookupTitle ( "Upload from Excel" ) ;     dialog. filenameLookupFilter ( [ "@SYS28576" ,#XLSX, "@SYS28576" ,#XLS ] ) ;     if ( !dialog. run ( ) )         return ;     io = new ExcelIo ( dialogFilename. value ( ) , 'r' ) ;     setprefix ( "Excel Import" ) ;     while ( io. status ( ) == IO_Status:: Ok )     {         con = io. read ( ) ;         info ( con2str ( con ) ) ;     ...

How can protect Sales Order line price?

First,find the cost price control in SalesTable Form SalesLine_ReturnCostPrice, set AutoDeclaration Yes. Second, find SalesTable Form->Data Sources->SalesLine->Fieds->CostPrice->methods then right click, choose override modified method, and insert the follwing codes : public void modified() { ; if(any2real(SalesLine_ReturnCostPrice.valueStr()) < SalesLine::find(salesLine.SalesId,salesLine.LineNum,false).CostPrice) { info('Under the cost price,please check!'); } else { super(); } }

Print report without user dialog

How can I print a report to screen without a user dialog in DAX2009? I have created a report based on ProdTable and I have created the following method on ProdTable: void printReport() { Args parameters = new Args(); MenuFunction prodQCreportMenu; ; prodQCreportMenu = new MenuFunction(menuitemoutputstr(ProdReport), MenuItemType::Output); parameters.record(this); prodQCreportMenu.run(parameters); } I have a class that calles ProdTable.printReport() for two or more productions, but when the report is printed it is printed twice for the same production. I am sure that this call in my class handles two differenc ProdTable records. It seems like there are some usageData or something on the query on the report, but I can't figure out what. Any ideas? Take a peek at the class EPSendDocument method makeDocument(). This code actually saves a report to a PDF file without any user interaction, but the general concept should work. The co...

Invent Movement Journal Creation and Posting from excel

static void MovementJournalImportExcel(Args _args) { InventJournalTrans inventJournalTrans; InventDim inventDim; InventJournalTable inventJournalTable; InventJournalCheckPost journalCheckPost; InventJournalId journalId; journalTableData journalTabledata; InventBatch inventBatch; InventBatch localInventBatch; NumberSeq numberSeq; NumberSequenceReference numberSequenceReference; InventSerial inventSerial; InventSerial localinventSerial; int j,countno=0,i,k; real Scarp; FilenameOpen filename; Sysexcelapplication excelapp=sysexcelapplication::construct(); sysexcelworksheet excelworksheet; sysexcelrange excelrange; sysexcelcells excelcells; // comvariant cellvalue=new comvariant(); ; // Creating Journal Header inventJournaltable.initValue(); inventJournalTable.JournalNameId = 'ERecover'; numberSeq = new NumberSeq(); n...

Create a dialog radiobutton

Create a dialog radiobutton static void CreateRadio(Args _args) { Dialog dialog = new Dialog(); DialogField df; FormRadioControl frc; ; df = dialog.addField(typeid(BaseEnum1)); frc = df.control(); frc.helpText(“Whatever the help message should be”); dialog.run(); }

Create Movement Journal And Post from excel

static void MovementJournalImportExcel(Args _args) { InventJournalTrans inventJournalTrans; InventDim inventDim; InventJournalTable inventJournalTable; InventJournalCheckPost journalCheckPost; InventJournalId journalId; journalTableData journalTabledata; InventBatch inventBatch; InventBatch localInventBatch; NumberSeq numberSeq; NumberSequenceReference numberSequenceReference; InventSerial inventSerial; InventSerial localinventSerial; int j,countno=0,i,k; real Scarp; FilenameOpen filename; Sysexcelapplication excelapp=sysexcelapplication::construct(); sysexcelworksheet excelworksheet; sysexcelrange excelrange; sysexcelcells excelcells; // comvariant cellvalue=new comvariant(); ; // Creating Journal Header inventJou...

Performing File IO with the TextIo Class

static void Job_File_IO_TextIo_Write_Read(Args _args) {     TextIo txIoRead,          txIoWrite;     FileIOPermission fioPermission;     container containFromRead;     int xx,         iConLength;     str sTempPath,         sFileName = "Test_File_IO.txt",         sOneRecord;     ;     // Get the temporary path.     sTempPath = WINAPI::getTempPath();     info("File is at: " + sTempPath + sFileName);     // Assert permission.     fioPermission = new FileIOPermission         (sTempPath + sFileName ,"RW");     fioPermission.assert();     // If the test file already exists, delete it.    ...

How to create a query range that searches two different fields

The 'OR' in a query is a little bit more complex the for example the 'AND', but it's not impossible. The following code should do the trick: q = new Query(); qbds = q.addDataSource(tablenum(DirPartyTable)); qbr = qbds.addRange(fieldnum(DirPartyTable, recId)); qbr.value(strfmt('("%1" == %2.%3) || ("%1" == %2.%4)', name, qbds.name(), fieldstr(DirPartyTable, firstName), fieldstr(DirPartyTable, lastName))); I just use the DirPartyTable as example. name is the argument that is passed to function.

How can I start a Job by X++ Code?

You can do that, but using a job instead of a class has only disadvantages (e.g. jobs aren't able to run on server side). Don't use jobs in any production code. In general, you have two possibilities - to create a menu item and call it: //you can change the type of called object without changing the invocation code MenuFunction::runClient(menuItemActionStr(YourMenuItem), MenuItemType::Action); or to run an application object via TreeNode: #AOT ; TreeNode::findNode(strFmt(#JobPath, identifierStr(YourJob))).AOTrun();