Terminology - MS AX Technical
Write:
This method is invoked when a user inserts a new
record or updates an existing one.
If there are several data sources on a form and they
are joined then the sequence of methods invoked on "save" is
something like this:
parent_ds.validateWrite()
child1_ds.validateWrite()
child2_ds.validateWrite()
child1_ds.write()
child2_ds.write()
parent_ds.write()
Validate
write:
Determines whether data is valid and ready to be
written.
Returns true if data is valid;
otherwise, false.
This method is called from FormDataSource.write.
If false is returned, the write operation is aborted and an error
message is displayed.
This method will get to fire when we update a
record.
Insert
& doInsert:
Insert method is the normal method which get called
when data insertion occur in table. Whereas doInnsert is the forceful insertion
in to AX Tables I.e., it bypasses all the validation when inserting in to
tables.
Ø
Calling DoInsert ensures that
any Axapta X++ code written in insert method of the record is not executed.
Ø
Calling Insert always executes
the Axapta X++ code written in the Insert method of the record.
InitValue:
This method get fired while creating new record to
initialize a value, here I am assigning user id to the userID field.
public void initValue()
{
super();
this.UserId = curuserid();
}
public void initValue()
{
super();
this.UserId = curuserid();
}
ModifiedField:
Each time the value of a field is changed the method
modifiedField() is called. It is useful to initialize the values of other
fields if the value of the current field is changed.
Example (2): Let’s now override modifiedField method
for MyFirstTable and target is to set CurrencyCode to null when CustGroupId is
modified.
public void modifiedField(fieldId _fieldId)
{
switch(_fieldId)
{
case fieldnum(MyFirstTable, custGroupId):
this.CurrencyCode="";
break;
default:
super(_fieldId);
}
}
After adding this method, open table MyFirstTable
using Table browser and try to modify custGroupId of an existing record, then
you will notice that CurrencyCode is immediately set to blank.
ModifiedField() receives the field number of the
active field as parameter. A switch statement is used to check which field is
active. If none of the checked fields are active the super() call is executed
instead.
Orig():
A wonderful feature in Dynamics Ax is when a field
value is modified, it is possible to re-call the value before the field was
modified. This is made possible using orig() method. The field values
can retain their last committed value. The method orig() is used to
get the stored value. Orig() will return an instance of the current
table.
A single field value from orig() is retained by specifying the field. And When the record is committed orig() will be updated.
A single field value from orig() is retained by specifying the field. And When the record is committed orig() will be updated.
Syntax: print this.orig().custCurrencyCode;
ValidateField:
Method validateField() is used for validation only
and will return true or false. If the return value is false, the application
user will be prevented to continue changing a field value.
Example (3): Let’s override validateField for
MyFirstTable to verify the condition that CustName must be have >3
characters.
public boolean validateField(fieldId
_fieldIdToCheck)
{
boolean ret;
ret =
super(_fieldIdToCheck);
if (ret)
{
switch (_fieldIdToCheck)
{
case fieldnum(MyFirstTable,
custName):
if
(strlen(this.custName) <= 3)
ret
= checkFailed("Customer name must be longer than 3 characters.");
}
}
return ret;
}
After adding this method, open table MyFirstTable
using Table browser and press Ctrl+N, in the new record try to enter less than
3 characters for field custName, Ax will throw warning message stating
“Customer name must be longer than 3 characters.” And you will be asked to
enter value again. Thus we validate the data to be entered for a specific
field.
ValidateWrite:
Method validateWrite() will just check mandatory
fields and is triggered when the record . Checks made by validateWrite() are
the same as the super() call in validateField().So if your condition is not
related to the value an application user enters in a specific field, you should
put the validation in validateWrite().
ValidateDelete:
When deleting a record the method validateDelete()
is first executed. If true, the method delete() will be called.
Polymorphism:
Polymorphism is not the same as method overloading
or method overriding. Polymorphism is only concerned with the application of
specific implementations to an interface or a more generic base class. Method
overloading refers to methods that have the same name but different signatures
inside the same class. Method overriding is where a subclass replaces the
implementation of one or more of its parent's methods. Neither method
overloading nor method overriding are by themselves implementations of
polymorphism.
Polymorphism in the context of object-oriented programming, is the ability of one
type, A, to appear as and be used like another type, B.
So, basically, any RunBaseBatch extension class (the
ones you use to process stuff in AX) is an example of polymorphism in AX.
Because they all call the methods of the base class as if they were their own.
And also method overloading is not supported in X++.
Super:
Super() is a call to the overriden method concerned
in the super or parent class.
For the click event it does not serve any purpose
since there is no change in functionallity if you remove it and you will not
get any error.
For example:
if you create a class myCLASS1 and then inherit from
it and override a method on it the call to super will execute the code from the
inherited class.
If you remove super that code will not be executed
and you may write different code for this method in the child class.
Display
method:
A display method is not a physical field in a table
but rather a method of displaying information from another table or source. It
appears like a "normal" field and it can be used in forms and
reports.
Usage
A display method can be created on either a table
(in which case it is available for all forms using that table), or on the datasource of a specific form (in which
case it is available only on that form).
Display methods must be created using a specific
signature, which varies depending on the location of the method.
Display
methods on tables
When declared on a table, display methods must be
preceded with the keyword display and expect no parameters. The
following example is a standard display method from the SalesTable table.
display CustName
customerName()
{
return this.partyTable_CustAccount().Name;
}
Display
methods on datasources
When declared on a form datasource, display methods must have one
non-optional parameter. The following example is from the PurchEditLines form
in standard Ax 2012. The parameter is a buffer of the same type as that of the
datasource on which the method is declared. It is essential as, when viewing a
grid on a form, the method must know for which row the return value is to be
calculated.
//BP Deviation
documented
display ImageRes
backOrder(PurchParmLine _purchParmLine)
{
if
(-InventTrans::backOrderQtyIssue(_purchParmLine.ItemId,
_purchParmLine.InventDimId) > 0)
return #Imageinfo;
return 0;
}
Edit method:
An edit method is not a physical field in a table
but rather a method of entering and displaying information from another table
or source. Like a display method it
appears like a "normal" field and it can be used in forms and
reports. For more information about display methods go to MSDN.
Usage
An edit method can be created on either a table (in
which case it is available for all forms using that table), or on the datasource of a specific form (in which
case it is available only on that form).
Edit methods must be created using a specific
signature, which varies depending on the location of the method.
Edit
methods on tables
When declared on a table, edit methods must be
preceded with the keyword edit and expect exactly two parameters. The
following example is a standard edit method from the SalesTable table.
Parameter _set indicates whether the edit
method is being used to show (_set = false)
or modify (_set = true) data. This is set automatically by the
caller form.
Parameter _exchRate in the example below
should be declared using the same type as the method return value, and contains
the new value to be set when _set is true. Then _set is false then
that value should be ignored by the method programmer.
Irrespective of the value of _set, the method
must always return the current calculated value.
public edit
SalesFixedExchRate editFixedExchRate(boolean _set, SalesFixedExchRate
_exchRate)
{
ExchangeRateHelper exchangeRateHelper =
ExchangeRateHelper::newCurrency(Ledger::primaryLedger(CompanyInfo::findDataArea(curext()).RecId),
this.CurrencyCode);
if (_set)
{
this.FixedExchRate =
exchangeRateHelper.prepareExchangeRateForStorage(_exchRate);
}
else
{
_exchRate =
exchangeRateHelper.displayStoredExchangeRate(this.FixedExchRate);
}
return _exchRate;
}
Edit
methods on datasources:
On a form datasource, an additional parameter is
required indicating against which record the method should operate. In the
following example from standard Ax 2012 it is the _purchParmTable parameter.
The order of the parameters is significant and must be followed exactly.
//BP Deviation
documented
edit boolean paymentIdValidated(boolean set,
PurchParmTable
_purchParmTable,
NoYes _validated)
{
NoYes
validated;
if (_purchParmTable.RecId)
{
if (!paymentIdValidatedSet)
paymentIdValidatedSet = new
Set(typeName2Type(extendedtypestr(recId)));
if (set)
{
validated = _validated;
if (_validated)
paymentIdValidatedSet.add(_purchParmTable.RecId);
else
paymentIdValidatedSet.remove(_purchParmTable.RecId);
}
else
{
validated =
paymentIdValidatedSet.in(_purchParmTable.RecId);
}
}
else
{
validated = NoYes::No;
}
return validated;
}
Table
type: TempDB & InMemory:
In AX 2012 we have 2 different type of temporary tables.
In Microsoft Dynamics AX, one type of temporary
table is a TempDB table. We call them TempDB tables because their TableType property
value is TempDB. This value comes from the TableType::TempDB enum
value. The TableType property value can be set at AOT > Data
Dictionary > Tables > MyTempDBTable > Properties > TableType.
All types of temporary tables are automatically
dropped by the system when the table variable in X++ goes out of scope. A
TempDB table is not dropped when you set its record buffer variable to null.
TempDB tables are a different type of temporary
table than InMemory tables.
InMemory - the type of
temporary table which existed in the previous versions of Dynamics Ax.
Such tables are held in memory and written to a local disk file once they
grow beyond a certain point
Such tables are held in memory and written to a local disk file once they
grow beyond a certain point
TempDB - a new option in
Ax 2012. They are "physical" temporary tables held in
the SQL Server database.
the SQL Server database.
The new TempDB tables operate in a similar
manner to InMemory tables but support more features of standard
physical tables:
Ø More powerful joins with physical tables are possible, and are properly supported
by the database.
Ø Can be either per company or global.
Ø Can be used from Enterprise Portal by using .NET
Business Connector.
Ø Can have foreign key columns.
Ø Can have indexes columns.
Ø Support for normal tts transactions.
Ø Stores TempDB table in database.
Ø Usable as a query: AOT > Query
To create a new instance link (populating
data/copying reference) from one table instance
variable to the other with Temporary type tables:
variable to the other with Temporary type tables:
For more details on TempDB capabilities,
Limitations, How to use, Its lifetime please check here –
Container
and TempTable:
Microsoft Dynamics AX supports a special data type
called a container. This data type can be used just as you would use a
temporary table.
Data in containers are stored and retrieved
sequentially, but a temporary table enables you to define indexes to speed up
data retrieval. Containers provide slower data access if you are working with many
records. However, if you are working with only a few records, use a container.
Another important difference between temporary
tables and containers is how they are used in method calls. When you pass a
temporary table into a method call, it is passed by reference. Containers are
passed by value. When a variable is passed by reference, only a pointer to the
object is passed into the method. When a variable is passed by value, a new
copy of the variable is passed into the method. If the computer has a limited
amount of memory, it might start swapping memory to disk, slowing down
application execution. When you pass a variable into a method, a temporary
table may provide better performance than a container.
Refresh:
This method basically refreshes the data displayed
in the form controls with whatever is stored in the form cache for that
particular datasource record. Calling refresh() method
will NOT reread the record from the database. So if changes happened
to the record in another process, these will not be shown after
executing refresh().
Reread:
Calling reread() will query the
database and re-read the current record contents into the datasource form
cache. This will not display the changes on the form until a redraw of the grid
contents happens (for example, when you navigate away from the row or re-open
the form).
You should not use it to refresh the form data if you have through code added or removed records. For this, you would use a different method described below.
You should not use it to refresh the form data if you have through code added or removed records. For this, you would use a different method described below.
Research:
Calling research() will rerun the
existing form query against the database, therefore updating the list with
new/removed records as well as updating all existing rows. This will honor any
existing filters and sorting on the form that were set by the user.
Research(true)
The research method starting with
AX 2009 accepts an optional Boolean argument _retainPosition. If
you call research(true), the cursor position in the grid will be
preserved after the data has been refreshed. This is an extremely useful
addition, which solves most of the problems with cursor positioning (findRecord method
is the alternative, but this method is very slow).
ExecuteQuery:
Calling executeQuery() will also
rerun the query and update/add/delete the rows in the grid. The difference in
behavior from research is described below.
ExecuteQuery should be used if you have modified the query in your code and need to refresh the form to display the data based on the updated query.
ExecuteQuery should be used if you have modified the query in your code and need to refresh the form to display the data based on the updated query.
formDataSource.queryRun().query()
vs. formDataSource.query()
An important thing to mention here is that the form
has 2 instances of the query object - one is the original datasource query
(stored in formDataSource.query()), and the other is the currently
used query with any user filters applied (stored in formDataSource.queryRun().query()).
When the research method is called, a new instance of the queryRun is created, using theformDataSource.queryRun().query() as the basis. Therefore, if the user has set up some filters on the displayed data, those will be preserved.
When the research method is called, a new instance of the queryRun is created, using theformDataSource.queryRun().query() as the basis. Therefore, if the user has set up some filters on the displayed data, those will be preserved.
Difference
b/w Abstract class and Interfaces(C#)
An abstract class may contain complete or incomplete
methods. Interfaces can contain only the signature of a method but no body.
Thus an abstract class can implement methods but an interface cannot implement
methods.
An abstract class can contain fields, constructors, or destructors and implement properties. An interface cannot contain fields, constructors, or destructors and it has only the property's signature but no implementation.
An abstract class cannot support multiple inheritance, but an interface can support multiple inheritance. Thus a class may inherit several interfaces but only one abstract class.
A class implementing an interface has to implement all the methods of the interface, but the same is not required in the case of an abstract Class.
Various access modifiers such as abstract, protected, internal, public, virtual, etc. are useful in abstract Classes but not in interfaces.
An abstract class can contain fields, constructors, or destructors and implement properties. An interface cannot contain fields, constructors, or destructors and it has only the property's signature but no implementation.
An abstract class cannot support multiple inheritance, but an interface can support multiple inheritance. Thus a class may inherit several interfaces but only one abstract class.
A class implementing an interface has to implement all the methods of the interface, but the same is not required in the case of an abstract Class.
Various access modifiers such as abstract, protected, internal, public, virtual, etc. are useful in abstract Classes but not in interfaces.
Abstract classes are faster than interfaces.
Thanks, Happy Daxing!! JJ
Leave a Comment