Monday, July 23, 2012

Copying License in Dynamics Ax

Axapta stores the License data in the following two tables.
1.SysLicenseCodeSort
2.SysConfig
So if you copy data of these tables(from Running instance) and import at your instance , this will serve your purpose.

X++ code to create and post Inventory Movement Journal

Following is the sample job to show how we can create and post movement journal by
making use of available api's in the Dynamics Ax.
static void createMovJournal(Args _args)
{ InventJournalTable journalTable;
InventJournalTrans journalTrans;
InventJournalTableData journalTableData;
InventJournalTransData journalTransData;
InventTable inventTable;
InventDim inventDim;
Counter cnt;
InventJournalCheckPost journalCheckPost = new InventJournalCheckPost();
;
journalTableData = JournalTableData::newTable(journalTable);
journalTransData = journalTableData.journalStatic().newJournalTransData(journalTrans,journalTableData);
// Init JournalTable
journalTable.clear();
journalTable.JournalId = journalTableData.nextJournalId();
journalTable.JournalType = InventJournalType::Movement;
journalTable.JournalNameId = journalTableData.journalStatic().standardJournalNameId(journalTable.JournalType);
journalTableData.initFromJournalName(journalTableData.journalStatic().findJournalName(journalTable.JournalNameId));
// Init JournalTrans
select firstonly inventTable;
for(cnt=1;cnt<10;cnt++)
{
journalTrans.clear();
journalTransData.initFromJournalTable();
journalTrans.TransDate = systemdateget() + 1 div 2;
journalTrans.ItemId = inventTable.ItemId;
journalTrans.Qty = 100;
journalTrans.CostAmount = 100;
// Dimension details
inventDim.InventLocationId = 'GW';
journalTrans.InventDimId = InventDim::findOrCreate(inventDim).inventDimId;
journalTransData.create();
}
journalTable.insert();
// Call the static method to post the journal
if(InventJournalCheckPost::newPostJournal(journalTable).validate())
InventJournalCheckPost::newPostJournal(journalTable).run();
}

X++ Code to find OnHand Stock for Item

In Dynamics Ax , use InventOnHand class for finding the stock of an item as shownbelow
static void findOnHand(Args _args)
{
InventDim inventDim;
InventDimParm inventDimParm;
Itemid itemid;
InventOnHand inventOnHand = new InventOnHand();
;
// take a sample item for testing
itemid = "20 MM RMC";
// take a combination of dimension , against which you want to find the stock
inventDim.InventLocationId = "GW";
//Set the flag for the selected dimensions as active.
inventDimParm.initFromInventDim(inventDim);
//initialize the inventonhand with item,dimension and dim paramter
inventOnHand.parmItemId(itemid);
inventOnHand.parmInventDim(inventDim);
inventOnHand.parmInventDimParm(inventDimParm);
// Retrieve the onhand info
info(strfmt("Available Physical: %1",
inventOnhand.availPhysical()));
info(strfmt("On order: %1",inventOnhand.onOrder()));
}

X++ code to find the Stock of Item by Date

static void findOnHand_ByDate(Args _args)
{
InventDim inventDim;
InventDimParm inventDimParm;
Itemid itemid;
InventOnHand inventOnHand = new InventOnHand();
InventSumDateDim inventSumDateDim;
TransDate transDate;
;
// take a sample item for testing
itemid = "20 MM RMC";
transDate = 13\01\2010;
// take a combination of dimension , against which you want to find the stock
inventDim.InventLocationId = "GW";
//Set the flag for the selected dimensions as active.
inventDimParm.initFromInventDim(inventDim);
//initialize the inventSumDateDim with Date,item,dimension and dim paramter
inventSumDateDim = InventSumDateDim::newParameters(transDate,
itemid,
inventDim,
inventDimParm);
// Retrieve the onhand info
info(strfmt("PostedQty: %1",inventSumDateDim.postedQty()));
info(strfmt("DeductedQty: %1",inventSumDateDim.deductedQty()));
info(strfmt("ReceivedQty: %1",inventSumDateDim.receivedQty()));
}

X++ code to create a customized lookup on form

