Search This Blog

Thursday, August 25, 2011

Wednesday, August 24, 2011

Dynamics AX Frameworks

Dynamics AX provides different framworks for each functionality.
Following are the list of AX frameworks

1. Runbase Framework
2. Batch Framework
3. Dialog Framework
4. Operation Progress Framework
5. NumberSequence Framework
6. SysLastValue Framework
7. AIF-Application Integration Framework
8. Wizard Framework
9. Infolog Framework
10.Unit Test Framework

Find Layer Wise changes Objects

UtilElments is the Table where all the object Types and Layer levels will store.
Following job will help you to get the objects in the layer.

static void CusLayerChanges_Find(Args _args)
{
       Utilelements utilElements;
       ;
      while select utilElements where utilElements.recordType 

                             ==UtilElementType::Table &&
                             utilElements.utilLevel == utilentryLevel::Cus
      {
           info(utilElements.name);
      }
}

When AX Starts Open the Form/report

When ever the AX Starts internally AX Kernel will creates an instance of the Info class
Info Class contains one method as startupPost().
This method used to execute the code every time AX starts.

Following Sample used to open the Item Details form whenever AX Starts

void startupPost()
{
    SysSetupFormRun formRun;
    Args args = new Args();
    ;

   args.name(formstr(InventTable));
   formRun = classfactory::formRunClassOnClient(args);
   formRun.init();
   formRun.run();
   formRun.detach();
}

AX 2012 VPC And Materials Download

Partner Source Users only can access the following links.
Dynamics AX2012 VPC
VPCLink

Dynamics AX2012 Materials
MaterialsLink




New in Dynamics AX 2012

Dynamics AX 2012 Unleashed Book Released

Microsoft AX 2012 Unleashed released
Following link you can find reference
http://www.amazon.com/Microsoft-Dynamics-AX-2012-Unleashed/dp/0672335484

Multi Selection Records in Grid

In Forms we will have the Grid with multiple records, so that we want to process the multiple records at the button click, do the following procedure.

Select button or menubutton and go to properties window and select multiselect=yes.

In Click of the button write the following code

void clicked()
{
      CustTable   custTable;
      ;
      super();
      if(CustTable_ds.anyMarked())
      {
              custTable= CustTable_Ds.getFirst(1,false);
              while(custTable)
              {
                  info(custTable.AccountNum);
                  custTable= CustTable_Ds.getNext();
               }
       }
}

Time Comparision using Dialog objects

The following sample code used to do Time values comparison and Time field values comparison using Dialog.

 static void TimeComparisonWithDialog(Args _args)
 {
  TimeofDay fromTime,toTime;

  Dialog dlg = new Dialog("TimeComparision");
  dialogField dlgField,dlgField2;
  TimeofDay fTime,tTime;

   ;
  dlgField = dlg.addFieldValue(typeid(TimeofDay),"","FromTime");
  dlgField2 = dlg.addFieldValue(typeid(TimeofDay),"ToTime","ToTime");

   if(dlg.run())
   {
       fromTime = dlgField.value();
       toTime = dlgField2.value();
    }
//str2Time("") this function is used to convet time into string.   if(fromTime < toTime)
  {
       info("This is the small time");
       info(time2str(fromTime,1,1));
  }
  else if(fromTime > toTime)
  {
       info("From Time should be less than To time ");
       info(time2str(toTime,1,1));
   }
   else

  {
      info("Enter the time");

   }
}

Build Query Ranges with Wild card Ranges

Sample code to retrive Items withe the wild card searches using Query Object

static void WildCardQuery()
{
Query query = new Query();
QueryRun queryRun;
InventTable inventTable;
;
query.addDataSource(tableNum(InventTable)).addRange(fieldNum(InventTable, ItemId)).value("900*, 1790*, 278*");
queryRun = new QueryRun(query);
    while(queryRun.next())
   {
      inventTable = queryRun.get(tableNum(InventTable));
      info(inventTable.ItemId);
   }

}

Hide/Unhide the TaskPane from Code

This piece of code will do the trick
Create the Job as below and Execute for Hide/Unhide

static void TaskPaneSet(Args _args)
{ boolean visible=true;
;
  new xInfo().taskPane().setVisiblity(visible);
}

 

How can a user id be linked to an employee?

Make sure you have created both an employee and a user. Now you are ready to associate them with one another. Go to the Administration - User form and select the desired user. Now press the button User relations. Ax will automatically create a new record, if no link already exists.
Go to the second tab page and under Employee, select the wanted Employee.
You have now successfully linked your Dynamics Ax user to an employee.

