Friday, October 17, 2014

Dialog Validation example

Dialog Validation example

In this example we fill the one dialog Field remain Fields going to non edit mode

STEP1:- Create new class and create classDeclaration

class CustSelect extends RunBase
{
    DialogField fieldAccount,fieldName,
                fieldGroup,fieldCurrecncy,
                fieldPaymTermId,fieldPaymMOde;
}

STEP2:- Create Pack Metod


public container pack()

{
    return  conNull();

}


STEP:-3  Create Unpack Method

public boolean unpack (container _packedClass)

{
    return true;
}

STEP:-4 Create Dialog method

protected Object dialog()
{

    Dialog dialog;
    DialogGroup groupCustomer;
    DialogGroup groupPayment;
    dialog = super();
    dialog.caption("Customer information");
    //
    dialog.allowUpdateOnSelectCtrl(true);
    //
    fieldAccount = dialog.addField(extendedTypeStr(CustAccount),"Customer account");
    fieldName = dialog.addField(extendedTypeStr(CustName));

   
    fieldName.enabled(false);

    dialog.addTabPage("Details");

    groupCustomer = dialog.addgroup("Setup");

    fieldGroup = dialog.addField(extendedTypeStr(CustGroupId));
    fieldCurrecncy = dialog.addField(extendedTypeStr(CurrencyCode));
    
    fieldGroup.enabled(false);
    fieldCurrecncy.enabled(false);

    groupPayment = dialog.addGroup("Payment");
    fieldPaymTermId = dialog.addField(extendedTypeStr(CustPaymTermId));
    fieldPaymMOde = dialog.addField(extendedTypeStr(CustPaymMode));
    
    fieldPaymTermId.enabled(false);
    fieldPaymMOde.enabled(false);

    return dialog;

}

STEP:-5 Create DialogSelectCtrl method

public void dialogSelectCtrl()
{
    CustTable custTable;

    custTable =custTable::find(fieldAccount.value());
    fieldName.value(custTable.name());
    fieldGroup.value(custTable.CustGroup);
    fieldCurrecncy.value(custTable.Currency);
    fieldPaymTermId.value(custTable.PaymTermId);
    fieldPaymTermId.value(custTable.PaymMode);

}


STEP6:- Create main method()



public static void main (Args _args)
{
    CustSelect custSelect = new CustSelect();
    if (custSelect.prompt())
    {
        custSelect.run();
    }
}

















CREATAING OF DIALOG AND IT HOLD ONE RECORD

CREATAING OF DIALOG  AND IT HOLD ONE RECORD

STEP-1 CREATE A NEW CLASS (CustCreate)  AND CREATE CLASS DECLARATION

class CustCreate extends RunBase
{
    DialogField fieldAccount,fieldName,fieldGroup,
                fieldCurrency,fieldPaymMode,
                fieldPaymTermId;
    CustAccount custAccount;
    CustName    custName;
    CustGroupId custGroupId;
    CurrencyCode currencyCode;
    CustPaymTermId paymTermId;
    CustPaymMode paymMode;


}


STEP 2:- Create pack method  in class
public container pack()
{
    return conNull();
}

STEP 3-  Create Unpack method
public boolean unpack(container _packedClass)
{
    return true;
}

STEP 4 :-  Create a Dialog method for dialog
protected Object dialog()
{
    Dialog dialog;
    DialogGroup groupCustomer;
    DialogGroup groupPayment;

    dialog = super();

    dialog.caption("Customer information");
    fieldAccount = dialog.addField(extendedTypeStr(CustVendAC),"Customer Account");
    fieldName = dialog.addField(extendedTypeStr(CustName));
    dialog.addTabPage("Details");
    groupCustomer = dialog.addGroup("Setup");
    fieldGroup     = dialog.addField(extendedTypeStr(custGroupId));
    fieldCurrency = dialog.addField(extendedTypeStr(currencyCode));
    groupPayment = dialog.addGroup("Payment");
    fieldPaymTermId = dialog.addField(extendedTypeStr(CustPaymTermId));
    fieldPaymMode = dialog.addField(extendedTypeStr(CustPaymMode));
    return dialog;


}

STEP 5 :-  Create GetFromDialog  Method

Public boolean getFromDialog()
{
    custAccount = fieldAccount.value();
    custName   = fieldName.value();
    custGroupId = fieldGroup.value();
    currencyCode = fieldCurrency.value();
    paymTermId = fieldPaymTermId.value();
    paymMode  = fieldPaymMode.value();
    return super();
}

