Friday, 30 October 2015

Based on selected element in combo box it has to show data in grid
Based on selected enum element it has to display the data.
The enum should contain two elements.
1. Customer.
2. Vendor.

Explanation:

I created a table using common fields from cust table and vend table.
Created table is attached to newly created form datasource.
Overrided form datasource init method as below to show grid empty while opening form.

public void init()
{
    delete_from CustomerVend;
    super();
}

Required fields are added to form designs -> grid.
A new combobox is created under designs
Enum property of combobox --> customervend(Enum)
Overrided modified method of combobox to show data
based on selected element in customervend enum.

public boolean modified()
{
    CustomerVend cv;
    CustTable ct;
    VendTable vt;
    boolean ret;
    ret = super();
    delete_from cv;
    if(this.valueStr() ==(enum2str(CustVendACType::Cust)))
    {
        while select * from ct
        {
            cv.AccountNum=ct.AccountNum;
            cv.BankAccount=ct.BankAccount;
            cv.CurrencyName=ct.Currency;
            cv.insert();
        }

        CustomerVend_ds.research();
        CustomerVend_ds.refresh();
    }
   else
      {
        while select * from vt
        {
            cv.AccountNum=vt.AccountNum;
            cv.BankAccount=vt.BankAccount;
            cv.CurrencyName=vt.Currency;
            cv.insert();
        }
          CustomerVend_ds.research();
          CustomerVend_ds.refresh();
    }
    return ret;
}




Filtering of grid data using date filters in form.

  • I created a form using salesline as data source.Add fileds in grid under the design node.
  • In design node add group.In that group add 2 utcdatetime controls. Add one more button in this group.
  • Now create a grid and drag and drop the fields what ever you want into the grid from data source.
  • override the execute query method in form data source methods.

public void executeQuery()
{
    Query query = new Query();
    QueryBuildDataSource  qbds;

    QueryBuildRange qbr;

    qbr = SysQuery::findOrCreateRange(SalesLine_q.datasourceTable(tableNum(SalesLine)),
    fieldNum(SalesLine,ShippingDateConfirmed));
    if (ToDate.dateTimeValue() > FromDate.dateTimeValue() )

    //if (ToDate.dateTimeValue() !=utcdatetimenull() && FromDate.dateTimeValue() !=utcdatetimenull())
        {

        qbr.value(SysQuery::range(FromDate.dateTimeValue(),
        ToDate.dateTimeValue()));
        super();
        }
    else
        {
        qbr.value(SysQuery::valueUnlimited());

        }
}

  • Override clicked method in the button.

void clicked()


    super();
    SalesLine_ds.executeQuery();

}


  • Make sure that the allow declaration property for the controls are yes.
  • Also keep the arrange method property as Horizontal, flush right for group controls.




Thursday, 29 October 2015

 scenario .
The scenario is consider two tables as student and faculty table.
Student table having below fields.
1.       Student Id.
2.       Student Name.
Faculty table having all the student table fields and below given fields.
1.       Faculty Id.
2.       Faculty Name.
When we insert a field (Student Id) in faculty table, by default the Student Name for the selected Student Id should be inserted.
How to achieve this :
    I created both tables with normal relation.
   Under the faculty table methods I written modified field method to perform automatic insertion of Student Name for the selected Student Id.
The code written for the modified field method is as below.
  Public void modifiedfield(fieldId_fieldid)
  {
  StudentTable st;
  If(_fieldid==fieldnum(st,StudentId))
  Super(_fieldid);
  Select st
  Where st.StudentId==this.StudentId;
  {
  this.SName=st.SName;
  }

 }
Displaying job code in infolog 
This time I came with an interesting concept like treenode,with this we can see the code that we have written in our job in infolog.

Enable and disable of records based on enum value in forms

  • First create a baseenum with elements active and inactive.Name that baseenum as status of condition.
  • Create a table with fields name and baseenum.



  • Create a form using above table in data source.
  • Now create a grid in design.
  • Add table fields in grid.
  • Override  selection changed method in form datasource methods. 

  • The output should be like this. 


Wednesday, 28 October 2015

How to filter a second LookUp based on a first LookUp  value in Class


We can achive this through run base class.
create a class.
In Class declaration:
class custfilter extends RunBase
{
    DialogField     custid,custgroupid;
    Dialog          dialog;

    CustAccount     custaccount;
    CustGroupId     custgroup;
}

Dialog:

protected Object dialog()
{
    ;
    dialog = super();
    custgroupid = dialog.addField(extendedTypeStr(CustGroupId));
    custid      = dialog.addField(extendedTypeStr(CustAccount));
    return dialog;
}

getFromDialog:



public boolean getFromDialog()
{

    CustGroupId = custgroupid.value();

    CustAccount = custid.value();
    return super();
}


run:
public void run()
{
    super();
}

where dialogCustId is the EDT. let say the name returned at runtime is Fld2_1.

Now if you have to override lookup method of the EDT you can write the method like this
Lookup:
public void Fld2_1_Lookup()
{
    SysTableLookup          systablelookup;
    QueryBuildDataSource    qbds;
    QueryBuildRange         qbr;
    Query                   q;
    CustTable               ct;
    CustGroup               cg;
    ;
    if(custgroupid.value())
    {
        systablelookup = SysTableLookup::newParameters(tableNum(CustTable),custgroupid.control());
        systablelookup.addLookupfield(fieldNum(CustTable,AccountNum));

        q = new Query();
        qbds = q.addDataSource(tableNum(CustTable));
        qbds = qbds.addDataSource(tableNum(CustGroup));
        qbr = qbds.addRange(fieldNum(CustGroup,custgroup));
        qbds.relations(true);
        qbds.fetchMode(QueryFetchMode::One2One);
        qbr = qbds.addRange(fieldNum(CustGroup,custgroup));
        qbr.value(custgroupid.value());
        systablelookup.parmQuery(q);
        systablelookup.performFormLookup();
    }
}

main:
public static void main(Args _args)
{
    custfilter custcreate = new custfilter();


    if (custcreate.prompt())
    {
        custcreate.run();
    }
}
dialogPostRun
public void dialogPostRun(DialogRunbase dialogs)
{
//;
    dialog.dialogForm().formRun().controlMethodOverload(true);
    dialog.dialogForm().formRun().controlMethodOverloadObject(this);
    //dialog.formRun().controlMethodOverload(true);
    //dialog.formRun().controlMethodOverloadObject(this);
    //dialog.allowUpdateOnSelectCtrl(true);
    //super(dialog);

}

Calling this class from job:

we can also call the above class from job using this code.
static void Job20(Args _args)
{
    custfilter ::main(_args);

}


How to override the event methods on dialog controls?


Overriding the event methods (e.g. modify, validate, selectionChange) on dialog controls is not as straight forward as it is on form controls, but the good news is that it is possible!
In order to override the event methods on dialog controls, the following needs to be done (for simplicity we assume that your class extends RunBase class) :
1) The method dialogPostRun() should be overridden and following two lines are added after the super() call:
_dialog.dialogForm().formRun().controlMethodOverload(true);
_dialog.dialogForm().formRun().controlMethodOverloadObject(this);

This will allow to call the event methods of your class.

2) The actual event methods should be added.
The format of the event method name is as follows: fld<ID>_1_<event name>

Please see the example below.
This method is called whenever a value of the dialog control with ID 900 is modified. In our case it is Employee ID field.