Linking a Ax user can either be internal (employee) or external (customer, vendor, business relation).
Same method applies for linking with external contacts.

 

Filter Records in Form using Code

The standard filter functionality in Ax forms is a neat and powerful feature.
Using this filter functionality in your code is something you'll definitely use at some point in time as a programmer.

Although it's possible to do it in a single line of code, I prefer a 3 step solution. That way it's more flexible.
Let me show you by example. We'll filter the customers records in form CustTable, only showing customers with Custgroup 20.

Step 1: Declare a class variable
In the ClassDeclaration method of the form, define a range.

QueryBuildRange CustGroupQBR;
Step 2: Instantiate the new range.
In the init method on the datasource of the form, you assign the range to a specific field (after the super call).

public void init()
{
super();

CustGroupQBR= this.query().dataSourceName('CustTable').addRange(fieldnum(CustTable,CustGroup));
}
Step 3: In the last step, you assign a value to the range.
This is done in the executeQuery method on the same datasource of the form. Before the super call. Like this:

public void executeQuery()
{ ;

CustGroupQBR.value(queryvalue('20'));

super();
}
You're done! When you open the form, your customer records are filtered, you only get the customers with CustGroup 20 set up.

How to use Query Ranges with Expressions

The standard filter functionality in Ax forms is very powerful and use full way to filter records. (Cntrl + G) is the shortcut for the filter functionality. Using this filter functionality in your code is something you’ll definitely use at some point in time as a programmer.

Technically this filter functionality is called adding ranges (range = where clause of the query). This is the very details topic which includes scenarios from Simple to very advance level.

Some time you need to show filtered records on the form (adding ranges to form datasource). This is very simple, you just need write some code.

this.query().dataSourceName(‘CustTable’).addRange(fieldnum(CustTable,Custgroup)).value(queryvalue(‘20));

Some time you need to use expressions or if you need OR clause in the query. Support of expressions is very good to implement the complex queries containing some complex joins and conditions. if you need to implement OR clause then again you need to use the expressions. If you add ranges to two different fields then it default supports the “And &&” clause, the “OR ||” clause is only supported if you add ranges to same field with different value. In all other cases we need to use the expressions to implement the OR clause. For details on implementing the expressions

this.query().documentaries(‘InventTable’).addRange(fieldnum(InventTable,RecId)).value(strFmt(‘(ItemId == “%1″)’, queryValue(“B-R14″))); http://www.axaptapedia.com/Expressions_in_query_ranges

Other than that there are two important classes in Dynamics ax 2009 which deals with the query ranges.

SysQueryRangeUtil
The SysQueryRangeUtil class is just the great enhancement to the AOT queries made in AX 2009. It is possible now to specify a range on the AOT query with the value taken from a method’s return. The requirements for such range method are quite simple: the method should be static, return string, be a member of the SysQueryRangeUtil class and not be related on the data fetched by the query

Tuesday, August 23, 2011

Trade and Logistics training

The Following link provides the intial training for AX learners to understand how Trade and Logistics setups are done.
http://www.dynamicsaxtraining.com/trade-and-logistics-training

Executing SQL directly from X++

The X++ language supports a number of ways to execute native SQL against any SQL data source. Below are two samples for retrieving data as well as manipulating data.
Following are the Example using Connection Class.
Example 1#Retrieve

void RetrieveSQLData()
{
   Connection con;
   Statement Stmt;
   ;
   Con = new Connection();
   Stmt = Con.createStatement();
   ResultSet Resultset =Stmt.executeQuery(‘SELECT VALUE FROM SQLSYSTEMVARIABLES’);
    while ( Resultset.next() )
    {
         print Resultset.getString(1);
     }
}

Example 2#Manipulation

void DeleteCustomerData()
{
    str sql;
    Connection conn;
    SqlStatementExecutePermission permission;
;

    sql = ‘delete from custTable where CustId='1005'’;
    permission = new SqlStatementExecutePermission(sql);
   conn = new Connection();
   permission = new SqlStatementExecutePermission(sql);
  //Define the Permission to be started for Executing any manipulation Statements directly
   permission.assert();
   conn.createStatement().executeUpdate(sql);
   // the permissions needs to be reverted back to original condition.
   CodeAccessPermission::revertAssert();

}

Performance improvement by changing position of dataAreaId field in index


