blog for Dynamics Axapta

Archive for the ‘Microsoft Dynamics AX 2009’ Category

Export your AOT Custom Objects Automatically

Hi,

Here I have posted a job to export all our newly created projects / jobs / any AOT objects as XPO automatically.

static void VAS_ExportXPO(Args _args)
{
#AOT

FileIoPermission perm;
ProjectListNode projectListNode;
ProjectNode projectTreeNode;
TreeNode treeNode, jobTreeNode;
TreeNodeIterator iterator, jobIterator;
str projName;
str exportProjName = ‘VAS_’;
str jobName;
str exportJobName = ‘VAS_’;
int noOfProjects;
int noOfJobs;
str folderpathProj, folderpathJobs;

#define.ExportMode(“w”)

;
folderpathProj = strfmt(@’C:\Vasanth Arivali\XPO Backup\%1\SharedProject’, date2str(today(), 321, 2, 3, 2, 3, 4));
folderpathJobs = strfmt(@’C:\Vasanth Arivali\XPO Backup\%1\Jobs’, date2str(today(), 321, 2, 3, 2, 3, 4));
WINAPI::createDirectoryPath(folderpathProj);
WINAPI::createDirectoryPath(folderpathJobs);

perm = new FileIoPermission(folderpathProj, #ExportMode);
if (perm == null)
{
return;
}
perm.assert();

projectListNode = SysTreeNode::getSharedProject();
iterator = projectListNode.AOTiterator();

treeNode = iterator.next();
while (treeNode)
{
projName = treeNode.AOTname();
if ( exportProjName == substr(projName, 1, 8))
{
// BP deviation documented.
treeNode.treeNodeExport(folderpathProj + ‘\\SharedProject_’ + projName + “.xpo”);
noOfProjects++;
}
treeNode = iterator.next();

}

jobIterator = TreeNode::findNode(@’\Jobs’).AOTiterator();
jobTreeNode = jobIterator.next();
while (jobTreeNode)
{
jobName = jobTreeNode.AOTname();
if ( exportJobName == substr(jobName, 1, 8))
{
// BP deviation documented.
jobTreeNode.treeNodeExport(folderpathJobs + ‘\\Job_’ + jobName + “.xpo”);
noOfJobs++;
}
jobTreeNode = jobIterator.next();

}

CodeAccessPermission::revertAssert();

if (noOfProjects > 0)
info(strfmt(‘%1 Projects exported sucessfully’, noOfProjects));
if (noOfJobs > 0)
info(strfmt(‘%1 Jobs exported sucessfully’, noOfJobs));
}

Hope this will help you guys.

// Vasanth Arivali

Auto comments on our customization codes by Editor Script Class

Hi Friends,

Here I have posted the code for auto comments by amending Editor Scripts class.

Adding auto script CODE comments
// Changes: XYZ to your intial name
public void addCommentsCODE(Editor _e)
{
int startLine = _e.selectionStartLine();
int endLine = _e.selectionEndLine();
str prefixCompany = “CONTOSO”;
str developerID;
str tagStart;
str tagEnd;
;

switch (curUserId())
{
case “vasan”: developerID = “Vasanth”;
break;
case “steve”: developerID = “Steven”;
break;
default:
developerID = “XYZ”;
}

tagStart = strFmt(“//–> %1 modified on %2 %3 by %4: %5 ~ mod description\n”,
enum2str(currentAOLayer()),
date2str(today(), 321, 2, 3, 3, 3, 4), time2str(timeNow(), 1, 1),
prefixCompany,
developerID
);
tagEnd = strfmt(“//<– by %1\n”, prefixCompany);

_e.gotoCol(1);
_e.unmark();

_e.gotoLine(startLine);
_e.insertLines(tagStart);

_e.gotoLine(endLine+2);
_e.insertLines(tagEnd);
}

Once done, got to code window, right click -> scripts -> you find the method created. Hope it will help you.

// Vasanth Arivali

Add Query Range for Same Table with Different DataSources

Hi Friends,

Here I have posted the code(not entire job/program) for adding multiple ranges/relations with the same table using Query object

Code Starts Here:

QueryRun qr;

//1st DataSource

QueryBuildDataSource qbdTableSourcefromQuery; // get query from the AOT Query which used by System in SysQuery()
QueryBuildDataSource qbdTableSourcefromCode; // newly added Query for Account Number Range

qr = new QueryRun(“your Query”);

qbdCustTableSourcefromQuery = SysQuery::findOrCreateDataSource(qr.query(), tableNum(TableName1));

SysQuery::findOrCreateRange(qbdCustTableSourcefromQuery, fieldNum(TableName1, FieldName)).value(“QueryValue”);

//2nd DataSource

qbdCustTableSourcefromCode = qbdCustTableSourcefromQuery.addDataSource(tableNum(TableName1), “TableNameNew”);
qbdCustTableSourcefromCode.relations(true);
qbdCustTableSourcefromCode.joinMode(JoinMode::ExistsJoin);
qbdCustTableSourcefromCode.addRange(fieldNum(TableName1, FieldName)).value(queryValue(“QueryValue”));

 

// Vasanth Arivali

Go To Main Table Functionality in Axapta

Hi All,

We all know about “Go To Main Table” Option in our Axapta Forms and Tables. Here I wrote one sample for how to get that functionality in our forms or table. This is done by three ways:

1) By EDT Relations

2) By using JumpRef method

