Dynamics ax 2012 Client Application Feature

The client application is a 32-bit Windows application that provides a rich user interface for the Microsoft Dynamics AX application. The client is typically used
by employees within the organization. You can use Enterprise Portal for browser based access by external users or for users who do not require the rich user
interface offered by the Windows client.
Your network must meet the minimum requirements for latency and bandwidth to get proper performance from the client. Because of the volume of
communication that passes between the client and the server, you might experience diminished response time if your network does not meet the minimum
requirements.


The client provides the following functionality:
Rich user interface:

The client is a Windows application with a rich user interface consisting of forms, menus, and controls. The client includes over 3,000
forms built using a combination of metadata and X++ code. The Microsoft Dynamics AX forms use X++ to process events and business logic. Forms can
host managed WinForms or Windows Presentation Foundation (WPF) controls, and X++ can interoperate with managed (.NET) classes and assemblies.

The MorphX development environment:

The development environment is integrated into the client application. Authorized developers can use the MorphX
development environment to enhance or customize the Microsoft Dynamics AX application.


Integration with Microsoft Office:

The Microsoft Dynamics AX application integrates with Microsoft Office. Data in grids can be exported to Microsoft
Excel, where that data can be formatted, manipulated, refreshed, modified, and saved back into Microsoft Dynamics AX. You can integrate Microsoft Outlook®
with the CRM module to synchronize schedules and tasks bi-directionally.

Unified communications:

The client provides integrated unified communications using Microsoft Office Communicator. Key forms and controls
are presence-aware for contacts and employees. These forms and controls also provide a visual indicator of the availability of contacts. Users can also use realtime
messaging such as instant messaging and outbound voice communication.

Integration with the Telephony Application Programming Interface (TAPI):
TAPI is a Windows standard interface for integration between telephone systems and Windows-based software. For example, your application displays
information about the caller when you receive a call. The Microsoft Dynamics AX client supports TAPI.

Reports:

The Microsoft Dynamics AX application provides reports based on SSRS.

Disaster Recovery

All companies should have a thorough Disaster Recovery Plan that describes what the company will do if a disaster happens.
To determine what provisions to make for partial or complete loss of data, stakeholders must determine the total cost of rebuilding or replacing the organization's data. Consider the following:
• What are the costs of reconstructing the organization's financial, personnel, and other business data?
• What does the business insurance cover with regard to replacing lost data?
• How long would it take to reconstruct the business’ data? How would this translate into lost future business?
• What is the cost for each hour of server downtime?

SIGSignatureLog Error

Error Message : Not enough rights to use table 'Signature log' (SIGSignatureLog)

(Some time this problem is occurred when we want to see record info of any record)

SOLUTION: After installing AX5 SP1, it creates a new configuration key which it leaves unpicked. go into Administration > Setup > System > Configuration and tick the Electronic Signature tick box

Types of MAP in dynamics AX

There are two types of Maps available in dynamics AX

1. X++ Maps: it can be used as a temp data store for the given scope of a process. This takes us less over head, and is much quicker than a TempTable.

Map class allows you to associate one value (the key) with another value. Both the key and value can be any valid X++ type, including objects. The types of the key and the value are specified in the declaration of the map. The way in which maps are implemented means that access to the values is very fast.

Below is a sample code that sets and retrieves values from a map.


 
static void checkItemNameAliasDuplicate(Args _args)
{
inventTable inventTable;
Map map;
MapEnumerator mapEnumerator;
NameAlias nameAlias;
int counter = 0;
;

map = new Map(Types::String, Types::Integer);

//store into map
while select inventTable
{
nameAlias = inventTable.NameAlias;
if (!map.exists(nameAlias))
{
map.insert(nameAlias, 1);
}
else
{
map.insert(nameAlias, map.lookup(nameAlias) + 1);
}
}


//retrieve from map by using MapEnumerator
mapEnumerator = map.getEnumerator();
while (mapEnumerator.moveNext())
{
nameAlias = mapEnumerator.currentKey();
info(strfmt("%1,%2",mapEnumerator.currentKey(),mapEnumerator.currentValue()));
}
}

References:
http://msdn.microsoft.com/en-us/library/aa553382.aspx


2. AOT Maps: A map can unify the access to similar columns and methods that are present in multiple tables. 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. Methods on maps enable you to create or modify methods that act on the table fields that the map references.

Map & MapEnumerator Objects