Performance-wise, fields in the index should be sorted by selectiveness. 
Most selective(unique) fields needs to go first and least selective should be in the end of the list. 
By default AX kernel creates indexes with dataAreaId field at first position in the index which is good if you work with multiple companies. Position of DataAreaId field 
can be changed by adding the dataAreaId as a field in an index:
1. right click on the index and click "New Field"
2. select dataAreaId in the index field properties
When it is done dataAreaId can be placed at any position in the index(last one in my case). 
AX kernel will keep that position and won't override it.

AX Interview Questions & answers


Dynamics Important Topics


EP- DataSets, Queries.Deploying EP forms to sit.

Workflows Classes functions

Importing Master Data from Excel

Define package and Deploy to environment and only admin must use it.

Ledger Journal posting Classes

Ledger Journal inbalance- what we have to do.

Map and Use of Map

Relations

Virtual Companies,Table collections,Domain

Estimation Techniques.

Load balancing setup between AOS servers

Caching mechanisms.



Load Balancing

  Create Cluster from Admin->setup->cluster Configuration

  Map the AOs to the Clusters as loadbalancer option to be ticked.

 Set the client configuration to connect LOAD balance AOS instance first.


Caching mechanism
1. single record cache,
2. entire table cache, and
3. record view cache.

Single Record Caching
The record cache is utilized for full key lookups only and contains the 100 most recently used records for a particular table. In a 3-tier environment, there is a record cache on the client and a record cache on the server. The server record cache is shared between all clients.
Record Cache are of the following types:
(a) NotInTTS
(b) Found
(c) FoundAndEmpty


Record caching is enabled for a table when all the following statements are true:

·         The CacheLookup property on the table is enabled by setting it to one of the following values:

·         notInTTS

·         Found

·         FoundAndEmpty



·         The table's PrimaryIndex property is set to a unique index that exists on the table. The RecId index does not qualify as a caching index unless you set the table's PrimaryIndex property to this index.

·         The record buffer disableCache method has not been called with a parameter of true.

The fields in the table's unique index make up the caching key. A record is placed in the cache when the following criteria are met:

·         The table is cached by setting the CacheLookup property to notInTTS, Found, or FoundAndEmpty.

·         The SELECT statement that selects the records uses an equal operator (==) on the caching key. The fields in the WHERE clause of the SELECT statement match the fields in the index referenced by the table's PrimaryIndex property.

The table's CacheLookup property defines how and when records are cached as shown in the following table.

CacheLookup Property Value
Result
None
No data is cached or retrieved from the cache for this table.
This property value should be used for tables that are heavily updated or where it's unacceptable to read outdated data.
NotInTTS
All successful caching key selects are cached.
When in a transaction (after ttsBegin), no caches made outside the transaction are used. When inside a transaction, the record is read once from database and subsequently from cache. The record is select-locked when read in a transaction, which ensures that the record cached is not updated while the transaction is active.
A typical example of the NotInTTS property is the CustTable in the Microsoft Dynamics AX standard application. It's acceptable to read outdated data from the cache outside a transaction, but when data is used for validation or creating references, it is ensured that the data is real-time.
Found
All successful caching key selects are cached. All caching key selects are returned from the cache if the record exists there. A selectforUpdate in a transaction forces reading from the database and replaces the record in the cache.
This is typically used for static (lookup) tables, such as Unit, where the record usually exists.
FoundAndEmpty
All selects on caching keys are cached, including selects that are not returning data.
All caching key selects are returned from caching if the record exists there, or the record is marked as nonexistent in the cache. A selectforUpdate in a transaction forces reading from the database and replaces the record in the cache.
An example of FoundAndEmpty record caching is in the Discount table in the Microsoft Dynamics AX standard application. By default, the Discount table has no records. By using a FoundAndEmpty cache on this table, the keys that are queried for but not found are stored in the cache. Subsequent queries for these same non-existent records can be answered from the cache without a round trip to the database.
EntireTable
Creates a set-based cache on the server. The entire table is cached as soon as at least one record is selected from the table.



The Found and FoundAndEmpty caches cross transaction boundaries. The NotInTTS cache is newly created inside a transaction. This example, modified for the purposes of this topic, demonstrates how records are retrieved from the cache when the table's CacheLookup property is set to NotInTTS, and the PrimaryIndex property is set to a unique index on the AccountNum field.

static void NotInTTSCache(Args _args)

