Tuesday, February 7, 2012

default index for a table in AX / X++

Question: What is the default index for a table ?

Microsoft Dynamics AX requires a unique index on each table. If there are no indexes on a table or all the indexes are disabled, a system index is automatically created. The system index is created on the RecId and DataAreaId fields if the DataAreaId field exists. Otherwise, the system index is created on the RecId field. You can see system indexes in the database, but they aren't visible in the AOT.

get values of base enums using code in x++

Question: How to get  values of base enums using code in x++

static void getEnumValues(Args _args)
    EnumId   enumId   = enumNum(LedgerDimensionType);
    DictEnum dictEnum = new DictEnum(enumId);
    int      count  = dictEnum.values();
    int      counter 

    for(counter = 0; counter < count; counter ++)
        // You can use the number of method exposed by DictEnum class
// dictEnum.name(counter)
// dictEnum.index2Value(counter)
// dictEnum.index2Symbol(counter)             
// dictEnum.index2Label(counter)

List in X++ / Dynamics AX

List is a type of data structure and collections, it can contain unlimited items, in x++, list can be created of several Types(specified in the Types base enum), the type must be specified on the declaration and it cannot be changed after the initialization.

There are some classes exists to enumerated and iterate the list object. ListIterator object has methods that can insert and deleted items from list,  ListEnumeration cannot modify the list content


    List           myList       = new List(Types::Integer);
    List           myListString = new List(Types::String);
    ListIterator   literator  

    // add the element at the end of the list

    // add the element at the start of the list


    myListString.addEnd ("Second");

    myListString.addStart ("First"); 

    // If you want to insert the data at some specific index, then you need to make use of the listIterator class 

    // Iterator performs a midpoint 

    // insert at current position.

    literator = new ListIterator(myListString);

    while (literator.more())
        // can provide some condition, i.e. if check etc
        if (literator.value() == "First")
            listIterator.insert ("Between first and second");

Sunday, February 5, 2012

How to implement Number sequence in AX 2012

I have read an article for creating number sequence in existing and new module of AX 2012, written by a friend Amir nazim also lso there is a white paper published by microsoft for the developers.

Amir's article link

Edit Methods versus Display Methods

Display Methods:

In some scenarios, we need to display some values derived from other columns and those are not associated directly with the database, like Amount fields (Unit*Price). In that case there are display methods that perform that functionality.
 display Amount amount()
    AmountMST  amount; 

    amount = this.unitprice * this.quantity; 

    return amount;

Edit Methods:
In AX 2009, when reference controls were not available, in table if there is a relation created on the basis of recId i.e. there is a child table and it contains the record Id of the parent Table. When that child table binds to form, (to display and select the user friendly information from the parent table, lookup controls were used). The record Id of the user friendly value is saved on the table with the help of the edit methods.
To give an example of an edit method, we will create a new field in the CarTable to hold the mileage of the car and have an edit method in RentalTable that enables the users to be in the RentalTable form and still edit the field in CarTable.

We'll create an extended data type of type integer for the new field and call it Mileage. Then we'll dd the field to the CarTable.

The edit method in RentalTable will then look like this: 

//This material is copyright and is licensed for the sole use by ALESSANDRO CAROLLO on 18th December, Chapter 4 [ 105 ]

edit Mileage mileage(boolean _set, Mileage value)
    CarTable carTable;
    Mileage  ret;

    // find the car records from the car table with update = true
    carTable = CarTable::find(this.CarId, _set);

    if (_set)

        carTable.Mileage = value;

        ret = carTable.Mileage;

    return ret;

Saturday, February 4, 2012

How to use the regular expression to validate the name in X++ AX

How to use the regular expression to validate the name