Map can be used as a temp data store for the given scope of a process, and is much quicker than a Temp. Table.

Map class allows you to associate one value (the key) with another value. Both the key and value can be any valid X++ type, including objects. The types of the key and the value are specified in the declaration of the map. The way in which maps are implemented means that access to the values is very fast.

Below is a sample code that sets and retrieves values from a map.


 
static void checkItemNameAliasDuplicate(Args _args)
{
inventTable inventTable;
Map map;
MapEnumerator mapEnumerator;
NameAlias nameAlias;
int counter = 0;
;

map = new Map(Types::String, Types::Integer);

//store into map
while select inventTable
{
nameAlias = inventTable.NameAlias;
if (!map.exists(nameAlias))
{
map.insert(nameAlias, 1);
}
else
{
map.insert(nameAlias, map.lookup(nameAlias) + 1);
}
}


//retrieve from map by using MapEnumerator
mapEnumerator = map.getEnumerator();
while (mapEnumerator.moveNext())
{
nameAlias = mapEnumerator.currentKey();
info(strfmt("%1,%2",mapEnumerator.currentKey(),mapEnumerator.currentValue()));
}
}

References:
http://msdn.microsoft.com/en-us/library/aa553382.aspx

Dynamics AX Caching

Hi every body,

Really it is very important and interesting topic and This post is imparted from Here, and now let’s start

 

Cache Location

Caches are used on both the client and the server. The Microsoft Dynamics AX runtime manages the cache by removing old records when new records are added to the cache.

Client Cache

A client-side cache can be used only by the client. The client cache is used when a select is executed from the client tier. If no record is found in the client cache, the client then searches the server cache for the record. If the record isn't located in the server cache, it's retrieved from the database. The maximum number of records maintained in a client cache is 100 records per table for a given company.

Server Cache

A server-side cache can be used by any connection to the server. The server cache is used when a select is executed on the server tier. If no record is found in the cache, it's retrieved from the database. The maximum number of records maintained in a server cache is 2,000 records per table for a given company.

Record Caching

Microsoft Dynamics AX database record caching is a performance-enhancing feature that helps avoid database access when it's not strictly necessary. Retrieving database records from memory instead of the database significantly speeds up data access. Caching can reduce the performance penalty for repetitively accessing the same database records.

Types of Caching

Caching is transparent to the application; however, it's important to know how caching works to optimize its performance in Microsoft Dynamics AX. Following are the types of caching:

  • Single-record
  • Set-based

Single-record caching has the following characteristics:

  • Defined at design time
  • Moves records to the cache based on the table's CacheLookup property and the type of SELECT statement that is used to retrieve the record

Set-based caching has the following characteristics:

  • Defined either at design time or in X++ code
  • Moves sets of records to the cache
  • Implemented either through the table's  CacheLookupproperty or in code by using the RecordViewCache class

 

Single-Record Caching

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 PrimaryIndexproperty 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 WHEREclause 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 thePrimaryIndex 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.

 

 

 

Set-Based Caching

In Microsoft Dynamics AX, groups of records can be cached all at once with set-based caching. Set-based caching can be implemented in two ways:

  • At design time, by setting the table's CacheLookup property to EntireTable.
  • In code, by using the RecordViewCache class.

EntireTable Cache

When you set a table's CacheLookup property to EntireTable, all the records in the table are placed in the cache after the first select. This type of caching follows the rules of single record caching in which the SELECTstatement WHERE clause fields must match those of the unique index defined in the table's PrimaryIndex property.

The EntireTable cache is located on the server and is shared by all connections to the Application Object Server (AOS). If a select is made on the client tier to a table that is EntireTable cached, it first looks in its own cache and then searches the server-side EntireTable cache. An EntireTable cache is created for each table for a given company. If you have two selects on the same table for different companies the entire table is cached twice.

Joins that include an EntireTable cached table are only performed against the cached copy when all tables participating in the join are EntireTable cached. Otherwise a database join is performed.

Important Note:

Avoid using EntireTable caches for large tables because once the cache size reaches 128 KB the cache is moved from memory to disk. A disk search is much slower than an in-memory search.

Flushing the Cache

An EntireTable cache is flushed whenever an insert, update, or delete is made to the table. At the same time, the AOS notifies other AOSs that their caches of the same table must be flushed. After the cache is flushed, a subsequent select on the table causes the entire table to be cached again. Therefore, avoid caching any table that's frequently updated. Regardless of when updates are made, EntireTable caches are flushed every 24 hours by the AOS.