{

    CustTable custTable;

    ;

// The query looks for records in the cache.

// If records don't exist, the query accesses the database.

    select custTable

        where custTable.AccountNum == '4000';

    // The transaction starts.

    ttsbegin;

    // The cache is not used. The query accesses the database

    // and records are placed in the cache.

    select custTable

        where custTable.AccountNum == '4000';



    // The query uses the database because

    // the forupdate keyword is used.

    select forupdate custTable

        where custTable.AccountNum == '4000';

    // The query uses the cache and not the database.

    select custTable

        where custTable.AccountNum == '4000';

    // The query uses the cache because

    // the forupdate keyword was used previously.

    select forupdate custTable

        where custTable.AccountNum == '4000';



    // The transaction is committed.

    ttscommit;



    // The query will use the cache.

    select custTable

        where custTable.AccountNum == '4000';

}

If the table CacheLookup property was set to Found or FoundAndEmpty, the first select statement inside the transaction (after the TTSBegin statement) would retrieve the record from the cache.


Entire Table Caching
The entire table cache is a different type of caching compared to record caching,which is a complete local copy of a table. The entire table cache exists on the AOS, a 3-tier rich client, the COM connector, and on a 2-tier client. This
means that there is no entire table cache on a 3-tier thin client, as it utilizes the entire table cache located on the AOS.
The cache is populated at the time of the first access to that particular table for a given company.

Record View Caching
The RecordViewCache is instantiated using a X++ select with a where clause that defines the result set. The RecordViewCache is deactivated as soon as the RecordViewCache object goes out of scope or is destroyed.
It is private and offers a result-set cache with a limited lifetime.

Clearing the Cache

ax_{GUID}.auc  The GUID is unique for each installation and is stored in the SysSQMSettings table.

example: ax_{76F5BA3B-AD98-4E5F-A1EE-D58C24370BDC}.auc
C:\Documents and Settings\%USERNAME%\Local Settings\Application Data\


Estimation Techniques

First place the old  version layers to the  old directory in the current application folder and run the following

AX-DevelopmentTools->code upgrade->Detect code upgrade conflicts.

After identifying the conflicts run the estimation report.

Before running the estimation report define the parameters for estimation for all the objects of the current client.

Domains
Domains are groups of company accounts that combined with user groups allow you to define different permissions  for a user group depending on the company that is active.ex;-A user have full access to GL in the context of Company dat and only limited access for cee company you do this by assigning the permissions to combination of domains  and usergroups.To do that Admin->Setup->domains->create the new domain and assign the companies for that domain.
Virtual CompanyDynamics Ax stores data as per company in tables. But there might be occasions when you want to share data across companies, like country, state, zip codes data. This sharing of data is achieved by creating a virtual company and storing data in this virtual company. Normal companies are then configured to read/write data from this virtual company. The only purpose of virtual company is to share data across companies, you cannot log into this virtual company.

Before seeing how to do virtual company setup, I would like you to show another trick that can be used to share data across Ax. There is a property on Ax tables called "SaveDataPerCompany", you can use this property to save data globally in Ax. To share data set this property to "No".


Virtual Company setup:

Step 1: Create Table Collection

Decide which tables you want to share and create a table collection for these functionally related tables. For example; if you want to share Global Address Book across companies then you can utilize the existing table collection "DirPartyCollection".



To create a table collection, go to AOT\Data Dictionary\Table Collections and on right click select "New Table Collection", then just drag your required tables in this collection.



Step 2: Create Virtual Company, configure/attach normal companies and table collection

Create a virtual company that will hold the shared data for normal companies.
Note: Before doing the below steps, make sure you are the Ax administrator and the only user online.

1.    Go to Administration -- Setup -- Virtual company accounts, and create a virtual company.


2.    Decide which companies needs to share data and attach those normal companies with this virtual company.


3.    Attach the table collection with this virtual company.



Your Ax client will re-start and you are done with setting up the virtual company account.

Now, when you have virtual company in place, all new data will be saved in this virtual company. Only companies attached to the virtual company can use this shared data. All other companies which are not attached will work normally, these companies will continue to read/write data as per company bases.

How to move existing data to virtual company?When you setup a new virtual company, Ax does not move data automatically from normal company to virtual company. This is done by system administrator manually.

There are many ways to do this data move, but I will discuss only two approaches here.

Ax Import / Export:This is standard Ax approach.

1.    Manually export existing normal company data from Ax.

2.    Remove duplicate records from this exported data set. 

3.    Delete exported data from normal companies.

4.    Import the exported data back in Ax, while logged into one of the participating companies. 