public bool validateName(str _name)

    System.Text.RegularExpressions.Match regExMatch;
    bool                                 isValid;

    // verify that Name doesn’t contain bad special character like <>:”/\|?*
    // other characters used in the regular expression are part of regex syntax. 

    regExMatch = System.Text.RegularExpressions.Regex::Match(_name, @’^[^<>:"/\\|?*]*$);
    // return true if name matches the criteria otherwise return false
    isValid = regExMatch.get_Success();   

    return isValid;

Data model of the dimension in AX 2012

In this post I will describes the data model of the ledger dimensions and we will a scenarios that how the data is stored on the these tables

Scenario: How an offset account (10110-D10-CC2) in the Lines Journal saved in the dimension.

Segmented control works with the DimensionStorage class to create the combination
So; we break apart the combination into each structure[10110 - D1] [CC2}. We first save the Account Structure portion of the combination.  Then we save the Account/Advanced Rule structure portion (as there could be multiples added thru multiple rules). In the end, this is what that combination will look like across all 4 tables shown in the combination storage block in the Data model bound to the LedgerDimension.
1.       An Segmented entry control will look like this
2.       As account structure configure there are 2 segments that must be filled.
3.       Type 10110 and tabit looks like this:10110 -
4.       Type D1 in the second segment and tab
5.       As tab press we pick up the fact that a rule is attached and a 3rd dimension must be added to the combinationso it looks like this:10110 - D1 -
6.       Now the user enters CC2and tabs from the control 10110 - D1 - CC2 
 DisplayValue:   "10110 - D1 – CC2"
 RecId: 400
 DimensionAttributeValueCombination: 400
 DimensionAttributeValueGroup: 500
 RecID: 201

DimensionAttributeValueCombination: 400
DimensionAttributeValueGroup: 501
RecID: 202
  DimensionHierarchy: AccountStructure(MA+DEPT)
  RecID: 500
  DimensionHierarchy: AdavancedRule (CC)
  RecID: 501
                DimensionAttributeValueGroup: 500
                Ordinal: 1
                RecId: 601

                DimensionAttributeValueGroup: 500
                Ordinal: 2
                RecId: 602

                DimensionAttributeValueGroup: 501
                Ordinal: 1
                RecId: 602
To insert: [10110 - D1] [CC2] we need to insert above all records as summarized below.
·         1 record in DAVC
2 Records in DAVGC (to link the full combination to each sub-group)
·         2 records in DAVG (one for each grouping)
·         3 records in DALV (one for each segment)

configure Account structure and advanced rules in ax 2012

This post is covering the following topics
·         Account Structure Configuration
·         Account Structure Configuration effect on GL
·         Advanced Rule application on Account Structure
·         Advanced rule effect on GL 

and the target audience includes AX Administrator, functional consultant and developers/testers.

Configure Account Structure

GL > Setup > chart of accounts > chart of accounts          

To Configure Account Structure Click on the configure account structure as shown in the above snap shot.

Click on Activate button to active this Account structure,   Click Yes to Activate this Account structure

Effect on GL

GL > Journal > General Journal  

  Click on Lines Button ->  Select the Offset Account from account structure(MA +Cost center)

Configure Advanced Rules

GL > Setup > chart of accounts > Advanced rule structure

GL > Setup > chart of accounts > Configure Account structure

Click Advanced rule to open below Advanced rule form

Advanced Rules Effect on GL
GL > Journal > General Journal  Click on Lines Button ->  Select the Offset Account from account structure + Advanced rule

As we have created an advanced rule for main account 50110 i.e User must have to select department if he selects main account 50110

Friday, February 3, 2012

Role based Security in AX

There is a new pattern introduced in the new version of Dynamics AX (AX6.0/2012), for the security of the forms/tables etc. which is called RBS.

In Microsoft Dynamics AX, role-based security is aligned with the structure of the business. Users are assigned to security roles based on their responsibilities in the organization and their participation in business processes. The administrator grants access to the duties that users in a role perform, not to the program elements that users must use.


Let’s take a looks at the data models of the Security framework

Contains list of roles
Contains the user to role mappings 
(System Administration à Users à User)
Contains the list of duties and privileges
Contains the duty to privilege mappings
(AOTàSecurityà Dutiesà Privileges)
contains the list of role to duty mappings
(AOTàSecurityà RolesàDuties)

Some Examples

///////////////// Code in X++ /////////////////////////////

SecurityRole            securityRole;
SecurityUserRole        securityUserRole;
SecurityTask            securityTask;
SecuritySubTask         securitySubTask;
SecurityRoleTaskGrant   securityRoleTaskGrant;
// 1. How to the find record ID of the privilege
select firstOnly RecId from securityTask
    where securityTask.AotName  == #SecurityTask
        && securityTask.Type    == SecurityTaskType::Privilege;
// 2. How to find the record ID of the security role of the currently logged-in user aving the specified security role
select firstonly RecId from securityRole
    exists join securityUserRole
    where securityRole.RecId     == securityUserRole.SecurityRole
        && securityRole.AotName  == #SecurityRole
        && securityUserRole.User == curUserId();

// 3. How to the find all the duties containing the specified privilege (security Duty)?
select SecurityTask from securitySubTask
    where securitySubTask.SecuritySubTask == securityTask.RecId;

// 4. How to check whether the privilege is directly associated with role
select firstOnly RecId from securityRoleTaskGrant
    where securityRoleTaskGrant.SecurityTask  == securityTask.RecId
        && securityRoleTaskGrant.SecurityRole == securityRole.RecId;

// 5. How to check whether the privilege is associated with role through duty
 select RecId from securityRoleTaskGrant
    exists join securitySubTask
    where securityRoleTaskGrant.SecurityTask == securitySubTask.SecurityTask
            && securityRoleTaskGrant.SecurityRole == securityRole.RecId;
 ///////////////// Code in X++ /////////////////////////////