Override the lookup method on Formdatasource field(on which you want to show lookup) , and copy the following code to your method.
Comment the super() method in the lookup.
public void lookup(FormControl _formControl, str _filterStr)
{
SysTableLookup sysTableLookup; // systemclass to create //customlookup
Query query;
QueryBuildDataSource qbd;
;
sysTableLookup = SysTableLookup::newParameters(
tablenum(InventTable),
_formcontrol);
// Construct query on the table,
// whose records you want to show as lookup.
query = new Query();
qbd = query.addDataSource(tablenum(InventTable));
qbd.addRange(fieldnum(InventTable,ItemType)).value(SysQuery::value(enum2str
(ItemType::Item)));
// add the fields to the lookup list
sysTableLookup.addLookupfield(fieldnum(InventTable,ItemId));
sysTableLookup.addLookupfield(fieldnum(InventTable,ItemName));
// pass the query as parameter
// system will show the records in the lookup
// as per your query
sysTableLookup.parmQuery(query);
sysTableLookup.performFormLookup();
}

Get AX4.0 look and feel back in Ax2009

You all might be aware that all forms in Ax2009 are behaving like independent application forms.i,e When you open any form it will get open outside the application.
So following are the two solutions to open forms in same workspace as in Ax4.0
1. Change the formdesign property windowtype(from standard to workspace).this you have to do for all the forms which is time cosuming.
2. Or else Add following line in the init method of SysSetupFormRun class. before super() as shown in the following code
public void init()
{
//at run-time you are setting property to workspace.
this.form().design().windowType(FormWindowType::Workspace);
super();
SysSecurityFormSetup::loadSecurity(this);
this.dimensionFieldCtrls();
this.inventStorageDimFieldCtrls();
if (this.isWorkflowEnabled())
{
workflowControls = SysWorkflowFormControls::construct(this);
workflowControls.initControls();
}
}

X++ code to hide content pane in ax2009

This is for developers , not for endusers.As you know it will irritate during developemnt since it is appearing on top of all windows when we open form.
static void hideContentPaneWindow(Args _args)
{
#WinApi
HWND contentPane = WinApi::findWindowEx(WinAPI::findWindowEx(infolog.hWnd(),
0, 'MDIClient', ''),0,'ContentFrame','' );
;
if (contentPane)
WinApi::ShowWindow(contentPane,#SW_HIDE); // To restore use #SW_RESTORE
}

How to Use Temporary Table in Form

Temporary table(Table whose property temporary set to "yes") is not persistent media , so at run-time you have to populate the temporary table and attach the same to the form/report. For illustration purpose ,I am using inventTable data and attaching the items whose group is Parts.
Steps
1. Create temporary table as TmpTestTable with 3 fields(ItemId,Itemname,ItemGroup).
2. Create a form as TempTestTable and attach the table as datasource
3. Create a new method on the form and copy the following code
TmpTestTable populateRecords(ItemGroupId _itemGroupId)
{
TmpTestTable tmpTable;
InventTable inventTable;
;
while select inventTable
where inventTable.ItemGroupId == _itemGroupId
{
tmpTable.Itemid = inventTable.ItemId;
tmpTable.ItemName = inventTable.ItemName;
tmpTable.Itemgroup = inventTable.ItemGroupId;
tmpTable.insert();
}
return tmpTable;
}
4. Call the above method in init() after super as below public void init()
{
super();
// Call the setTmpData method to attach records to datasource
TmpTestTable.setTmpData(element.populateRecords("Parts"));
}

How to use Dialog in Dynamics Ax.

If you came accross a requirement , where you need to collect the information and then executes a task . In such scenario Please make use of RunBase class.
Advantage of RunBase class
1. It provides dialog for presenting and collecting the information from user.
2. Pack/Unpack methods , for storing the last value entered by the user.
3. Progress bar ,for long time process where in you can show a progress bar.
4. Validate method , to validate the data entered by the user in the dialog.
you can refer tutorial in AOT->Classes->tutorial_RunBaseForm .

X++ code to identify multiple selected records in Grid

Steps : 1. Create a new method on form and copy the following code. 2. Next create a button on form . and call the method on the button click event. (for the button property makesure the Multiselect should be set to yes , or else by default for multiple selection system will disable the buttons)
void checkSelectedRecords()
{
InventTable inventLocal;
;
//getFirst method gets all the selected records in the grid
inventLocal = InventTable_ds.getFirst(true);
while (inventLocal)
{
info(strfmt("You selected Item %1",inventLocal.ItemId));
// get the next selected record
inventLocal = InventTable_ds.getNext();
}
}