5.    Create records deleted in point 2 again in Ax using your logic. How you want to handle duplicate? For example, if you have customer 'Rah' in more than one normal company, what you want to do with this?

Direct SQL:
Use this approach if you have good knowledge about SQL queries and Ax table structures/relationships. Below are few points that will help you understand what to do and how to do.

  • All Ax tables store data as per company unless otherwise specified. For this, Ax uses a special field called DataAreaId. In case of virtual company, it does not matter from which normal company you log-in, it is always the virtual company id which is stored in DataAreaId field of shared tables. 
  • Ax also assigns a unique 64bit number to each record in table. For this, Ax uses a special field called RecId. This RecId is unique in the table and is generated by Ax when you insert a new record in Ax. It is not related to DataAreaId / Company.
  • For unique records between all participating normal companies, update the DataAreaId to the virtual company id.
  • For duplicate records, create them again in Ax using some Ax job or Ax import/export technique.
Relations

·         Normal to specify relation fields without conditions.

·         Field fixed to specify relation fields to restrict the records in the primary table.

·         Related field fixed to specify relation fields that restrict the records in the related table.

·         New ForeignKey to specify a correspondence between a foreign key field in the present table to the primary key field in another parent table.

Ex:-SalesTable->salesLine.

Normal Relation

1.       In the Field property, select the field in the primary table that relates to a field in the present table.

2.       In the RelatedField property, select the field in the related table.

Ex:-Salesline.salesid==SalesTable.salesid

Field fixed Relation

1.       In the Field property, select the field in the primary table to use to restrict the records.

2.       In the Value property, enter the value of the selected field as the filter. This relates only records in the primary table that match that field value. Only numeric values can be entered in the Value property. Field fixed relations can be created only on numeric fields. Each of the related fields are AND ed in the table relation.

Ex:-Salesline.Salesid==1234

Related field fixed Relation

1.       In the Value property, enter the filter value of the selected field. This causes only records in the related table that match that field value to be related. Only numeric values can be entered in the Value property. Related field fixed relations can be created only on numeric fields.

2.       In the Field property, select the field in the related table to restrict the records. Each of the related fields are ANDed in the table relation.

Ex:- 1234==SalesTable.SalesId.

New ForeignKey Relation-2012

We often use the term child to refer to a table that has a foreign key column. And we use the term parent to refer to the other table that supplies the value for the foreign key column. But we never use the terms parent and child to describe the base and derived tables in an inheritance relationship.

1.       Set the Table property to the name of the parent table, the table that contains the primary key field.

2.       Set the RelatedTableRole property to a word or phrase that describes the purpose of the parent in the relationship.

Note
This value is added automatically as a method name on the child table. This method is displayed by IntelliSense in the X++ editor, but you cannot see the method in the AOT. For more information about how to use this method, see How to: Use the UnitOfWork Class to Manage Database Transactions.

3.       Set the Name property. A helpful value is a combination of the Table property and RelatedTableRole property values.

4.       Right-click the node for your relation, click New, and then click New ForeignKey. Next click either PrimaryKey based or Single field AlternateKey based. A new field is instantly added to the child table. This field stores the foreign key values.

5.       Under the Fields node, click the new field, and then change its Name property value.

6.       For performance benefits, you might decide to add an index on the new foreign key field.

Maps
Maps define X++ elements that wrap table objects at run time. With a map, you associate a map field with a field in one or more tables. This enables you to use the same field name to access fields with different names in different tables. Map methods enable you to create or modify methods that act on the map fields.

A table can be accessed through more than one map. Typically, if more than one map accesses the same table, each map accesses different subsets of fields in the table. Maps don't define database objects and so they aren't synchronized with the database. For more information about creating maps,.

Benefits of Map:




The benefits of maps include:

·         Simplicity - maps provide a single interface to fields in multiple tables. This means that any object referencing the map field can be used against multiple tables without changing any field names.

·         Consistency - table fields with varying names can be accessed in code in a consistent manner. For example by using a map, fields named Zip in one table, ZipCode in another, and PostalCode in yet another table can all be accessed by the name ZipCode.

·         Code reuse - a map method enables you to add code that runs against the map fields. A single map method prevents the duplication of methods and code on each table.

An example of a map in Microsoft Dynamics AX is the Address map, which can be used to access fields in two tables (among others) called Address and CustVendTransportPointLine. This enables developers to use one Address map object to access common address fields and methods. The following table shows how the map fields are associated to table fields.