3) By using FormRef property in Table

EDT Relations:

If you use an EDT in tables which have relation with some other table fileds, that time you can able to navigate the main table or main form.

FormRef Property:

Select the Table and go to properties and select the required form in the FormRef property.

JumpRef method:

If you are not having that option, simply write a override the JumpRef method in a field of DataSource or in a Form Control. Here i show you a sample jumpRef method code:

public void jumpRef()
{
Args            args;
MenuFunction    menuFunction;
;

args = new Args();
menuFunction = new MenuFunction(menuitemDisplayStr(“FormName”), MenuItemType::Display);
args = new Args(menuFunction.object());
args.caller(element);
args.record(“RecordName”); // to be a datasource which added in the current form
menuFunction.run(args);
}

In the form init() which we called here, we have to check the condition whether the form is called by any dataset or not.

Thanks & Regards

Vasanth Arivali

Using Regular Expression in Ax 2009

Hi Guys,

Here i posted a small job , to explain how we use regular expressin in Axapta. Try it.

static void RegularExpression_Test()

{

int nameLength,myStringLength;

str myname = “Vasanth”;

str myString = “1234″;

str formatString , formatString1;

System.Text.RegularExpressions.Regex regEx;

System.Text.RegularExpressions.Regex regEx1;

System.Text.RegularExpressions.Match regMatch;

InteropPermission permission = new InteropPermission(InteropKind::ClrInterop);

boolean retVal, retVal1;

;

nameLength = strLen(myname);

myStringLength = strLen(myString);

formatString   = strfmt(@”^[0-9]{%1}”, myStringLength);

formatString1   = strfmt(@”^[a-zA-Z ]{%1}”, nameLength);

permission.assert();

//BP Deviation documented

regEx = new System.Text.RegularExpression.Regex(formatString);

regEx1 = new System.Text.RegularExpression.Regex(formatString1);

regMatch = regEx.Match(myString);

retVal = regMatch.get_Success();

print retVal; // Returns True;

regMatch = regEx1.Match(myname);

retVal1 = regMatch.get_Success();

print retVal1 // Returns True;


}

Thanks & Regards,

Vasanth Arivali

Dynamic Query Using Aggregative Functions and Joins

Hi All,

Here i written the code to use the Aggregate functions and Joins inDynamic Query in spite of using normal Select statement in Ax 2009

Normal Select Statement:

while select sum(qty) from inventTrans where inventTrans.ItemId ==

“OL-2500” join inventDimgroup by inventBatchId where

inventDim.InventDimId == inventTrans.InventDimId

{

// Our Code Here

}

Dynamic Query:

static void Vasanth_Query_Eg1(Args _args)

