Showing posts with label Forms. Show all posts
Showing posts with label Forms. Show all posts

January 21, 2019

List panel control in Dynamics 365 FO #MSDyn365FO

Hi Folks,

A list panel is an interactive control to assign multiple values to a record. It let the user select multiple records against selected record on a form/grid. To understand it better let's take an example, I want to assign vendor group(s) to an employee so he/she can access those vendor related stuff like Masters, Transactions or PR creation (I am not covering the security in this post, its only about the List panel control). In today’s post I will be creating a new object for a random example, in real time you may need to tweak the solution to fit your requirement.

To do this what I need are
1. A new table to store these data. 1 Employee: N Vendor Groups
2. A new form where I can select an employee and then select one or many vendor groups to this selected employee.
3. List panel on this new form to do actual operation.

First, let's see how my form and table should look like,
imageimage

and your table browser should look like below,
image

To achieve this setup you need to create a new table as below
image

and new form as below,
image

Now, lets coming to coding part. Although there are many ways to achieve this setup, the best I would recommend is by using  SysListPanelRelationTableCallback framework class. By using this class you can achieve this with minimal coding. You need to add a group on from here we have ListPanelGroup which will be used to create list panel control. Overwrite init method on form and paste below code.

A. Initialize the control.


here
  1. Form control
  2. Caption for available records in the list
  3. Caption for selected records in the list
  4. ImageId (e.g. #ImageUser)
  5. Relation table: new table which we created to store data.
  6. Relation field: Field which you need to save in table from the list.
  7. Relation range field: Source field which you want to select in relation to binding with related field.
  8. Data table: Source table for list records. here we have VendGroup table.
  9. Data field: Field to be selected from list panel control.
  10. Data container field Ids: Fields that you want to show in available records.
  11. dataRangeField
  12. dataRangeValue
  13. validateMethod
  14. selectedMethod
  15. availableMethod

11-15 parameters can be used to further manipulate the control with some validations.

B. Tab change
Now add a new method on the form to fill the list for previously assigned records

void tabChanged(int fromTab, int toTab)
     {
         #define.TabEmplOverview(1)
         #define.TabvendGroup(2)
        switch (toTab)
         {
             case #TabvendGroup:
                 listPanel.parmRelationRangeValue(HcmWorker.name()); //This should be compatible to 7th parameter of SysListPanelRelationTableCallback in init method
                 listPanel.parmRelationRangeRecId(HcmWorker.RecId);
                 listPanel.fill();
                 break;
         }
     }

C. Tab change
Copy paste below code in tabChanged method to call above method every time when the user changes the tab.

[Control("Tab")]
     class Tab
     {
         public void tabChanged(int _fromTab, int _toTab)
         {
             super(_fromTab, _toTab);
             element.tabChanged(_fromTab, _toTab);
         }
    }

That's it, you just created a very simple list panel control with minimal coding.

Cheers!!!
Harry

January 09, 2015

How to add new fields/Methods in Listpage from in AX 2012

How to add new fields/Methods in List page from in AX 2012
Here we use the Production Order list page for example
Open Production order list page from below link
Production control/Common/Production orders/All production orders
clip_image002
Now we need to add one new field “Serial Number” in this grid (Assuming there will be only one item in one Production order in every case).
This serial number is available in “Transaction” from of this production order.
Untitled
Now to display new fields you can add a new display method in table and drag-drop this method in a grid as a field.
Add one new method in “ProdTable” table add copy below code
display InventSerialId inventTransInventSerialId()
{
InventTransOrigin InventTransOrigin;
InventTrans InventTrans;
;
select InventTrans join InventTransOrigin
where InventTrans.InventTransOrigin == InventTransOrigin.RecId &&
InventTrans.ItemId == InventTransOrigin.ItemId &&
InventTransOrigin.ReferenceId == this.ProdId &&
InventTransOrigin.ItemId == this.ItemId;
return InventDim::find(InventTrans.inventDimId).inventSerialId;
}
Now set DataSource property of this new field as ProdTable. Save your from and compile for any error.
Now open this from, here is your from
clip_image008

-Harry

December 23, 2014

How to Attachments button on a new form DAX 2012 R3

Hi Friends,

Here is another post to share with you all.
In this post will will demonstrate how to add a button for document handling on a new AX Form. To add this functionality you may need to perform following steps.

Step 1. Open your form in AOT and Go to from Design node.

Step 2. Add new button group under ActivePanTab.

Step 3. Add new command button under this new button group.

clip_image001

Step 4. Set following properties of this button

clip_image002

Now you need to do one functional setup for this new customization

Step 5: Open below from
 Organization administration/SetUp-> Document Management -> Active Document Table

Step 6: Add your table details here and click on Always enable.

clip_image003

Step 7: So its done now.
Open your form and click on Attachment button , below form must open.

clip_image006
Enjoy……
Merry Christmas to all of you.

-Harry

September 04, 2013

How to create a lookup on Dimension(SysDimesion) ENUM

How to create a lookup on Dimension(SysDimesion) ENUM

Note:
1. DimentionSetCombination is the table in Which dimension hierarchy stored 
2. MachineHour is a customized table in this example, you can use your own logic in the same
3. fieldId2Ext is an X++ keyword which is used to access a particular array index value.
 example:  fieldId2Ext(fieldNum(DimensionSetCombination,Dimension),4)


public void lookup()
{
    SysTableLookup       sysTableLookup =      SysTableLookup::newParameters(tablenum(DimensionSetCombination), this);
    Query                query;
    QueryBuildDataSource queryBuildDataSource;
    QueryBuildRange      queryBuildRange, queryBuildRangeDlvryWH;
    ;

    sysTableLookup.addLookupfield(fieldId2Ext(fieldNum(DimensionSetCombination,Dimension),4), true);

    query                   =   new Query();
    queryBuildDataSource    =   query.addDataSource(tablenum(DimensionSetCombination));
    queryBuildRange         =   queryBuildDataSource.addRange(fieldId2Ext(fieldnum(DimensionSetCombination,Dimension),3));

    queryBuildRange.value(MachineHours.CostElement);
    sysTableLookup.parmQuery(query);
    sysTableLookup.performFormLookup();
}

-Harry

Multiple Tables in field Lookup method

Hi Folks,

Here is an example of lookup where you can use multiple tables in the lookup method. 



-Harry

May 03, 2013

How to Enable/Disable fields in a dialog

How to Enable/Disable fields in a dialog

If you need to enable/disable the dialog fields use dialog postrun method in your code.
here is some code sample for enabling/disable dialog fields.

public void dialogPostRun(DialogRunbase _dialog)
{
    ;
    super(_dialog);
// allow to call the event methods of this class (e.g. theaxapta1_modified() method)
    _dialog.dialogForm().formRun().controlMethodOverload(true);
    _dialog.dialogForm().formRun().controlMethodOverloadObject(this);
}


Now you can create event methods on your dialog fields like theaxapta1.modified() where you can address other components in the dialog, and modify their properties as well.

public boolean theaxapta1_modified()
{
    FormStringControl   control = dialog.formRun().controlCallingMethod();
    boolean             isFieldModified;
    ;
    isFieldModified = control.modified();
// every time the employee id is changed,it will update the employee name
    if(isFieldModified)
    {
        dlgFldEmplName.value(EmplTable::find(control.text()).Name());
    }
    return isFieldModified;
}


You have to make sure that the control “Employee ID” gets the same control ID as used in the event method name (). This should be done at the time of adding the control to the dialog. for eg:

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. 
theaxapta1_modified()).
    dlgFldEmplId = new DialogField(dialog, typeid(EmplId), #dlgFlgEmplIdFieldNo);
    dialog.addCtrlDialogField(dlgFldEmplId.name());
    dlgFldEmplId.init(dialog);
    dlgFldEmplId.label("@SYS81251");
    dlgFldEmplId.helpText("@SYS81251");
    dlgFldEmplId.value(emplId);
// verify that the field name generated by the system is correct
    if(dlgFldEmplId.name() != #dlgFlgEmplIdFieldName)
    {
        throw error(strfmt("@SYS79285", dlgFldEmplId.name(), #dlgFlgEmplIdFieldName));
    }
// Add a new field and let the Dialog framework to do all the work by assigning the field id and initializing the control since there are no event methods for that field.
    dlgFldEmplName = dialog.addFieldValue(typeid(EmplName), emplName, "@SYS54564", "@SYS54564");
    dlgFldEmplName.enabled(false);
    return dialog;
}


Then you can get the value of fields using this method :

public boolean getFromDialog()
{
    boolean ret;
    ret = super();
// get the values from the dialog in order to save them in SysLastValue (using pack() method)
    emplId      = dlgFldEmplId.value();
    emplName    = dlgFldEmplName.value();
    return ret;
}
verify whether a correct employee id has been specified
public boolean fld900_1_validate()
{
    FormStringControl   control = dialog.formRun().controlCallingMethod();
    ;
// verify whether a correct employee id has been specified
    return EmplTable::checkExist(control.text());
}


The pack and unpack methods are used as following:

public container pack()
{
// pack the employee id and employee name and save them in SysLastValue
    return [#CurrentVersion, #CurrentList];
}

public boolean unpack(container packedClass)
{
    boolean  ret;
    Integer  version = conpeek(packedClass,1);
    ;
    switch (version)
    {
        case #CurrentVersion:
// get the employee id and employee name values from the container that has been saved in the SysLastValue record
            [version, #CurrentList] = packedClass;
            ret = true;
            break;
        default:
            ret = false;
    }
    return ret;
}


Finally, in the main method :

static void main(Args args)
{
    SETutorialDialogControlEvent  seTutorialDialogControlEvent = SETutorialDialogControlEvent::construct();
    ;
// show the dialog
    if (seTutorialDialogControlEvent.prompt())
    {
// if OK is pressed, run some code (in that case, run() method should be overriden in the current class)
        seTutorialDialogControlEvent.run();
    }
}


Where SETutorialDialogControlEvent is defined as following:

public static SETutorialDialogControlEvent construct()
{

return new SETutorialDialogControlEvent();
}

As you can see the macro #dlgFlgEmplIdFieldNo is used to assign the ID to the dialog control. 
Overriding the event methods (e.g. modify, validate, selectionChange) on dialog controls is not as straight forward as it is on form controls.


-Harry

April 08, 2013

Create a From through X++ Job

Hi,
Here is small code for create a AX From through X++ Job code.

static void theaxapta_formJob(Args _args)
{
    Form                    form;
    FormRun                 formRun;
    Args                    args;
    FormBuildDesign         formBuildDesign;
    FormBuildControl        formBuildControl;
    FormBuildTabControl     formBuildTabControl;
    FormBuildTabPageControl formBuildTabPageControl;
    FormBuildGridControl    formBuildGridControl;
    FormBuildDatasource     formBuildDatasource;
    FormBuildStringControl  formString;
    ;
    form = new Form();
    formBuildDatasource     = form.addDataSource(tableStr(PurchTable)); // Main Data Source for FORM
    formBuildDesign         = form.addDesign('design');// Add design in FORM
    formBuildTabControl     = formBuildDesign.addControl(FormControlType::Tab, 'Tab');
    formBuildDesign.height(1000);
    formBuildDesign.width(1000);
    formBuildTabPageControl = formBuildTabControl.addControl(FormControlType::TabPage, 'TabPage');
    formBuildTabControl.height(500);
    formBuildTabControl.width(500);

    formBuildGridControl    = formBuildTabPageControl.addControl(FormControlType::Grid, 'Grid');
    formBuildTabPageControl.height(500);
    formBuildTabPageControl.width(100);

    formString              = formBuildGridControl.addDataField(formBuildDatasource.id(), fieldNum(PurchTable, PurchId));
    formString.label("Purchase Order Form");

    args    = new Args();
    args.object(form);
    formRun = classFactory.formRunClass(args);
    formRun.init();
    formRun.run();
    formRun.wait();
}


-Harry

March 15, 2013

Dynamics AX – Form lookups and how they work

There are few different ways to achieve a lookup field on a form.
1.     Create an Extended data type – EDT123




2.     Create a table Table123
3.     Add EDT123 to the table and the Description EDT field
4.     Go back to the EDT and create a relation between table123.EDT123 and the EDT123
5.     Automatically when the EDT field is added to another table lets say CustTable a lookup displaying the values from table123 will be displayed in the drop down.
6.     Now let’s say you want to add the description field to the lookup as well. Add the description field to the AutoLookup field group on the table. Now the lookup will display EDT123 and the description field from table123.

That is a simple way to create a lookup. Another way to create a lookup is to write a dynamic lookup on the table in which the data is coming from. This method will be a static method and will require the passing of arguments – typically the formstringcontrol that is to be the point of lookup. I prefer this method and use it often.

This a very simple example of a static lookup from a table



static void lookupTruckLoadIdEndingInv(FormStringControl  _ctrl)
{
    SysTableLookup          sysTableLookup  = SysTableLookup::newParameters(tablenum(WfsRMTruckLoadStatus), _ctrl);
    Query                   query           = new Query();
    QueryBuildRange         qbr;
    ;

    query.addDataSource(tablenum(WfsRMTruckLoadStatus));

    sysTableLookup.addLookupfield(fieldnum(WfsRMTruckLoadStatus, truckLoadId ));

    query.dataSourceTable(tablenum(WfsRMTruckLoadStatus)).addRange(fieldnum(WfsRMTruckLoadStatus,retTransferred)).value(SysQuery::value(NoYes::No));

    sysTableLookup.parmQuery(query);
    sysTableLookup.performFormLookup();
}

Joins can be peformed as well to pull back the desired data so you are not limited to querying on one table to return the proper data back to your lookup

static void lookupSettledTruckLoadIdCashier(FormStringControl  _ctrl)
{
    SysTableLookup          sysTableLookup  = SysTableLookup::newParameters(tablenum(WfsRMTruckLoadHeader), _ctrl);
    Query                   query           = new Query();
    QueryBuildRange         qbr;
    queryBuildDataSource    qbdsTruckLoadStatus,qbdsTruckLoadHeader,qbdsTenderSlipHeader;
    ;

    qbdsTruckLoadHeader = query.addDataSource(tablenum(WfsRMTruckLoadHeader));

    qbdsTruckLoadStatus         = qbdsTruckLoadHeader.addDataSource(tablenum(WfsRMTruckLoadStatus));
    qbdsTruckLoadStatus.relations(true);

    qbdsTruckLoadStatus.addRange(fieldnum(WfsRMTruckLoadStatus,settled)).value(enum2str(NoYes::No));
    qbdsTruckLoadStatus.addRange(fieldnum(WfsRMTruckLoadStatus,HHTruckLoadIdEnded)).value(enum2str(NoYes::Yes));
    qbdsTruckLoadStatus.addRange(fieldnum(WfsRMTruckLoadStatus,RetTransferred)).value(enum2str(NoYes::Yes));

    qbdsTenderSlipHeader         = qbdsTruckLoadStatus.addDataSource(tablenum(wfsRMTenderSlipHeader));
    //qbdsTenderSlipHeader.relations(true);
    qbdsTenderSlipHeader.addLink(fieldnum(WfsRMTruckLoadStatus, truckLoadId),fieldnum(wfsRMTenderSlipHeader, truckLoadId));
    qbdsTenderSlipHeader.joinMode(joinMode::NoExistsJoin);

    sysTableLookup.addLookupfield(fieldnum(WfsRMTruckLoadHeader, truckLoadId));
    sysTableLookup.addLookupfield(fieldnum(WfsRMTruckLoadHeader, routeId));
    sysTableLookup.parmQuery(query);
    sysTableLookup.performFormLookup();
}





Another way is to create an actual form and call it in a method on the table. You will still need to pass in the formstringcontrol object but in this case you will be calling an actual existing form that you have created. Now why do this? Well one reason may be that you want to be able to filter on a specific field in the lookup that maybe you could not on a typical lookup or maybe you need to add a field to the lookup that would otherwise not be possible like you can add a display method to a lookup but maybe you want to see the field referenced in the display method and have the ability to sort on the field or filter on the field. For example, like DirPartyTable.Name. Sure, you can access it using a display method but maybe you want to see it in your lookup and be able to filter on it.
So you will create a form and call it like a lookup so you can have all the the filtering of a standard form

public client static void WfsRMlookupEmplIdCashier(Object _ctrl)
{
    Args        args;
    FormRun     formRun;
    ;

    args = new Args();
    args.name(formstr(WfsRMEmplIdLookupCashier));
    args.caller(_ctrl);
    formRun = classfactory.formRunClass(args);
    formRun.init();
    _ctrl.performFormLookup(formRun);
}

The standard lookups present in AX like the item number lookup and the customer lookup are very interesting in that you only see one field on the relation but no fields in the autolookup. In these cases the lookup fields are coming from the standard indexes on the table. Take note of what you see in the itemId lookup when unchanged and then reference the indexes coincidence not really. this can apply to any new lookup you create as well.
You can also override the lookup on the datasource - field of a form or an actual field string edit control on a form and perform a lookup
Form design object

public void lookup()
{

    SysTableLookup        sysTableLookup;
    Query                 query=new Query();
    QueryBuildDataSource  qbds;

    ;
    sysTableLookup=SysTableLookup::newParameters(tablenum(Dimensions),this);

    sysTableLookup.addLookupfield(fieldnum(Dimensions,Num));
    sysTableLookup.addLookupfield(fieldnum(Dimensions,Description));

    qbds = query.addDataSource(tablenum(Dimensions));

    qbds.addRange(fieldnum(Dimensions, DimensionCode)).value(queryValue(COSAllowedDimensions::getAllowedDimensionValue(sysDim)));

    sysTableLookup.parmQuery(query);
    sysTableLookup.performFormLookup();
}
//Lookup from a field on the form data source
public void lookup(FormControl _formControl, str _filterStr)
{
    Args    args;
    FormRun formRun;
    SysTableLookup      sysTableLookup = sysTableLookup::newParameters(tablenum(InventTable),_formControl);
    Query               query = new Query();
    QueryBuildDataSource     queryBuildDataSource;
    QueryBuildRange     queryBuildRange;
    ;
    sysTableLookup.addLookupfield(fieldnum(InventTable,ItemID));
    sysTableLookup.addLookupfield(fieldnum(InventTable,ItemName));
    sysTableLookup.addLookupfield(fieldnum(InventTable,ItemGroupID));
    sysTableLookup.addLookupfield(fieldnum(InventTable,NameAlias));
    sysTableLookup.addLookupfield(fieldnum(InventTable,ItemType));
    sysTableLookup.addLookupfield(fieldnum(InventTable,DimGroupID));

    queryBuildDataSource = query.addDataSource(tablenum(Inventtable));
    queryBuildRange = queryBuildDataSource.addRange(fieldnum(InventTable,ItemGroupID));
    //FGL, FGR, Returns
    queryBuildRange.value('xxx');

    queryBuildRange = queryBuildDataSource.addRange(fieldnum(InventTable,ItemGroupID));
    queryBuildRange.value('yyy');

    queryBuildRange = queryBuildDataSource.addRange(fieldnum(InventTable,ItemGroupID));
    queryBuildRange.value('Returns');

    sysTableLookup.parmQuery(query);
    sysTableLookup.performFormLookup();

}
-Harry

February 28, 2013

Dynamics AX – Passing parameters between object – What is args??

Hi Friends,

ARGS is your friend in the world of AX (me also :) ). It allows you to pass records, the calling locations (form, report, query etc) , ENUMS and the list goes on!  
Simple declaration of args

Args  args = new Args();

Now lets try passing args an record.

select firstonly custTable where custTable.AccountNum == ‘XXXX’
if(custTable)
{
args.record(custTable);
}

Now lets view a snippet of code that passes in a record and runs a report using the record passed in. 
I- Create an instance of the report run class.
Create a new Args instance to hold all of this information. 
Pass the name of the report.
Instantiate the report run object and call the init and and run methods of the report.

II- Next override the init method of the report and put a condition that checks to see if a record was passed to the report from the args object. If so do not allow the user to be interactive with the report and sent the report straight to the screen.

III- Set a report variable eHeader to the record that was passed to the report. If there is no calling record to the report meaning the report is being launched from a menu or elsewhere besides a place with a calling record then allow interaction of the report query for the users to select the range criteria they want to use.

IV- Then override the fetch method and keep the super in place to allow the standard query to run however before the super use a condition to determine if a record has been passed into the report. If so then set a query of a key field to the a field from the record passed in.

V- You can use args to do the same with forms as well
You can pass in objects such as maps to run reports I have done this as well and I find it very helpful and useful

void printPickList(wfsEMPickListHeader  wfsEMPickListHeader)
{
    Args                    args = new args();
    ReportRun               reportRun;
    ;

    args.name(reportStr(wfsEMExportPickList));
    args.caller(this);
    args.record(wfsEMPickListHeader);

    reportRun = classfactory.reportRunClass(args);
    reportRun.init();

    reportRun.run();
}

public void init()
{
    super();
    if(element.args().record())
    {
        this.report().interactive(false);
        this.query().interactive(false);
        this.printJobSettings().preferredTarget(PrintMedium::Screen);
        eHeader = element.args().record();

    }
    else
    {
        this.report().interactive(true);
        this.query().interactive(true);
    }
}

public boolean fetch()
{
    boolean ret;
    if(element.args().record())
    {
        element.query().dataSourceTable(tablenum(wfsEMPickListHeader)).
       addRange(fieldnum(wfsEMPickListHeader,PickListId)).value(eHeader.PickListId);
    }
    ret = super();

    return ret;
}

void wfsRMRunManualTruckLoadIdForm()
{
    wfsWhseUser    wfsWhseUser;
    FormRun        formRun;
    Args           args = new Args();
    boolean        ret = false;
    ;
    args.record(this);
    formRun = new MenuFunction(menuitemdisplaystr(wfsManualTruckLoadSelection),
    MenuItemType::Display).create(args);
    formRun.run();
    formRun.wait();
}

-Harry

February 11, 2013

How to pass values between form and report

How to pass values between form and report

Here is for example the code of the button that calls the report:

void clicked ()
{
    Args     args;
    ReportRun          reportRun;
    ;
    super();
    args = new Args();
    args.name(Reportstr(HistoryHolidays));
    args.parm( LogId  );
    reportRun = classfactory.reportRunClass(args);
    reportRun.init();
    reportRun.run();
    reportRun.wait();
    args.parmObject( args );
}

in the init method of your report try this:

public void init()
{
    if( element.args() )
    {
        logId =  element.args().parm();
    }
     super();
}

then you can use this parameter in your report form example: 

public void executeSection()
{
    ;
    if  ( employee_1.LogId == logId)
    {
        emplId = employee_1.empId;
        super();
    }
    if ( logid == "1")
    {
        emplId = DropHoliday_1.EmpId;
        super();
    }
}

You can use this logic in your code for many purpose.

-Harry
 

November 07, 2012

Finding all data sources in a form through Job

Finding all data sources in a form through code

Hi ,
Here is small trick to find the datasource in form. Open job node , and a new job and copy paste following code over there,.....

static void AllDataSourcesInForm(Args _args)
{
    Args args = new Args();
    FormRun fr;
    FormBuildDataSource formBuildDataSource;
    counter i;
    ;
    args.name("CustTable");   // its your FORM name
    fr = ClassFactory.formRunClass(args);
    for(i=1 ; i<=fr.form().dataSourceCount();i++)
    {
        formBuildDataSource = fr.form().dataSource(i);
        info(new DictTable(formBuildDataSource.table()).name());
    }
}



When you run this job you get all data source which is used in CustTable Form




















- Harry

August 04, 2012

How to update multiple rows at backend and refresh the UI?


Update multiple rows at backend and refresh the UI at the same time.


Hi friends,
           
              Some times we need to update multiple rows in grid (Form) and the same time need to refresh the user interface also. 
For example:-
In a form grid there is a check box that is for  xyzValue = Yes or No. all the selected records should be update when user press a button. In following image we are going to post all selected reords and at the same time we update all selected rows in back end as well as refresh the UI also.



    to do this write following code in your click method of post button.

void clicked()
{
    Ax_dataSource                                  _ Ax_dataSource  ;   // your data source Table
    ; 
    ttsbegin;
    while select forupdate   _ Ax_dataSource where   _ Ax_dataSource .Status == AllOpenPosted::Open
                                           &&   _ Ax_dataSource .checkBox == NoYes::Yes
    {
             // write here your required updation  after posting
          _ Ax_dataSource .Status    = AllOpenPosted::Posted;     
          _ Ax_dataSource .checkBox  = NoYes::No;                 
          _ Ax_dataSource .update();
        
    }
    ttscommit;
     Ax_dataSource _ds.refresh();        
     Ax_dataSource _ds .reread();
     Ax_dataSource _ds .research();
   super();
}

-Harry

July 26, 2012

How to split a Form in two window

hi Friends,
WE a going to create a new form and want to show this form in two interrelated windows, like the following form
Untitled
on the basis of the header the line level information will update,
so for get this type of design in your form you have to write three methods in from design.
1.
int mouseDown(int x, int y, int button, boolean ctrl, boolean shift)
{
    int ret;
    ret = super(x, y, button, ctrl, shift);
    return _formSplitterVertical.mouseDown(x, y, button, ctrl, shift);
}

2.
int mouseMove(int x, int y, int button, boolean ctrl, boolean shift)
{
    int ret;
    ret = super(x, y, button, ctrl, shift);
    return _formSplitterVertical.mouseMove(x,y,button,ctrl,shift);
}

3.
int mouseUp(int x, int y, int button, boolean ctrl, boolean shift)
{
    int ret;
    ret = super(x, y, button, ctrl, shift);
    return _formSplitterVertical.mouseUp(x, y, button, ctrl, shift);
}

after adding these three methods in your form design it will spilt  into two windows, now write your code for validation what ever is your requirement.

- Harry

July 17, 2012

Simple Dialog Box in Ax 2009

Simple Dialog Box Example in Ax 2009


Hi Friends ,
Today we are tring to develop a  simple DialogBox .
try to following code


static void Simple_Dialog(Args _args)
{
dialog dlg;
dialogGroup dlgGroup;
dialogField dlgField;
;
dlg = new dialog("Simple Dialog");
dlgGroup = dlg.addGroup("Customer");
dlgField = dlg.addField(TypeID(custAccount),"Account
Number");
if (dlg.run())
{
print dlgField.value();
pause;
}
}


-Harry

Sample union query from AX 2009


Sample union query from AX 2009

Hi friends;

Queries build with the Query classes now supports unions, meaning that you can combine the result from several tables into one result set. The results you want to combine from the different tables must be structured the same way for all tables.

You could for example create a query combining CustTable and VendTable. This would be particularly useful if you need to present for example a lookup form showing both customers and vendors in the same grid. In earlier version you’d have to push customer and vendor data to a temporary table before being able to present the combined data in one grid.

Here is an example on how to build and use a union query from X++:

static void union(Args _args)
{
    Query                query;
    QueryBuildDataSource qbdsCustTable;
    QueryBuildDataSource qbdsVendTable;
    QueryRun             queryRun;
    CustTable            custVendTable;
    Map                  mapTableBranches = new Map(types::Integer, typeId2Type(typeId(TableId)));
    SysDictTable         dictTable;
    ;



    // The map is used to match the UnionBranchID with a table id
    mapTableBranches.insert(1, tableNum(CustTable));
    mapTableBranches.insert(2, tableNum(VendTable));


    query = new Query();
    query.queryType(QueryType::Union);


    qbdsCustTable = query.addDataSource(tableNum(CustTable));
    qbdsCustTable.unionType(UnionType::UnionAll); // Include duplicate records
    qbdsCustTable.fields().dynamic(false);
    qbdsCustTable.fields().clearFieldList();
    qbdsCustTable.fields().addField(fieldNum(CustTable, AccountNum));
    qbdsCustTable.fields().addField(fieldNum(CustTable, Name));


    qbdsVendTable = query.addDataSource(tableNum(Vendtable));
    qbdsVendTable.unionType(UnionType::UnionAll); // Include duplicate records
    qbdsVendTable.fields().dynamic(false);
    qbdsVendTable.fields().clearFieldList();
    qbdsVendTable.fields().addField(fieldNum(VendTable, AccountNum));
    qbdsVendTable.fields().addField(fieldNum(VendTable, Name));


    queryRun = new QueryRun(query);
    queryRun.prompt();

    while (queryRun.next()) 
    {
        custVendTable = queryRun.getNo(1);
        dictTable = SysDictTable::newTableId(mapTableBranches.lookup(custVendTable.unionAllBranchId)); 

        info (strFmt("%1 %2 (%3)", custVendTable.AccountNum,
                                   custVendTable.Name,
                                   dictTable.name()));
    }
}



- Harry

April 23, 2012

LookUp On forms

Hi Folks,

Here I am sharing a method to how to write x++ code for a custom lookup control on a form. Try the following method in your code.

-Harry

April 14, 2012

How To Create Forms in Enterprise Portal

ABSTRACT:- This article demonstrates how to create basic forms in Enterprise Portal. Create a DataSet

1. Open Microsoft Dynamics AX.
2. Open the AOT.
3. Right-click on the Data Sets node and choose New Data Set.
4. Right-click on the newly added data set and choose Properties.
5. In the property sheet rename the new Data Set to SampleCustomers.
6. Expand SampleCustomers.
7. Right-click the Data Sources node and choose New Data Source.
8. Right-click the new Data Source and choose Properties.
9. In the property sheet set the Table property to CustTable.
10. In the property sheet set the Name property to CustTable.
11. In the property sheet set the InsertIfEmpty property to No.

  • Create a Web Project
1. Open Microsoft Visual Studio 2008.
2. Under the File menu choose New and then Web Site.
3. Choose Visual C# as the Language – note that only C# is supported.
4. Choose Dynamics AX Web Project as the template.
5. Enter SampleBasicForm as the project name.
6. Click OK when finished.
  • Create a User Control and Add it to the AOT
1. In Visual Studio add a new File under File then New File.
2. Choose Visual C# as the language.
3. Choose Dynamics AX User Control under the My Templates Section.
4. Enter SampleBasicForm.ascx as the name.
5. Click Add when finished.
6. In the Solution Explorer, right-click on the new user control, SampleBasicForm.ascx, and select Add to AOT.

  • Add a Form to Your User Control
Forms in Enterprise Portal are used to display and edit record information. They consist of three different controls, an AxDataSource, an AxForm, and an AxGroup. The AxDataSource is used to interact with data. The AxForm is a container for the form entity. The AxGroup will reference and display fields
from the data. The specific record information to display is retrieved from the external context (information passed through the URL).

1. In Visual Studio in the Solution Explorer, right-click the user control and select View Designer.
2. Locate the Microsoft Visual Studio 2008 Toolbox under View then Toolbox.
3. Find and expand the Dynamics AX section.
4. Drag-and-drop an AxDataSource onto the design.
5. Click on the arrow in the upper right-hand corner of the AxDataSource and set the DataSet Name    property to SampleCustomers. This can also be done through the properties pane.
6. Right-click on the AxDataSource and choose Properties.
7. Rename the new AxDataSource to Customers_DS by changing the (ID) property to Customers_DS.
8. Find the AxForm control in the toolbox under View and then Toolbox.
9. Drag-and-drop the AxForm onto the design.
10. Right-click on the AxForm and choose Properties.
11. Rename the AxForm’s ID to SampleCustomers by changing the (ID) property.
12. Set the DataSourceID property to Customers_DS.
13. Set the DataMember property to CustTable_Current.
14. Find the AxGroup control in the toolbox under View and then Toolbox.
15. Drag-and-drop the AxGroup onto the AxForm.
16. Right-click on the AxGroup and choose Properties.
17. In the Fields property for the AxGroup, click the … icon.
18. Add AccountNum, Name and Address from Available Fields by double-clicking or selecting each item and clicking Add Field.
19. Press OK to save.
20. Click the Save icon on the Visual Studio toolbar to save your project.

  • Testing Your User Control To Test Through Microsoft SharePoint Services
1. Navigate to your Microsoft Dynamics AX Enterprise Portal web site.
2. Click on Site Actions and select Create.
3. Click on the Web Part Page link.
4. Choose a Name, Template, and the Document Library Enterprise Portal.
5. Click the Create button.
6. If the page is not in Edit Mode, click Site Actions and select Edit.
7. In one of the web page’s sections click the Add a Web Part bar.
8. Check Dynamics User Control Web Part and select Add.
9. On the new web part, click edit and select Modify Shared Web Part.
10. Set the Managed content item property to your user control, SampleBasicForm.
11. Click OK.
12. Under the Site Actions menu click the link Exit Edit Mode.
13. Minimize the web browser.
14. Locate and open the web.config file for the SharePoint site. (ex: C:\Inetpub\wwwroot\wss\VirtualDirectories\80)
15. Locate the compilation section and set the debug property to true


16. Open your Microsoft Visual Studio 2008 SampleBasicForm project.
17. From the menu choose Debug and select Attach to Process.
18. Select the w3wp.exe process for the SharePoint site and click Attach.
19. In Visual Studio’s Solution Explorer right-click your control and choose View Code.
20. Add breakpoints to the code where needed.
21. Maximize the open web browser and refresh the SharePoint site.
22. When finished debugging, set the debug attribute in the web.config file back to false.

  • To Test Through Microsoft Visual Studio 2008
1. In Visual Studio in the Solution Explorer, right-click the project node and select Import Style Sheets.
2. In the Solution Explorer, right-click the AxWebPartPage.aspx page and select View Designer.
3. In the design under Body, locate dynamics:AxUserControlWebPart1. It is the second box containing Untitled under the Body.
4. Right-click dynamics:AxUserControlWebPart1 and choose Properties.
5. Set the Dynamics AX Managed Web Content Item property to your user control, SampleBasicForm.
6. Save your control.
7. In the Solution Explorer right-click your SampleBasicForm control and choose View Code.
8. Add breakpoints to the code where needed.
9. In the Solution Explorer, click on the AxWebPartPage.aspx so it is selected.
10. Click the green arrow on the toolbar to build and run the solution.


-Harry