STEP6:- Create Run method for dialog
public void run()
{
    info("you have entered customer information :");
    info(strFmt("Account : %1",custAccount));
    info(strFmt("Name : %1", custName));
    info(strFmt("Group: %1", custGroupId));
    info(strFmt("Currency: %1", currencyCode));
    info(strFmt("Terms of Payment: %1 ", paymTermId));
    info(strFmt("Method of Payment : %1", paymMode));
}


STEP7:- Create Main Method

public static void main (Args _args)
{
    CustCreate custCreate = new CustCreate();
    if (custCreate.prompt())
    {
        custCreate.run();
    }
}







Thursday, October 16, 2014

Merge Two Records In Ax 2012

Merge Two Records In Ax 2012

static void CookBookEX18(Args _args)
{
    ReasonTable reasonTableDelete;
    ReasonTable reasonTable;
    ;
 
    ttsBegin;
        select firstOnly forUpdate reasonTableDelete
            where reasonTableDelete.Reason == 'Counter';
        select firstOnly forUpdate reasonTable
            where reasonTable.Reason == 'Auction';
 
        reasonTableDelete.merge(reasonTable);
    reasonTable.doUpdate();
    reasonTableDelete.doDelete();
    ttsCommit;
}

Creating a Dynamics AX Table and Table variables

Creating a Dynamics AX Table and Table variables


While creating a new Micrsoft Dynamic Ax Table, it is very important that you initially consider how our new tables are going to be used. Because when the new tables are installed in a live application, and after the data has been entered to the tables, it will be more complex to redesign the tables.

If we want to add additional fields on an existing table, you might have chosen to create a new table with the required fields. And each time you need to access the new fields you will have to join the new table with the existing table. This can be frustrating, and slower, so it is very important to concentrate on the Design before creating tables.

Creating a table:

Let consider a table to store customer information is to be created.

1.       Create a new table by going to the Tables node in the AOT, right-click and chooseNew Table. A new table called "Table1" will be created. Open the property sheet and rename the table to "MyFirstTable".

2.      Expand the new table node so the nodes at the next level are visible. Open another instance of the AOT and go to Data Dictionary/Extended Data Types. Locate the extended data type AccountNum and drag the extended data type AccountNum to the Fields node of MyFirstTable.

3.      Locate the extended data types CustName, CustGroupId and CurrencyCode and then drag them all to the Fields node of MyTable.

4.      Save the table by pressing ctrl+s at the MyTable node. The table is now synchronized to the database and you have created your first table.
 
By using the table browser, you can now add records to MyTable.

 When creating a new record notice that the fields' custGroupId and currencyCode both have a lookup button and only values from the related lookup table can be chosen. This is because of the extended data types we used. This way, for these two fields we have created a relation to the tables CustGroup and Currency.

So now Without any coding you have already created a new table with relations !!


Table variables

Tables are declared in X++ like any other variable. To initiate a table variable with a value from the database select statements are used. You can also set a table variable equal to another as long as both tables variables are of the same type.

Example(1):

static void DataDic_OneCursor(Args _args)
{
CustTable custTable, newCustTable;
;
select firstonly custTable;
newCustTable = custTable;
}

In this example with the CustTable, only one cursor position will exist if one table variable is set to equal another. If one of the table variables is used to select another record, both table variables will point to the new record.

 
Example(2):

static void DataDic_TwoCursors(Args _args)
{
CustTable custTable, newCustTable;
;
select firstonly custTable;
newCustTable.data(custTable);
}
To have two separate cursors the method data() must be used. Now the table variable custTable and newCustTable will each have a cursor.

Document Handling In Ax 2012

Document Handling In Ax 2012

static void CookBookEx20(Args _args)
{
    DocuRef     docuRef;
    VendTable   vendTable;
    ;
    vendTable = vendTable::find('3001');
    docuRef.RefCompanyId    =   vendTable.dataAreaId;
    docuRef.RefTableId      =   vendTable.TableId;
    docuRef.RefRecId        =   vendTable.RecId;
    docuRef.TypeId          =   'Note';
    docuRef.Name            =   'Imported';
    docuRef.Notes           =   "This Vendor was Imported";
    docuRef.insert();
}

How to create normal table to temp table in Ax 2012

How to create normal table to temp table in Ax 2012