{

Query                   query;

QueryBuildDataSource    queryBuildDataSource;

QueryBuildRange         queryBuildRange;

QueryRun                queryRun;

Qty                     total;

InventTrans             inventTrans;

;

query = new Query();    queryBuildDataSource    = query.addDataSource(tableNum(InventTrans));

queryBuildDataSource.addSelectionField(fieldNum(InventTrans,Qty),

SelectionField::Sum);

queryBuildDataSource.orderMode(OrderMode::GroupBy);

queryBuildRange         = queryBuildDataSource.addRange(fieldNum(InventTrans,ItemId));

queryBuildDataSource    = queryBuildDataSource.addDataSource(tableNum(InventDim));

queryBuildDataSource.orderMode(OrderMode::GroupBy);

queryBuildDataSource.addSortField(fieldNum(InventDim,InventBatchId));

queryBuildDataSource.relations(true);

queryRun = new QueryRun(query);

if (queryRun.prompt())

{

while (queryRun.next())

{

inventTrans = queryRun.get(tableNum(InventTrans));

total = inventTrans.Qty;

}

}

info(strFmt(“Quantity: %1″, total));
}

Using AOT Query Object in X++ Code

Hi,

Here i posted the code to use the AOT Query Object in our X++ code.

Steps:

1) Create a AOT Query Object as your requirement.

2) Create a Job and paste the below code to check the Query Object.

static void ExecuteAOTQuery(Args _args)

{

QueryRun queryRun;

Counter totalRecords;

;

queryRun = new QueryRun(queryStr(CreatedAOTQueryName));

if (queryRun.prompt())

{

while (queryRun.next())

{

totalRecords++;

}

}

info(strFmt(“Total Records : %1”, totalRecords));

}

 

Create LookUps Using X++

Hi All,

Here I create Lookups using X++ Code(without Ax Table or EDT relation). For that i override a String(Text) Control’ s lookup method.

public void lookup()

{
//super();

// Added by Vasanth Arivali

// Declaration
Query   LookupQuery    =   new Query();

QueryBuildDataSource     LookupQueryBuildDataSource;

QueryBuildRange                  LookupQueryBuildRange;
SysTableLookup CustomSysTableLookup =       SysTableLookup::newParameters(tableNum(InventTable), this);

;

// Add fields that you want in Lookups

CustomSysTableLookup.addLookupField(fieldNum(InventTable, ItemId));

CustomSysTableLookup.addLookupField(fieldNum(InventTable,ItemName));

CustomSysTableLookup.addLookupField(fieldNum(InventTable,ItemGroupId));

CustomSysTableLookup.addLookupField(fieldNum(InventTable,NameAlias));

CustomSysTableLookup.addLookupField(fieldNum(InventTable,ItemType));

CustomSysTableLookup.addLookupField(fieldNum(InventTable,DimGroupId));

// Add DataSource, Range and Value

LookupQueryBuildDataSource =

LookupQuery.addDataSource(tableNum(InventTable));

LookupQueryBuildRange=

LookupQueryBuildDataSource.addRange(fieldNum(InventTable,ItemVisibility));

LookupQueryBuildRange.value(queryValue(NOYESCOMBO::Yes));

// Execute the Query

CustomSysTableLookup.parmQuery(LookupQuery);

CustomSysTableLookup.performFormLookup();
// Added by Vasanth Arivali

}

 

Find the Table Name in Dynamics Ax 2009

Hi,

Here i write a sample code to find the Table Name of Ax Tables using the TableId.

 

static void findTables(Args _args)

{

Dictionary            dictionary;

TableId                                  tableId;

tableName         tableName;

;

 

dictionary            =             new Dictionary();

// tableId             =             dictionary.tableNext(0);

tableId                  =             359;       //366; //62;

tableName         =             dictionary.tableName(tableId);

 

info(strfmt(“%1 – %2”,int2str(tableId), tableName));

 

//while (tableId)

//{

// tableId = dictionary.tableNext(tableId);

// tableName = dictionary.tableName(tableId);

//}

 

}

 

Thank You,

Vasanth Arivali.

 

Argument Passing in Dynamics Ax 2009