RecordViewCache Cache

Set-based caching is implemented in code by using the RecordViewCacheclass. You must first create a record buffer using the nofetch statement and then pass the record buffer to the RecordViewCache class when it's instantiated.

The cache is created on the server and is only accessible by the process that creates the cache object. Once the cache is instantiated, all select statements are issued against the cache, as shown in the following

static void RecordViewCache(Args _args)

{

CustTrans custTrans;

RecordViewCache recordViewCache;

;

// Define records to cache.

select nofetch custTrans

where custTrans.AccountNum == '4000';

// Cache the records.

recordViewCache = new RecordViewCache(custTrans);

// Use cache.

select firstonly custTrans

where custTrans.AccountNum == '4000' &&

custTrans.CurrencyCode == 'USD';

}

Due to concurrency issues, the forUpdate keyword on the instantiating X++SELECT statement should only be used when all of the records in the result set will be updated. Otherwise it's a better strategy to use select forUpdate only for the records that are to be updated.

The RecordViewCache class is used in a select when the select is from a table that's cached, the select statement doesn't participate in a join and the select WHERE clause matches the WHERE clause with which theRecordViewCache was instantiated.

The cache created by the RecordViewCache class stores records in a linked list. Therefore Microsoft Dynamics AX searches the cache sequentially for records that match the search criteria. If the SELECT statement contains anORDER BY clause, a temporary index is placed on the cache and the runtime uses the index when searching records.

Override the event methods on dialog controls in Dynamics AX

In generally most of the Form control events (Modifying Field, Cursor movements, Focusing events, etc...) can override using standard AX method. But in dialog control events are not as straight forward as it is on form controls. Today I’m going to show how we can override Dialog controls events.

Step 1: Create a Class extends by RunBaseBatch class & declare main variables. In my example I have extended by RunBaseBatch Class.

class Test_DialogField extends RunBasebatch

{

CustAccount CustId;

DialogField dialogCustId;

DialogField dialoglName;

Dialog dialog;

#define.CurrentVersion(1)

#localmacro.CurrentList

CustId

#endmacro

}

Step 2: Add Pack() & Unpack() methods. Here I have not written code to store & retrieve stored data. But I added those methods to avoid compiling errors.

public container pack()

{

return connull();

}

public boolean unpack(container packedClass)

{

return true;

}

Step 3: Add Main() method to Execute class.

static void main(Args args)

{

Test_DialogField tmpDialogField = new Test_DialogField();

;

if (tmpDialogField.prompt())

tmpDialogField.run();

}

Step 4: The dialogPostRun() method should override like below. This will allow calling to the event methods.

public void dialogPostRun(DialogRunbase tmpdialog)

{

super(tmpdialog);

tmpdialog.dialogForm().formRun().controlMethodOverload(true);

tmpdialog.dialogForm().formRun().controlMethodOverloadObject(this);

}

Step 5: Add code to display dialog fields.

protected Object dialog(DialogRunbase tmpdialog, boolean forceOnClient)

{

;

dialog = super(tmpdialog,forceOnClient);

dialogCustId = dialog.addFieldValue(typeid(CustAccount),"Customer", "Customer");

dialoglName = dialog.addFieldValue(typeid(Name),"Name", "Name");

return dialog;

}

Step 6: When we have used Dialog field in the class, that Dialog field name in the System will appear with a different format. Its look like: fld<ID>_1. This ID value can be changed according to number of dialog filed which we have used. By using following step we can get exact Field ID & system Name.

· Run the class which you created

· Right Click on the Customer field & select “Setup”

· You will get below form. I have coloured Dialog Filed System name by RED Colour. In my example System name of the Customer Dialog Field is Fld1_1.

This System Name we should use to write our “modified” method. Then it will call whenever a value of the dialog control with ID 1 is modified. In our case it is Customer ID field.

public boolean fld1_1_modified()

{

FormStringControl control = dialog.formRun().controlCallingMethod();

boolean isFieldModified;

;

isFieldModified = control.modified();

if(isFieldModified)

{

dialoglName.value(custTable::find(control.text()).Name);

}

return isFieldModified;

}

When you execute the class & select a customer Id, then above method will call & return the customer Name to other dialog box.

Hope you got an idea about overriding the Dialog Field methods in Dynamics AX... Enjoy in Dynamics AX World.