Field in Address map Field in Address table Field in CustVendTransportPointLine table
Address
Address
ToAddress
City
City
ToCity
State
State
ToState
ZipCode
ZipCode
ToZipCode





In Microsoft Dynamics AX, maps are located in the Application Object Tree (AOT) under the Data Dictionary\Maps node. Each map has four primary elements:

·         Fields

·         Field Groups

·         Mappings

·         Methods

Fields


The Fields node contains the map field elements. Each field must be the same data type as the field to which it's associated. Use the ExtendedDataType property to specify the map field's data type if the map field is associated with a table field that's based on an extended data type.

Field Groups


The Field Groups node contains field groups that group together fields that logically belong together. Field groups in maps work the same way they do in tables. For more information about field groups

Mappings


The Mappings node is where the map fields are associated with table fields. Directly under the Mappings node are the MappingTable objects. Each MappingTable object specifies a table that the map is associated with. Under the MappingTable object are the field mappings that associate a map field with a table field. If a field exists in the map with no associated field in a particular table just leave the MapFieldTo property blank.

Methods


This node displays all the methods available from a map. In this node you can add a new method or you can override methods on the xRecord kernel class and add your own code.

Map methods are useful because code that acts on the map fields can be encapsulated in a map method instead of being in multiple table methods. For example, the AddressMap has a formatAddress method that formats the address consistently whether the map references the Address table or the CustTable table.


Journal Imbalance while GL posting-What to Do?

Object:
\Classes\LedgerVoucherObject\updateTotals
Invoke Scenario:
When there is some problem about imbalance, this function will be very helpful to track why it is imbalance.

Operation Instance:

General ledger -> Journals -> General journal -> Create a new line -> Click Line -> add lines for journal -> Click button post -> post.

Explanation of codes:
private void updateTotals(LedgerTrans _ledgerTrans)
{
LedgerTrans ledgerTransTotals;
;
ledgerTransTotals.data(_ledgerTrans);
if (transDateTotals.find(ledgerTransTotals)) //line 13
{

ledgerTransTotals.AmountCur += _ledgerTrans.AmountCur;
ledgerTransTotals.AmountMST += _ledgerTrans.AmountMST; //line 16
ledgerTransTotals.AmountMSTSecond += _ledgerTrans.AmountMSTSecond;
ledgerTransTotals.Qty += _ledgerTrans.Qty;
transDateTotals.ins(ledgerTransTotals, true);

}
else //line 21
{
transDateTotals.ins(ledgerTransTotals);
}
}
“ledgerTransTotals” is used to accumulate all the transactions. If the transaction is the first transaction needs to be checked, it goes into line 13. Otherwise, it goes into line 21. The ledgerTransTotals.AmountMST at line 16 should be 0 when the last transaction has been added, or it will not be posted. And you will receive a infolog “The trasaction on voucher *** do not balance”


 Ledger Journal posting Classes

Class Names:-

LedgerJournalCheck

LedgerJournalCheckPost

LedgerJournalCheckPostApproval

LedgerJournalPost

LedgerJournalPostBatch


Indexes in AX2009


The indexes in the Microsoft Dynamics AX 2009 table definition are the physical indexes that exist on the tables in the database.

 There are two types of indexes:

Unique or Primary

Non-Unique

 If a unique index is created based on a column (or a set of columns), Microsoft Dynamics AX 2009 makes sure that no duplicate keys occur in that column (or set of columns).

A primary index is an index used to organize both the data store and other indexes for more efficient updating and faster access.

 Non-unique, or cluster indexes, are created for performance reasons. They provide a quick way of retrieving data, instead of performing a full-table search of all the records in the table.

 A unique index guarantees that the index key contains no duplicate values and therefore every row in the table is in some way unique. Specifying a unique index makes sense only when uniqueness is a characteristic of the data itself. For example, if you want to make sure that the values in the NationalIDNumber column in the HumanResources.Employee table are unique, when the primary key is EmployeeID, create a UNIQUE constraint on the NationalIDNumbercolumn. If the user tries to enter the same value in that column for more than one employee, an error message is displayed and the duplicate value is not entered.

 What is the difference between index and index hint ?

 Normal 0 false false false EN-US X-NONE X-NONE MicrosoftInternetExplorer4

Index :