static void CookBookEX21(Args _args)
{
    CustTable custTable;
    ;
    custTable.setTmp(); // Here I'm setting the normal table as a Temp Table;
     custTable.AccountNum  = "23";
    custTable.Blocked = CustVendorBlocked::All;
    custTable.Party     =   12;
    custTable.doInsert();
    custTable.clear();
 
    custTable.AccountNum = "177";
    custTable.Blocked = CustVendorBlocked::Invoice;
    custTable.Party     =   1112;
    custTable.doInsert();
 
 
 
 
    while select custTable
    {
        info(strFmt("%1",custTable.AccountNum));
    }

}

Copying A Record In Ax 2012



Copying A Record In Ax 2012


This example for only for single company, for multiple company's we go for bufer2bufer()

static void CookBookEX22(Args _args)
{
    MainAccount             mainAccount1;
    MainAccount             mainAccount2;
    ;
   
    mainAccount1 = MainAccount::findByMainAccountId('211100');
    ttsBegin;
    mainAccount2.data(mainAccount1);
    mainAccount2.MainAccountId = '211102';
    if(!mainAccount2.validateWrite())
    {
        throw Exception::Error;
    }
    mainAccount2.insert();
    ttsCommit;
   
}

Query Example2 In Ax 2012

Query Example In Ax 2012

static void CookBookEx25(Args _args)
{
    Query                           query;
    QueryRun                        queryRun;
    QueryBuildDataSource            qbds1;
    QueryBuildDataSource            qbds2;
    QueryBuildRange                 qbr1;
    QueryBuildRange                 qbr2;
    ProjTable                       projTable;
    ;
 
    query = new Query();
    qbds1 = query.addDataSource(tableNum(projTable));
    qbds1.addSortField(fieldNum(projTable,Name),SortOrder::Ascending);
    qbr1 = qbds1.addRange(fieldNum(projTable,Type));
    qbr1.value(queryValue(projType::FixedPrice));
 
    qbr2 = qbds1.addRange(fieldNum(projTable,ProjId));
    qbr2.value(queryValue('2') + '*');
    qbds2 = qbds1.addDataSource(tableNum(ProjEmplTrans));
    qbds2.relations(true);
    qbds2.joinMode(JoinMode::ExistsJoin);
    queryRun = new QueryRun(query);
    while (queryRun.next())
    {
            projTable = queryRun.get(tableNum(ProjTable));
            info(strFmt(            "%1, %2, %3",
            projTable.ProjId,
            projTable.Name,
            projTable.Type));
    }
}

Query Ex 2 In Ax 2012

Query Ex 2 In Ax 2012

static void CustTableQueryEx(Args _args)
{
    CustTable               custTable;
    Query                   query;
    QueryBuildDataSource    qbds;
    QueryRun                queryRun;
    ;
 
    query = new Query();
    qbds =  query.addDataSource(tableNum(custTable));
    queryRun =  new QueryRun(query);
    while(queryRun.next())
    {
       custTable =  queryRun.get(tableNum(custTable));
        info(strFmt("%1 , %2 ",custTable.name(),custTable.AccountNum));
    }
 
}

Custom LookUp in Ax 2012

Custom LookUp in Ax 2012


Step 1): Create one table with 2 fields Like

              Id

              Name
Fill some data on this table.
Step 2) Create one form and go to designs add one String Edit Control.

Step 3) Go to the methods of stringedit control and override the Lookup Method

Step 4)

Copy and paste the Bellow code and press F5

public void lookup()
{
        SysTableLookup sysTableLookup; // systemclass to create //customlookup
        Query query;
        QueryBuildDataSource qbd;
        ;
        sysTableLookup = SysTableLookup::newParameters(tablenum(LookupTable),this);
           

        // Construct query on the table,
        // whose records you want to show as lookup.
        query = new Query();
        qbd = query.addDataSource(tablenum(LookupTable));
        //qbd.addRange(fieldnum(InventTable,ItemType)).value(SysQuery::value(enum2str(ItemType::Item)));

        // add the fields to the lookup list
        sysTableLookup.addLookupfield(fieldnum(LookupTable,Id));
        sysTableLookup.addLookupfield(fieldnum(LookupTable,Name));

        // pass the query as parameter
        // system will show the records in the lookup
        // as per your query
        sysTableLookup.parmQuery(query);
        sysTableLookup.performFormLookup();

}

Print All Enum Values In Ax 2012

Print All Enum Values In Ax 2012

static void EnumIteration(Args _args)
{
    DictEnum DEnum;
    int      i;
    ;
    DEnum = new DictEnum(enumName2Id("Weekdays")); // Here You can mention your Enum Val.
    for (i=0; i < DEnum.values(); i++)
    {
        print DEnum.index2Label(i);
    }
    pause;
 
}