public boolean fld900_1_modified()
{
FormStringControl control = dialog.formRun().controlCallingMethod();
boolean isFieldModified;
;
isFieldModified = control.modified();
// every time the employee id is changed, update the employee name
if(isFieldModified)
{
dlgFldEmplName.value(EmplTable::find(control.text()).Name);
}
return isFieldModified;
}
You will also need to make sure that the control “Employee ID” gets the same control ID as used in the event method name (ID 900). This should be done at the time of adding the control to the dialog. Please see below:
protected Object dialog(DialogRunbase _dialog, boolean _forceOnClient)
{
;
dialog = super(_dialog, _forceOnClient);
// Add a new field by explicitly specifying the field id.
// This field id is used to create the field event methods (e.g. fld900_1_modified()).

dlgFldEmplId = new DialogField(dialog, typeid(EmplId), #dlgFlgEmplIdFieldNo);
dialog.addCtrlDialogField(dlgFldEmplId.name());
dlgFldEmplId.init(dialog);
dlgFldEmplId.label("@SYS81251");
dlgFldEmplId.helpText("@SYS81251");
dlgFldEmplId.value(emplId);

}
As you can see the macro #dlgFlgEmplIdFieldNo is used to assign the ID to the dialog control. The macro is defined in the classDeclaration and it equals 900.

That’s all what you need to do to be able to override the events on the dialog controls.

//You can also create a dialog form and pass it as the parameter in the dialog method of runbase class. you can find an example in tutorial_runbase class and form.

Refference Link:
https://community.dynamics.com/ax/b/dynamics101trainingcenterax/archive/2015/02/10/runbase-framework-in-microsoft-dynamics-ax-2012

How to filter a second LookUp based on a first LookUp  value in Form’s



  • First I created a form and added two tables (InventItemGroup, InventItemGroupItem).
  • In the design add new string edit controls (Item GroupId), string edit1 (ItemId).
  • Override the lookup method in string edit(Item GroupId).

public void lookup()
{
     Query q = new Query();
    QueryBuildDataSource        qbds;
    QueryBuildRange             qr;

     SysTableLookup  sl = SysTableLookup::newParameters(tableNum(InventItemGroup),this);

    sl.addLookupfield(fieldNum(InventItemGroup,ItemGroupId),true);
    qbds = q.addDataSource(tableNum(InventItemGroup));

    sl.parmQuery(q);
    sl.performFormLookup();
    super();
}
Override the lookup method in string edit1( ItemId).
public void lookup()
{
    Query q = new Query();
    QueryBuildDataSource        qbds,qbds1;
    QueryBuildRange             qr1,qr2;

    SysTableLookup  sl = SysTableLookup::newParameters(tableNum(InventItemGroupItem),this);
    sl.addLookupfield(fieldNum(InventItemGroupItem,ItemId),true);
 

    qbds = q.addDataSource(tableNum(InventItemGroupItem));
    qbds1 = qbds.addDataSource(tableNum(InventItemGroup));
        qbds1.joinMode(JoinMode::ExistsJoin);
    qbds.relations(true);
  
    qr1 = qbds.addRange(fieldNum(InventItemGroupItem,ItemGroupId));
  
    qr1.value(ItemGroupId.valueStr());

    sl.parmQuery(q);
    sl.performFormLookup();
   
}










Tuesday, 27 October 2015


Find method in ax 2012 and usage
Find method in ax 2012:
1. Find method can be used for finding the data’s from outside the table using some relations.
2. Static keyword is very important in find method.
3. Tablename – means the return type of the find method. Here you can use table OR Field. But most of the cases we can use table as return type, so that we can get all the data’s from single find method.
4. OvertimereqId – Primary index field, based on this we can get the data. Here I used EDT of the index field.
 Example for the find method:
 static Tablename find(OvertimereqId   _OvertimereqId, boolean       _forUpdate = false)
{
    Tablename tablename;
    ;
     if (_OvertimereqId)
    {
        if (_forUpdate)
            tablename.selectForUpdate(_forUpdate);
         select firstonly tablename
            index hint ReqNoIdx
            where tablename.Requestno == _OvertimereqId;
    }
    return tablename;
}
 5. From the above code inside the find parameter we can specify multiple primary OR cluster index field as we want, but initially for update should be false.
6. For update is needed when all the indexes are in table, then we can allow the update.
7. We can use this method in multiple tables, display methods,assigning values to the other table.
 How to use the find method:
 8. In form level , table2 must have the same field.
            Anyfield = Tablename ::find(table2.OvertimereqId).name;
9. In display method also we can use the same code.
     EX:  
       display name getname()
      {
        return Tablename ::find(table2.OvertimereqId).name;
       }

Tuesday, 20 October 2015

Sequence of methods in the FORM level in AX
Hi...

This gives the information of method calls in the form level while
1. Opening the Form.
2. Creating/Updating/Deleting the record in the Form.
3. Closing the Form.
Sequence of Methods calls while opening the Form

Form --- Datasource --- init ()
Form --- init ()
Form --- run ()
Form --- Datasource --- execute Query ()
Form --- Datasource --- active ()

Sequence of Methods calls while closing the Form
Form --- canClose ()
Form --- close ()

Sequence of Methods calls while creating the record in the Form
Form --- Datasource --- create ()
Form --- Datasource --- initValue ()
Table --- initValue ()
Form --- Datasource --- active ()

Sequence of Method calls while saving the record in the Form
Form --- Datasource --- ValidateWrite ()
Table --- ValidateWrite ()
Form --- Datasource --- write ()
Table --- insert ()

Sequence of Method calls while deleting the record in the Form
Form --- Datasource --- validatedelete ()
Table --- validatedelete ()
Table --- delete ()
Form --- Datasource --- active ()

Sequence of Methods calls while modifying the fields in the Form
Table --- validateField ()

Table --- modifiedField ()