Using "Index": when you add the statement "index MyIndex", the Axapta kernel will add an "ORDER BY" with all the fields of the index.

 Example: select * from InventTable index GroupItemIdx will generate the following SQL statement to the database:

 SELECT A.ITEMGROUPID, A.ITEMID, A.ITEMNAME,.... FROM INVENTTABLE A ORDER BY A.ITEMGROUPID, A.ITEMID

 The Index ItemGroupIdx of the InventTable exactly contains the two fields ItemGroupID and ItemId (in that order). Using "index", you still give the control of which index to use to the database optimizer. So, if the optimizer finds a better index to use, it will use it.

 Index hint

Normal 0 false false false EN-US X-NONE X-NONE MicrosoftInternetExplorer4

Using "Index hint": when you add the statement "index hint MyIndex", the Axapta kernel will add a statement to instruct the database to use that index and no other one.

 Example: select * from InventTable index hint GroupItemIdx will generate the following SQL statement to the database:

 SELECT /*+ INDEX(A I_175GROUPITEMIDX) */ A.ITEMGROUPID, A.ITEMID, A.ITEMNAME,.... FROM INVENTTABLE A

 Using "index hint", you take away the control of which index to use from the database optimizer. So, if there may be a better index, the database will not use it.

 Conclusion:

 Adding the "index" statement to an Axapta select, it does NOT mean that this index will be used by the database. What it DOES mean is that Axapta will send an "order by" to the database.

 Adding the "index hint" statement to an Axapta select, it DOES mean that this index will be used by the database (and no other one).


Dialog framework validation at field level

Getfromdialog method does not do much then just copying the values enterd in

the dialog box to the variable you created in your class declaration. For

stopping the window from closing you have to write the validate method and

return false value if validation fails.

See the following example:

Public class dlgTest extends runbase

{

dialogfield dlgfldCust;

custAccount custAccount;

}

static void main(args   _args)

{

dlgTest dlgTest = new dlgTest();



if(dlgTest.prompt())

dlgTest.run();

}



public boolean getFromDialog()

{;

custAccount = dlgfldCust.value();



return true;

}

public boolean validate(Object calledFrom)

{

boolean     ret = super();

if(custAccount  && !CustTable::find(custAccount))

ret = ret && CheckFailed("Invalid Customer account");
return ret; }



Important Questions Part 2



1.     Can you just tell the table properties that you can remember?

Label,Titlefield1,titlefield2,primary index, cluster index,temporary


  1. Explain OCC & PCC (optimistic concurrency control , Pessimistic concurrency control)

Locking of records happens automatically (if you have Pesimistic concurrency

switched on) when updating a record, if you have Optimistic concurrency

switched on (the default) then the record is not locked, but the RecVersion

field is used to detect any possible update conflict.

You can call a method to override the behaviour like so:

    table.concurrencyModel(ConcurrencyModel::PessimisticLock);


  1. Difference between views and tables

Tables
Tables store business data. Each table in the AOT has a corresponding table in the underlying Microsoft SQL Server database.
In Microsoft Dynamics AX, tables have advanced features beyond what tables might have in the underlying database. The advanced features include the following:
  • Method members – A table can have methods, just as a class in X++ or C# can have methods.
  • Table inheritance – A table can extend, or be derived from another table. That same table can be the base table for several derived tables.
  • Valid time state – A table can be configured to track data relationships for specific date-time spans.
Tables are specified at AOT > Data Dictionary > Tables.
Views
A view is an X++ SQL select statement that is given a name that is reusable in other X++ SQL statements. The select statement of the view can reference one table, or it can join tables. Also, a view can reference other views, or a mix of views and tables. A view can also reference maps.
Developers are encouraged to consider using an AOT query element as the source of data for their view.
Views are specified at AOT > Data Dictionary > Views.



  1. Explain Queries? What’s it used for?
  2. Explain different types of reports?

Reports in AX 2009

There are two main types of reports in Microsoft Dynamics AX:

1 ad hoc reports 2.preconfigured reports.

Ad hoc reports

Ad hoc reports are reports that you create yourself. You select the data that you want to display on the report, and you design the layout of the report. You can create transactional ad hoc reports or multidimensional ad hoc reports.

Transactional ad hoc reports

A transactional ad hoc report is a report that is based on transactional data that is entered in Microsoft Dynamics AX.

To create a transactional ad hoc report, you use a tool called Report Builder, which is a component of Microsoft SQL Server Reporting Services. Using Report Builder, you can create a report by dragging database tables and fields onto a report template.

Multidimensional ad hoc reports

A multidimensional ad hoc report is a report that is based on Microsoft SQL Server Analysis Services cubes.

