Thursday, July 2, 2015

Exporting data to an XML file

class CreateXmlFile
{
}


public static void main(Args _args)
{
XmlDocument doc;
XmlElement nodeXml;
XmlElement nodeTable;
XmlElement nodeAccount;
XmlElement nodeName;
MainAccount mainAccount;
#define.filename(@'C:\Users\XYZ\Desktop\AX(FolderName)\accounts.xml')
doc = XmlDocument::newBlank();  /*----Create a new XML Document------*/
nodeXml = doc.createElement('xml'); /*----Create its root node named xml using the createElement() method ------*/
doc.appendChild(nodeXml); /*-----add the node to the document by calling the document's
appendChild() method. ------*/
while select RecId, MainAccountId, Name from mainAccount
{
nodeTable = doc.createElement(tableStr(MainAccount));
nodeTable.setAttribute(fieldStr(MainAccount, RecId),int642str(mainAccount.RecId));
nodeXml.appendChild(nodeTable);
nodeAccount = doc.createElement(
fieldStr(MainAccount, MainAccountId));
nodeAccount.appendChild(
doc.createTextNode(mainAccount.MainAccountId));
nodeTable.appendChild(nodeAccount);
nodeName = doc.createElement(
fieldStr(MainAccount, Name));
nodeName.appendChild(
doc.createTextNode(mainAccount.Name));
nodeTable.appendChild(nodeName);
}
doc.save(#filename);
info(strFmt("File %1 created.", #filename));
}

/* Explaination for the code */

Next, we go through the MainAccount table and do the following for each record:
1. Create a new XmlElement node, which is named exactly as the table name, and add
this node to the root node.
2. Create a node representing the account number field and its child node representing
its value. The account number node is created using createElement(), and its
value is created using createTextNode(). The createTextNode() method
basically adds a value as text with no XML tags.
3. Add the account number node to the table node.
4. Create a node representing the account name field and its child node representing
its value.
5. Add the account name node to the table node.
Finally, we save the created XML document as a file.

Monday, June 29, 2015

How to write a job to print coming 5 Tuesdays with date using X++

You can print the coming 5 Tuesday with the help built in Date function :- 

static void dayofweek(Args _arg)
{
    date d = today();
    str s;
    int i;
    ;
    i= dayOfWk(d);
    switch( i )
    {
        case 1:
            d = d + 1;
            break;
        case 2:
            d = d+7;
            break;
        case 3:
           d = d+6;
            break;
        case 4:
           d = d+5;
            break;
        case 5:
           d = d+4;
            break;
        case 6:
           d = d+3;
            break;
       case 7:
           d = d+2;
            break;        
         
    }

    for(i=1;i<=5;i++)
    {
    s=dayName(dayOfWk(d));  
    info(strFmt('  %1 %2' , d , s));
        d = d+7;
    }
 
}


Tuesday, June 9, 2015

Number Sequence in AX 2012 using X++

Step by step procedure to create number sequence :-

Step 1:- Create a EDT : Esh_StdId

AOT >> Extended Data Types >> New >> Properties >> Name >> Esh_StdId.



Step 2:- Select the Module in which you want to generate the Number Sequence.

EX:-Human Resource
AOT>Classes> NumberSeqModuleHRM >LoadModule

Step 3:- Write a code on lode module() on NumberSeqModuleHRM.


    datatype.parmDatatypeId(extendedtypenum(Esh_StdId));
    datatype.parmReferenceLabel(literalstr("Number Sequence"));
    datatype.parmWizardIsContinuous(true);
    datatype.parmWizardIsManual(NoYes::No);
    datatype.parmWizardIsChangeDownAllowed(NoYes::No);
    datatype.parmWizardIsChangeUpAllowed(NoYes::No);
    datatype.parmWizardLowest(1);
    datatype.parmWizardHighest(999999);
    datatype.parmSortField(20);

    this.create(datatype);

Step 4:- Write a method on HRMParameters Table
Note:- Every Module has there own parameters table as I have selected HRM Module for Number Sequence I am writing the method in HRMParameters Table.


client server static NumberSequenceReference numRefEshId()
{
     return NumberSeqReference::findReference(extendedTypeNum(Esh_StdId));
}

Step 5:- Create a Table and Drag the EDT which you have created to the Table field.


Step 6:- Write a Job to run the programme.


static void Esh_StdId(Args _args)
{
    NumberSeqModuleHRM  numberSeqModuleHRM = new NumberSeqModuleHRM();
    ;
    numberSeqModuleHRM.load();
}



Step 7:- Now run the wizard
Organization Administration >> CommonForms >> Numbersequences>>Numbersequences>> Generate >> run the wizard.

Step 8:- After generating number sequence go to
Human Resource Area Page >> Setup >> Human Resources Shared Parameter



Step 9:- Click on Number Sequence


Step 10:- Select Reference, Right click on it and select View Record and then Click on Number sequence code.


Step 11:- Edit the Number Sequence and add the Segments as show in the picture.


*uncheck continues in General Tab, save the changes and close the form.

Step 12:- Write the job and check whether the number sequence is working correctly


Step 13:- Run the Job and check the generated Number Sequence


Step 14:- Now steps to check the number sequence in table.

Create a initValue Method in Table Method. Copy the Job code and paste in the initValue method of the Table Method as shown in the picture below.



Step 15:- Now Run the Method it will open the table and automatically generate the number Sequence for the assigned field.


Step 16:- Creating Number Sequence at Form Level
Create a New Form and in Data Source Drag and Drop the table for which you have created Number Sequence as shown in the picture below.



Step 17:- Right Click on Design and Select Grid
Drag and Drop the required field from data source to Design Grid and Open the form.
It will show Number Sequence generated in the form as shown in the picture below.


Step 18:- To get the next Record below of the Previous Record, You need to write Create override method in the form DataSource and change the Boolean append type to True as shown in the picture below.


* Now you will get the result as shown in the below picture..


Friday, May 15, 2015

Method Calling Sequences of Table in AX 2012

When you press CTR+N

inItValue()

When you change data in a Field

validateField()  -> validateFieldValue() ->  ModifiedField() ->  ModifiedFieldValue()

When you close the table after entering some data

validateWrite() - > Insert()  -> aosValidateInsert()

When you open the table which will contain some data
If table will contain 10 records this method is called 10 times

aosValidateRead()

When you Save the Record for the first time

validateWrite() ->Insert() - > aosValidateInsert()

When you modify the record and saving

validateWrite() -> update() - > aosValidateUpdate()

When you delete the record

validateDelete() -> delete() -> aosValidateDelete()

Tuesday, April 28, 2015

How to filter the gird based on the given input in ListPageForm

Filtering the grid based on the given purchase order in the Listpage:-

In ListPage we don't have override method. In order to filter the data based on the given input in the field and If you want to initialize some value to the field and based on that you want the grid to display.

When ever a ListPage Form is Opened, initializeQuery() method on the ListPageInteraction class is called.

In order to filter the grid based on the given input in the Listpage form you need to override the initializeQuery() method.

Scenario :- Take a input field in the PurchTableListPage form and based on the Purchase Order entered in the field it should display the grid.

 It can be achieved by adding the below code.

Add the below code in initializeQuery() method :-

/* actually we are making a range value empty so that when you open the listpage form the grid will be empty */

else
   {
       _query.dataSourceTable(tableNum(PurchTable)).addRange(fieldNum(PurchTable, PurchId)).value(SysQuery::valueEmptyString());
   }


Now add the below code to the modified method of the Field based on which you want the grid to be filter

public boolean modified()
{
    boolean ret;
    ret = super();
    PurchaseTable_ds.queryBuildDataSource().clearRanges();

   /*filtering the grid based on the given purchase order */

   if (this.valueStr() != '' )
   {
       PurchaseTable_ds.queryBuildDataSource().addRange(fieldNum(PurchTable, PurchId)).value(this.valueStr());
       PurchaseTable_ds.executeQuery();
   }

 /* if the input field is empty we are changing the range from PurchId to RecId and searching for RecId with a value "0", which is always not present. This will help you to show an empty grid whenever user enter a null value and search for the list*/  

   else
   {
       PurchaseTable_ds.queryBuildDataSource().addRange(fieldNum(PurchTable, RecId)).value("0");
       PurchaseTable_ds.executeQuery();
   }

   return ret;

}

Monday, April 27, 2015

Find and Exists Method in AX

Find :-

All tables should have at least one find method that selects and returns one record from the table that matches the unique index specified by the input parameters.

The last input parameter in a find method should be a Boolean variable called 'forupdate' or 'update' that is defaulted to false. When it is set to true, the caller object can update the record that is returned by the find method.

See the next example from the InventTable:

static InventTable find(ItemId itemId, boolean update = false --->to define how many primarykeys in table)
{
InventTable inventTable;
;
inventTable.selectForUpdate(update);
if (itemId)
{
select firstonly inventTable -->table name
index hint ItemIdx -->index name
where inventTable.ItemId == itemId;
}
return inventTable;
}

Exists :-

As with the find method, there should also exist an exists method.
It basically works the same as the find method, except that it just returns true if a record with the unique index specified by the input parameter(s) is found.

In the next example from the InventTable you can see that it returns true if the
input parameter has a value AND the select statement returns a value.

static boolean exist(ItemId itemId)
{
return itemId && (select RecId from inventTable
index hint ItemIdx
where inventTable.ItemId == itemId
).RecId != 0;
}

Thursday, April 23, 2015

How to Browse a File in Form Using X++ in AX 2012

Follow the below step to add  Browse Functionality in Form

Step1:-  Create a Form
            > Add a StringEdit in Design
            >Assign a EDT Property as FilenameOpen

Step 2:-
           Add the below Methods to the form in order to complete the functionality

  FilenameFilter filenameLookupFilter()
{
    #file
    return [WinAPI::fileType(#xpo), #allfilesName+#xpo, #allFilesType, #allFiles];
}
-----------------------------------------------------------------------------------------------------------
str filenameLookupTitle()
{
    return "Select a trade agreement to import";
}
------------------------------------------------------------------------------------------------------------

str filenameLookupInitialPath()
{
    return "";
}
-------------------------------------------------------------------------------------------------------------

str filenameLookupFileName()
{
    return "";
}
----------------------------------------------------------------------------------------------------------------

All Done !!!!!!!!!
Now you can browse the file in Form

Method 2 :-

Step 1:-  Create a Form
            > Add a StringEdit in Design
            >Assign a EDT Property as FilenameOpen

Step 2:- Override the Lookup method on StringEdit Control.

public void lookup()
{
    FilenameOpen    file;
    Filename        path;
    Filename        name;
    Filename        type;
    #File

    file = WinAPI::getOpenFileName(element.hWnd(),[WinAPI::fileType(#xlsx),#AllFilesName + #xlsx],path,'Select ...',"",name + type);
    if(file)
    {
        StringEdit.text(file);
    }
}


How to enable the dimension fields based on the Item selected on the form.

[Form] public class KMTShipFromWarehouses extends FormRun {     InventDimCtrl_Frm_EditDimensions        inventDimFormSetup;     /// ...