Primary Elements of Microsoft Dynamics Ax Table

Primary Elements of Microsoft Dynamics Ax Table


Tables are the foundation objects in Microsoft Dynamics AX and store data used by the system. A table is made up of records (or rows) that contain information about a single entry in the table
Tables are located in AOT under the 
Data Dictionary\Tables node. Each table contains the following primary elements: 

·         Fields
·         Field Groups
·         Indexes
·         Relations
·         DeleteActions
·         Methods 

Fields:

The Fields node contains all the fields in the table. By specifying a field's data type, you define the type of data that can be stored in it

·         The best practice is to drag and drop either extended data types and base enums to create a new field.

·         If existing EDTs and Enums does not fulfill your needs, you should start creating new ones EDT/Enum before creating your fields.

·         One Important property to be defined is configuration key, as your fields will not be viewable for the application users if the related configuration key is disabled.

·         All fields should have an extended data type or a base type set in the properties.

·         A very powerful flexible feature of Axapta is by using EDTs/Enums, if you change a property value such as field length or alignment or Rename the EDT/Enum, it will locate all places in application where that EDT/Enum is used and will update them all accordingly.

·         Best practice states that all fields should start with lower case letters.

·         Few Common properties for fields are:
ü  Mandatory (yes/no)
ü  AllowEdit (yes/no)
ü  AllowEditOnCreate(yes/no)
ü  Visible (yes/no)

·         Container Fields: Fields of the base type container are often use for storing binary files like bitmaps, which is large in comparison to other fields. So we should be cautious of adding such fields to existing tables.
For example, Table CompanyInfo is a widely used table and if we add a large bitmap for the company logo it may affect the performance of the application.

·         System Fields: All tables have a set of system fields which are automatically added when creating a new Table.
The system fields are not listed in the AOT. You can get the list of system fields by checking the fields for the system table Common.
RecID: is a unique id for each and every record. And track of counter is done by Table SystemSequences.
The fields prefixed with Created* and modified* contain no value unless you set the properties with the corresponding name at the table property sheet.

 

System field
Table property
RecId
Always
RecVersion
Always
DataAreaId
SaveDataPerCompany = Yes
CreatedBy
CreatedBy = Yes
CreatedDate
CreatedDate = Yes
CreatedTime
CreatedTime = Yes
CreateTransactionId
CreateTransactionId = Yes
ModifiedBy
ModifiedBy = Yes
ModifiedDate
ModifiedDate = Yes
ModifiedTime
ModifiedTime = Yes
ModifiedTransactionId
ModifiedTransactionId = Yes

 
Fields Groups:

Field groups are objects that group together fields that logically belong together. 

·         Field groups are widely used when creating forms and reports. Instead of adding fields one by one to a design, you should add field groups.

·         If a field group is later changed, e,g, when adding a new field to a group, then the new field will automatically be available everywhere that specific field group is used.

·         Fields visible for the application users must be part of at least one field group. However in Morphix we can use fields which are not part of any field group.

Example (1):In the previous example the table MyFirstTable was created and fields were added. Now let’s add field groups to the previously created MyFirstTable.

  1. Locate the field group node AutoReport. Mark CustName, CustGroupID & CurrencyCode and drag the fields to the AutoReport node.
  2. Go to the field group node AutoLookup. Drag the fields accountNum and custName to the AutoLookup node.
  3. Create a new field group called “Identification” by right-clicking the Field Groupsnode and choose New Group. The name of the field group is set by using the property sheet. Add the field accountNum to the field group.
  4. Create a new field group called “Overview” and add all 4 fields to the field group.
  5. Finally, create a new field group called “Details” and add the fields custName, custGroupId and currencyCode.
  6. Save the table.
Output:  
 

You might wonder why so many field groups are needed for a few fields: AutoReport & AutoLookup are reserved field groups The other 3 field groups are used for grouping the fields on forms and reports.

AutoReport: fields in this are printed when selecting print icon from a form.
AutoLookup: fields in this are showed when pressing the lookup button.
Identification: should contain all fields which make up the Key fields of the table for unique identification.
Overview: fields for summarization of the table

Apart from Overview, all fields should be part of atleast one field group for logical grouping of all fields. For MyFirstTable, Identification & Details are the logical grouping of fields.


 
Indexes:

An index is a table-specific database structure that speeds the retrieval of rows from the table. Indexes are used to improve the performance of data retrieval and sometimes to ensure the existence of unique records