To create a multidimensional ad hoc report, open Microsoft Office Excel, select the cube data that you want to display on the report, and then format the report as a PivotTable or PivotChart report.

Preconfigured reports

Preconfigured reports are reports that have been designed for you. Although you will not be able to modify the layout of these reports, you can filter and sort the data that is displayed on the reports. The following types of preconfigured reports are available.

Microsoft Dynamics AX standard reports

Standard reports are preconfigured reports that are provided by Microsoft Dynamics AX. Each module's area page has a Reports area that contains links to standard reports. See Appendix for list of reports in each Module.

Microsoft Dynamics AX auto reports

Auto reports are preconfigured reports that you can generate by clicking the Print icon on a form.


  1. Differentiate auto design spec & Generated design? Which one is a preferable choice and why
  2. Primary Key in tables (In dynamics AX don’t have primary key)

There is Primary index but it can accept Duplicates or not depends upon the property setting at the index properties.

  1. What is the default index for a table?
Recid index.

  1. Explain delete action? Types of delete action?

Delete Action
Description
Comments
None
Delete action disabled
Cascade
Deletes related records.
Setting the DeleteAction property to Cascade extends the functionality of the table's delete method. As a result, super(), in delete, initiates a cascaded deletion, propagating the delete from table to table.
A cascaded delete is implicitly protected by tts. Database changes aren't committed until the entire transaction is complete.
Example
On the CustTable table, a cascading delete action has been defined for the CustBankAccount table. When a customer is deleted from the CustTable table, the delete method also ensures that the corresponding bank account information is automatically deleted.
Restricted
Restricts deletion in the current table if data is present in related tables.
Setting the DeleteAction property to Restricted extends the functionality of the table's validateDelete method.
As a result, super(), in validateDelete, checks whether records exist on related tables. If records do exist, validateDelete returns false. The forms system ensures that the deletion is not performed. In your own X++ code, check the return value of validateDelete. Don't delete the primary or related records if the method returns false.
Example
On the CustTable table, a restricted delete action has been defined for the CustTrans table. When a customer is deleted in the CustTable table, the validateDelete method ascertains whether transactions exist for the customer in the CustTrans table. If so, validateDelete returns false.
Cascade+Restricted
Cascade the delete, even though records exist on related tables.
Setting the DeleteAction property to Cascade+Restricted extends the functionality of the table's validateDelete and delete methods.
As a result, super(), in validateDelete, ascertains whether records exist on related tables. Whether deleting records from forms or X++, if validateDelete returns false, the primary record isn't deleted and the cascading delete isn't performed. You should first delete the records in the related table before deleting the primary record.
If the primary record is being deleted as part of a cascading delete, the primary record and the records in the related table will be deleted.
Example
The Cascade+Restricted delete action is used in the standard application for LedgerJournalTrans on LedgerJournalTable.
This type of delete action is useful when you prefer a total clean-up—when you delete a customer, you also delete all the transactions associated with that customer.



  1. What are all the add- on tools you used in Dynamics AX (It’s an indirect question for AIF)
  2. Can you just point out some best practice you used when u develop a project?
  3. Did you worked with base modules?  Actually I answered this question as  
  4. I worked with production module to integrate with our steel process management
  5. So can you just point out three classes that you used in production module
  6. Explain the posting in production module
  7. When you create production order….Can you point out the affecting classes, tables.
  8. what precautions you need for overriding fetch() method for a report?
  9. In which case delete_from and delete() have same result?

The difference between the two approaches is in the speed of execution.
            Assuming that the tables delete() method has not been overridden and that there is database  logging of deletes for the table then "delete_from" x++ code will generate a single database round trip which will delete all of the records matched by the where clause. The looping approach will issue one database round trip for each record to be deleted in addition to the initial select and is, consequently, slower than the "delete_from" approach.

It's worth noting that "delete_from" will automatically revert to a looped approach if the table's delete() method has been overridden or AX has been configured to log deletes for the table. This can be avoided by call the table's skipDataMethod() and skipDatabaseLog() passing "true" as the argument to each of these calls but you can only do that if you are sure that the code in the delete() method isn't needed in this instance and that its okay to not log the delete.

You might have seen table locks with "delete_from" if your where clause has no viable index. In such cases the database has no choice but to lock the whole table while it deletes the rows.

My advice: use "delete_from" wherever you can but, as with all database access, make sure you have suitable indexes.

  1. Explain sales/purchase order processes in AX.