Hi,
Here a sample code to pass argument to one form to another form and using of Args() class.
Steps:
1) Create two Forms named FormA and FormB
2)Use the EmplTable as the Datasource of both forms
3)Design FormA with one Grid and add 4 data fields to the Grid(EmplId,DEL_Name,Grade,EmplStatus…..)
4)Assign the datasource for the grid and the data fields
5)Add a Button in FormA
6)Override the Clicked() method and write the below code:
void Clicked()
{
Args    _args;
FormRun _formRun;
EmplId   _empId;
;

_empId = EmplTable.EmplId;  // Selected employee id in the Grid is assigned to the variable which is pass to the next form_args = new Args(); // creating a object for args class
_args.name(formstr(VA_FormB));  // Form Menuitem
_args.caller(this);  // Form Caller(Current Form is mentioned as this)_args.parm(_empId); // Employee Number is passed to next form[but parm() is not a best practise]
_args.record(EmplTable); // Table name is passed

_formRun = ClassFactory.formRunClass(_args); //new FormRun(_args);   // Creating object for FormRun
_formRun.init();   // Form Initialization for Load
_formRun.run();  // Form Run for process
_formRun.wait(); // Form Wait for Display
}

7) Open the Second Form – FormB
8) Add one Grid Control and set the Data Source is EmplTable
9) Add 4 data fields as same in the Form A
10)Now Override the Init() of Form
public void init()
{

parmid      _parmId;
EmplTable   _EmplTable;
//     DictTable   _dictTable;    FormBuildDataSource   _ds;    FormBuildGridControl frmGrid; // These are for dynamic Form creation so leave it
_parmId =  element.args().parm(); // Getting the argument value from the Caller

//info(int2str(element.args().record().TableId));
if(!element.args().caller())   // Check the form is called by caller or directly, if directly it throw error
throw error(“Cant Run Directly”);
if(element.args().record().TableId == tablenum(EmplTable))   // check if the sent Table and the Current form table are equal or not
{

//        _EmplTable = element.args().record();  // Assign the Received Table name to Local Variable
//_dictTable = new DictTable(element.args().record().TableId);  // leave it , is used for Dynamic Form Creation
//_ds = form.addDataSource(_dictTable.name());  // leave it , is used for Dynamic Form Creation

//_ds.table(_dictTable.id());   // leave it , is used for Dynamic Form Creation
//frmGrid = form.addControl(FormControlType::Grid, “Grid”);   // leave it , is used for Dynamic Form Creation

//frmGrid.dataSource(_ds.name());   // leave it , is used for Dynamic Form Creation
//info(strfmt(“%1     %2”,_EmplTable.EmplId,_EmplTable.DEL_Name));

//frmGrid.addDataField(_ds.id(),fieldnum(EmplTable, DEL_Name));  // leave it , is used for Dynamic Form Creation
//        EmplTable_EmplId.dataSource(_EmplTable);   // leave it , is used for Dynamic Form Creation

//        EmplTable_EmplId.dataField(fieldnum(EmplTable,EmplID));   // leave it , is used for Dynamic Form Creation

//        EmplTable_DEL_Name.dataSource(_EmplTable);   // leave it , is used for Dynamic Form Creation

//        EmplTable_DEL_Name.dataField(fieldnum(EmplTable,EmplId));  // leave it , is used for Dynamic Form Creation//        EmplTable_DEL_Email.dataSource(_EmplTable);   // leave it , is used for Dynamic Form Creation

//        EmplTable_DEL_Email.dataField(fieldnum(EmplTable,EmplId));   // leave it , is used for Dynamic Form Creation

super();  // Form Initialization
}
else
{
info(“DataSet Not Received”);  // throw error
}
}

11)Override the Init() of the DataSource

public void init()
{

switch(element.args().dataset())// get the table id sent by caller
{
case tablenum(EmplTable):  // check the table if matches with this tableid
{
_EmplID  =   element.args().parm();  // get the argument value
query   = new Query();            queryBuildRangeProj =                                          query.addDataSource(tablenum(EmplTable)).addRange(fieldnum(EmplTable,EmplId));          // query build for the form to display
queryBuildRangeProj.value(_emplId); // Criteria for the form
EmplTable_ds.query(query); // execution of the query
break;
}
}

super(); //datasource  initialization on the form based on the criteria
}

12) Save it, and create two menu items for each.
13) It is important to change the runon property of the FormB as CalledFrom.
14)Run the FormA and select an Employee Record and click the button.
15)The FormB opens with the Related information of the Selected Employee on form.

Thanks & Regards,
Vasanth Arivali