·         Any table must have atleast  one index.

·         Keeping in mind the performance issues because of improper use of indexes, the best practice is, Main tables and group tables like the customer table and customer group table should have unique indexes, Whereas, tables with a lot of records like transaction tables should not have a unique index.

·         Each time data is changed in the table, database will update the indexes for that table.

·         Tables with a unique index should have the properties PrimaryIndex and ClusterIndex set.

Creation of Indexes:Lets add indexes to MyFirstTable. We will create two indexes.

  1. Locate the node Indexes in MyFirstTable. Right-click and choose New Index to create an index. Use the property sheet to name the index “AccountIdx”.
    Drag the field accounNum to the index.
  2. Go to the property sheet for AccountIdx and set the property AllowDuplicates to “No”.
  3. Create a new index named GroupIdx.
    Add the fields custGroupId and accountNum in this order.
  4. Save the table.

Relations:

Relations will connect your tables and let MorphX know how the data model looks like. To define the relationship between two tables that contain related data

·         One good example to understand relations is, If you click the Transactions button in the customers form you will open the customer transaction form. . Try selecting another customer in the customer from. Notice that the customer transaction form will automatically be refreshed with the customer transactions for the selected customer.

·         Table relations are most commonly used in form fields to enable the look-up of information in another table. So that Lookup button can be used.

·         An Extended data type can also have a relation to a table. However, if a table has relations on the same field, the table relation will overrule an extended data type relation.

Example (2): Adding relations
Let’s create a relation in CustTable relating customer account to an account in MyFirstTable.


1.       Find the table CustTable and go to the Fields node. Add a new field using the extended data type AccountNum.
Rename the field to ‘altCustAccountNum’.
Also update the label to ‘altCustAccountNum’
2.      Go to the field group Delivery in CustTable and add the field altCustAccountNum.
3.      Locate the node Relations in CustTable. Right-click the node Relations and choose New Relation.
Rename the new relation to ‘MyFirstTable’ using the property sheet.
Go to the property sheet and add ‘MyFirstTable’ for property Table.
4.      Right-click the new relation MyFirstTable and choose Normal. Go to the property sheet and select altCustAccountNum as Field and an accountNum as RelatedField.
5.      Save the table.

Output:

 


Here, we create a new field ‘altCustAccountNum’ and related to MyFirstTable. As the new fields is part of Group Delivery, if open CustTable > Setup tabpage > Delivery group, you will find a new field. Notice that the field also has a lookup button and shows the data from MyFirstTable because we related to it and can only select data from the same (throws error if we give someother data).

All of the fields part of a primary index must be added as normal relation fields. In our example, We only have one field in the primary index, only one field is needed. 
Besides a normal relation, two other relation types exist, field fixed and related field fixed. These are used to narrow the choices of a relation and are often used for filtering data depending on the  value of an enum, or even defining which table to relate. Good example for this are relations for LedgerTable, CustTable and VendTable in the table LedgerJournalTrans

For more details about Types of relations - Go here
 
DeleteActions:

The DeleteAction element is used to maintain database consistency when a record is deleted. And the delete action values are None, Cascade, Restricted, and Cascade + Restricted.

·         Delete actions use relations to figure out whether to delete or prevent deleting related data. So if there is no relation, delete action will have no effect.

·         None: If you delete a record from a table, it will get deleted without any verifications.

·         Cascade: If you have a parent child relation. We can have deleteActions to ensure that data record from child table is deleted whenever the related parent data record is deleted.

·         Restricted: By using this relation we can restrict the deletion of existing records. Typically, transactions for a customer will prevent the customer to be deleted, whereas information only relevant for the customer like personal data will be deleted when the customer is deleted.
Samething applies when deleting records using X++, some rules must be followed to have the delete actions validated.

·         Cascade + Restricted: This delete action mode will act as restricted if used from the table browser or from a form. Deleting a record using X++, this mode will perform a cascade delete from the related table without calling validateDelete()

Example:
We will add 
delete actions will be added to both CustTable and MyFirstTable to ensure data consistency.

  1. Go to the node DeleteActions in MyFirstTable. Right-click and chooseNewDeleteAction. Use the property sheet for the new delete action and set to the CustTable.
    The Delete action mode should also be set to Restricted.
  2. Now locate CustTable and add a new delete action to MyFirstTable. Open the property sheet for the new delete action and choose MyFirstTable. Set the delete action mode to Cascade.
  3. Save the table