here we r validating to allow the marks field less than 100 only..
Form-DS->mothods->validateWrite()
boolean ret;
;
if(StuMarks.m1<=100)
{
ret=super();
}
else
{
info("Please enter less than 100 marks");
}
return ret;
This blog is for Dynamics AX (AXAPTA) Developers,this will help you for your development issues. This site contains some Microsoft Dynamics AX X++ Codes for use in your day to day use.
26 December 2010
20 December 2010
Convert the selected values from ax form to Word document template
Hi
Now you can create a user defined template and attach it to the Particular record using Document Handling feature.
Here we go
step 1: Open Microsoft Word, Create a Template / Design.
For Example: If the Field name is AccountName
Type Account Name in the word document and select Insert-> BookMark
In the Book mark Field give a name to refer that field in AX (ex: Account)
Step 2: Save the word document as a template (.dot or .dotx)
Step 3: Open AX, Basic->setup->Document Management -> Document Types
Step 4: Create New record, Type as Document, Class description as Create word document via COM, Group as Document.
Step 5: Click Options, Select the table name from the lookup (the table you want to attach the template)Ex: LedgerJournalTrans
Step 6: In the Template File field Browse and attach the template document u created in step 2.
Step 7: Click on the Fields Tab in the same form, create a new record, select the table name (same table name as step 5), Select the Data Field For Ex: Account Name
In the Book mark field enter the value, same u have given in the Word Template Bookmark. Click OK.
Step 8: Now create a Journal (EX: General Ledger -> Journals-> General Journal)
Step 9: Once u finished creating the Journal Lines, Select the Document Handling Icon in the tool bar.Create New ->Document(the name u have given in the step 4)
Step 10: Once u create the new document, the word template will open and the field value (Account Name) will be fetched in the document template. Like this u can add more fields and create bookmark and attach it with the Document types Form.
Regards
Praveen
Now you can create a user defined template and attach it to the Particular record using Document Handling feature.
Here we go
step 1: Open Microsoft Word, Create a Template / Design.
For Example: If the Field name is AccountName
Type Account Name in the word document and select Insert-> BookMark
In the Book mark Field give a name to refer that field in AX (ex: Account)
Step 2: Save the word document as a template (.dot or .dotx)
Step 3: Open AX, Basic->setup->Document Management -> Document Types
Step 4: Create New record, Type as Document, Class description as Create word document via COM, Group as Document.
Step 5: Click Options, Select the table name from the lookup (the table you want to attach the template)Ex: LedgerJournalTrans
Step 6: In the Template File field Browse and attach the template document u created in step 2.
Step 7: Click on the Fields Tab in the same form, create a new record, select the table name (same table name as step 5), Select the Data Field For Ex: Account Name
In the Book mark field enter the value, same u have given in the Word Template Bookmark. Click OK.
Step 8: Now create a Journal (EX: General Ledger -> Journals-> General Journal)
Step 9: Once u finished creating the Journal Lines, Select the Document Handling Icon in the tool bar.Create New ->Document(the name u have given in the step 4)
Step 10: Once u create the new document, the word template will open and the field value (Account Name) will be fetched in the document template. Like this u can add more fields and create bookmark and attach it with the Document types Form.
Regards
Praveen
16 December 2010
Microsoft Dynamics AX 2009 System Requirements
Microsoft Dynamics AX 2009 System Requirements click here
15 December 2010
Getting Data Without Declaring a Table Variable
Its Possible to get data from the database without declaring a table variables.
Static void Job3(Args _args)
{
// No Variables
;
print (select CustTable).AccountNum;
Pause;
}
Note the parentheses around the select statement. This tells the compiler to create a temporary, anonymous buffer to hold the record. The select statement uses the exact table name and is immediately followed by a field name to get a value from a field.
If you use this there’s no Intellisense to help you look up the field name because the editor doesn’t know the type of the anonymous buffer.
This technique is often used in exist() methods on tables.
Static void Job3(Args _args)
{
// No Variables
;
print (select CustTable).AccountNum;
Pause;
}
Note the parentheses around the select statement. This tells the compiler to create a temporary, anonymous buffer to hold the record. The select statement uses the exact table name and is immediately followed by a field name to get a value from a field.
If you use this there’s no Intellisense to help you look up the field name because the editor doesn’t know the type of the anonymous buffer.
This technique is often used in exist() methods on tables.
14 December 2010
13 December 2010
In runtime look up filter the duplicate values
In runtime look up filter the duplicate values click here
To send a mail with attachments using outlook in Ax
To send a mail with attachments click here:
sysInetMail::sendEMail
smmOutlookEMail
Form-smmEncyclopedia
--
static void sendEmail(Args args)
{
smmOutlookEMail smmOutlookEMail = new smmOutlookEMail();
Object smmSendEmail;
container c;
;
args = new Args();
args.name(formstr(smmSendEmail));
args.caller(smmOutlookEMail);
smmSendEmail = classfactory.formRunClass(args);
if (smmSendEmail)
{
smmSendEmail.init();
smmSendEmail.setEmailTos("aaa@gmail.com");
smmSendEmail.setEmailSubject("Sunil");
smmSendEmail.setAttachments(["D:\SUN\I & C.pdf"]);
smmSendEmail.run();
smmSendEmail.refreshControl();
smmSendEmail.wait();
}
}
sysInetMail::sendEMail
smmOutlookEMail
Form-smmEncyclopedia
--
static void sendEmail(Args args)
{
smmOutlookEMail smmOutlookEMail = new smmOutlookEMail();
Object smmSendEmail;
container c;
;
args = new Args();
args.name(formstr(smmSendEmail));
args.caller(smmOutlookEMail);
smmSendEmail = classfactory.formRunClass(args);
if (smmSendEmail)
{
smmSendEmail.init();
smmSendEmail.setEmailTos("aaa@gmail.com");
smmSendEmail.setEmailSubject("Sunil");
smmSendEmail.setAttachments(["D:\SUN\I & C.pdf"]);
smmSendEmail.run();
smmSendEmail.refreshControl();
smmSendEmail.wait();
}
}
08 December 2010
To make a form in select mode ( Form in Lookup)
Which form want to open in lookup
form->methods->init()
element.selectMode(StringEdit);
form->methods->init()
element.selectMode(StringEdit);
Add a value to Year in date
Add a value to Year in date
static void YearInDate(Args _args)
{
Date date1,date2;
int length,day,mth,years;
;
length = 2;
date1 = systemdateget();
day = dayofmth(Systemdateget());
mth = mthofyr(SystemDateget());
years = year(SystemDateget());
date2 = mkdate(day,mth,years+length);
print date2;
pause;
}
static void YearInDate(Args _args)
{
Date date1,date2;
int length,day,mth,years;
;
length = 2;
date1 = systemdateget();
day = dayofmth(Systemdateget());
mth = mthofyr(SystemDateget());
years = year(SystemDateget());
date2 = mkdate(day,mth,years+length);
print date2;
pause;
}
07 December 2010
validation to allow only alphabets in textControl
validation to allow only alphabets in textControl
Form->design->StringControl->method->validate()
public boolean validate()
{
boolean ret;
;
if(strnfind(this.text(),'ABCDEFGHIJKLMNOPQRSTUVWXYZ',1,strlen(this.text())))
{
info("enter only alfa");
}
else
{
ret = super();
}
return ret;
}
Form->design->StringControl->method->validate()
public boolean validate()
{
boolean ret;
;
if(strnfind(this.text(),'ABCDEFGHIJKLMNOPQRSTUVWXYZ',1,strlen(this.text())))
{
info("enter only alfa");
}
else
{
ret = super();
}
return ret;
}
Table Fields in Form Lookup / UtileElements
Table Fields in Form Lookup
Form->DS->Field->Method-> lookup()
public void lookup(FormControl _formControl, str _filterStr)
{
SysTableLookup sysTableLookup = SysTableLookup::newParameters(Tablenum(Utilelements),_formControl);
Query query = new Query();
QueryBuildDataSource QBDS;
;
SysTableLookup.addLookupfield(fieldnum(Utilelements,name));
QBDS = query.addDataSource(Tablenum(Utilelements));
QBDS.addRange(fieldnum(utilelements,recordtype)).value(queryvalue(UtilelementType::TableField));
QBDS.addRange(fieldnum(Utilelements,ParentId)).value(queryvalue(tablenum(ClinicalMaster)));
sysTableLookup.parmQuery(query);
systableLookup.performFormLookup();
//super(_formControl, _filterStr);
}
Form->DS->Field->Method-> lookup()
public void lookup(FormControl _formControl, str _filterStr)
{
SysTableLookup sysTableLookup = SysTableLookup::newParameters(Tablenum(Utilelements),_formControl);
Query query = new Query();
QueryBuildDataSource QBDS;
;
SysTableLookup.addLookupfield(fieldnum(Utilelements,name));
QBDS = query.addDataSource(Tablenum(Utilelements));
QBDS.addRange(fieldnum(utilelements,recordtype)).value(queryvalue(UtilelementType::TableField));
QBDS.addRange(fieldnum(Utilelements,ParentId)).value(queryvalue(tablenum(ClinicalMaster)));
sysTableLookup.parmQuery(query);
systableLookup.performFormLookup();
//super(_formControl, _filterStr);
}
03 December 2010
Add Fields To a Table with X++ , Dynamically
Add Fields To a Table with X++ , Dynamically
There is 2 ways to create a fields for Table.
1.New Table with New Fields
2. Add New fields To Existing Table
1.Create a New Table with New Fields
static void newTableCreate112(Args _args)
{
TreeNode treeNode;
AOTTableFieldList fieldList;
#AOT
;
treeNode = TreeNode::findNode(#TablesPath);
treeNode.AOTadd("Test_ABC");
SqlDataDictionary::synchronize();
//treeNode.AOTfindChild('naresh3');
fieldList = treeNode.AOTfindChild('Test_ABC').AOTfindChild('fields');
fieldList.addString('Name');
fieldList.addInteger('Id');
fieldList.addString('Address');
fieldList.addReal('Salary');
print "Table Created";
pause;
}
2.Add New fields To Existing Table
static void newFieldCreate(Args _args)
{
TreeNode treeNode;
AOTTableFieldList fieldList;
#AOT
;
treeNode = TreeNode::findNode(@'\\Data Dictionary\Tables\Test_ABC\');
fieldList = treeNode.AOTfindChild('fields');
fieldList.addInteger('Mobile');
SqlDataDictionary::synchronize();
print "Field Created";
pause;
}
There is 2 ways to create a fields for Table.
1.New Table with New Fields
2. Add New fields To Existing Table
1.Create a New Table with New Fields
static void newTableCreate112(Args _args)
{
TreeNode treeNode;
AOTTableFieldList fieldList;
#AOT
;
treeNode = TreeNode::findNode(#TablesPath);
treeNode.AOTadd("Test_ABC");
SqlDataDictionary::synchronize();
//treeNode.AOTfindChild('naresh3');
fieldList = treeNode.AOTfindChild('Test_ABC').AOTfindChild('fields');
fieldList.addString('Name');
fieldList.addInteger('Id');
fieldList.addString('Address');
fieldList.addReal('Salary');
print "Table Created";
pause;
}
2.Add New fields To Existing Table
static void newFieldCreate(Args _args)
{
TreeNode treeNode;
AOTTableFieldList fieldList;
#AOT
;
treeNode = TreeNode::findNode(@'\\Data Dictionary\Tables\Test_ABC\');
fieldList = treeNode.AOTfindChild('fields');
fieldList.addInteger('Mobile');
SqlDataDictionary::synchronize();
print "Field Created";
pause;
}
02 December 2010
How to disable the employee field in sysqueryform
How to disable the employee field in sysqueryform
Do u want that field should not appear in sysqueryform
Add a range for that field in data source and set the status to "Hide";
Do u want that field should not appear in sysqueryform
Add a range for that field in data source and set the status to "Hide";
23 November 2010
Run time Lookup with range
Form lookup with reange:
--
1.
public void lookup(FormControl _formControl, str _filterStr)
{
Query query = new Query();
SysTableLookup sysTableLookup;
QueryBuildDataSource queryBuildDataSource;
;
sysTableLookup = SysTableLookup::newParameters(tablenum(AddressCityTable_BR), _formControl);
sysTableLookup.addLookupfield(fieldnum(AddressCityTable_BR, City), true);
sysTableLookup.addLookupfield(fieldnum(AddressCityTable_BR, StateId));
sysTableLookup.addLookupfield(fieldnum(AddressCityTable_BR, CountryId));
queryBuildDataSource = query.addDataSource(tablenum(AddressCityTable_BR));
queryBuildDataSource.addRange(fieldnum(AddressCityTable_BR, StateId)).value(queryValue(zipCode.State));
queryBuildDataSource.addRange(fieldnum(AddressCityTable_BR, CountryId)).value(queryValue(zipCode.CountryRegionId));
sysTableLookup.parmQuery(query);
sysTableLookup.performFormLookup();
}
--
1.
public void lookup(FormControl _formControl, str _filterStr)
{
Query query = new Query();
SysTableLookup sysTableLookup;
QueryBuildDataSource queryBuildDataSource;
;
sysTableLookup = SysTableLookup::newParameters(tablenum(AddressCityTable_BR), _formControl);
sysTableLookup.addLookupfield(fieldnum(AddressCityTable_BR, City), true);
sysTableLookup.addLookupfield(fieldnum(AddressCityTable_BR, StateId));
sysTableLookup.addLookupfield(fieldnum(AddressCityTable_BR, CountryId));
queryBuildDataSource = query.addDataSource(tablenum(AddressCityTable_BR));
queryBuildDataSource.addRange(fieldnum(AddressCityTable_BR, StateId)).value(queryValue(zipCode.State));
queryBuildDataSource.addRange(fieldnum(AddressCityTable_BR, CountryId)).value(queryValue(zipCode.CountryRegionId));
sysTableLookup.parmQuery(query);
sysTableLookup.performFormLookup();
}
18 November 2010
AX Environment/Company Information on Form
AX Environment Information on UI.
--
during implementations where there are multiple environments it becomes difficult to identify which environment a form belongs to especially when there are multiple forms open form different environments (Live, Test, Prod, Training etc). I made a very simple tweak which highlights which environment a form belongs to.
click here to download the xpo
The XPO is attached below. This XPO is for AX 2009 SP1 and the SysSetupFormRun class was modified.
--
during implementations where there are multiple environments it becomes difficult to identify which environment a form belongs to especially when there are multiple forms open form different environments (Live, Test, Prod, Training etc). I made a very simple tweak which highlights which environment a form belongs to.
click here to download the xpo
The XPO is attached below. This XPO is for AX 2009 SP1 and the SysSetupFormRun class was modified.
Hyperlink on a form
Theres a standard method \Classes\Info\urlLookup that can be used to open URLs. So you can format an URL and then just call
infolog.urlLookup( urlStr );
The call can be placed in a clicked() method of a button or somewehere else.
infolog.urlLookup( urlStr );
The call can be placed in a clicked() method of a button or somewehere else.
17 November 2010
How to change form color of Microsoft Dynamics AX 2009
In the class SysSetUpFormRun class add a following code in run method
public void run()
{
super();
this.design().colorScheme(FormColorScheme::RGB);
this.design().backgroundColor(WinAPI::RGB2int(255,0,0));
}
--
Based Upon the company we can change the color of ax
switch(curext())
{
case "CEU":
this.design().backgroundColor(red);
break;
case "DMO":
this.design().backgroundColor(yellow);
break;
default:
break;
}
--
IN AX 2012 Class: sysSetupFormRun->init()
public void init()
{
super();
//start
this.design().colorScheme(FormColorScheme::RGB);
this.design().backgroundColor(WinAPI::RGB2int(120,120,120));
this.setStatusBarBackgroundColor(255,0,200,255);// form status bar color
// end
if (this.isWorkflowEnabled())
{
workflowControls = SysWorkflowFormControls::construct(this);
workflowControls.initControls();
}
}
public void run()
{
super();
this.design().colorScheme(FormColorScheme::RGB);
this.design().backgroundColor(WinAPI::RGB2int(255,0,0));
}
--
Based Upon the company we can change the color of ax
switch(curext())
{
case "CEU":
this.design().backgroundColor(red);
break;
case "DMO":
this.design().backgroundColor(yellow);
break;
default:
break;
}
--
IN AX 2012 Class: sysSetupFormRun->init()
public void init()
{
super();
//start
this.design().colorScheme(FormColorScheme::RGB);
this.design().backgroundColor(WinAPI::RGB2int(120,120,120));
this.setStatusBarBackgroundColor(255,0,200,255);// form status bar color
// end
if (this.isWorkflowEnabled())
{
workflowControls = SysWorkflowFormControls::construct(this);
workflowControls.initControls();
}
}
16 November 2010
caller - calling form with button click and caller only for a form only
---
Display->formB-Properties->RunOn: Calledform// this allow for formA.
---
Form A->button clicked()
--
void clicked()
{
Args _args;
FormRun _formRun;
EmplId _emplid;
;
super();
_emplid = EmplTable.EmplId;
_args = new Args();
_args.name(formstr(FormB));
_args.caller(this); //this refer current object form
_args.parm(_emplid);
_args.record(EmplTable);
_formRun = ClassFactory.formRunClass(_args);
_formRun.init();
_formRun.run();
_formRun.wait();
}
--
FormB->DS->init()
--
public void init()
{
EmplId _emplId;
Query query;
QueryBuildRange querybuildrangeproj;
;
super();
Switch(element.args().dataset())
{
case tablenum(EmplTable):
_emplId = element.args().parm();
query = new Query();
querybuildrangeproj = query.addDataSource(tablenum(EmplTable)).addRange(fieldnum(EmplTable, EmplId));
querybuildrangeproj.value(_emplId);// adding range value from form A
EmplTable_ds.query(query);
break;
}
}
--
Display->formB-Properties->RunOn: Calledform// this allow for formA.
----
Display->formB-Properties->RunOn: Calledform// this allow for formA.
---
Form A->button clicked()
--
void clicked()
{
Args _args;
FormRun _formRun;
EmplId _emplid;
;
super();
_emplid = EmplTable.EmplId;
_args = new Args();
_args.name(formstr(FormB));
_args.caller(this); //this refer current object form
_args.parm(_emplid);
_args.record(EmplTable);
_formRun = ClassFactory.formRunClass(_args);
_formRun.init();
_formRun.run();
_formRun.wait();
}
--
FormB->DS->init()
--
public void init()
{
EmplId _emplId;
Query query;
QueryBuildRange querybuildrangeproj;
;
super();
Switch(element.args().dataset())
{
case tablenum(EmplTable):
_emplId = element.args().parm();
query = new Query();
querybuildrangeproj = query.addDataSource(tablenum(EmplTable)).addRange(fieldnum(EmplTable, EmplId));
querybuildrangeproj.value(_emplId);// adding range value from form A
EmplTable_ds.query(query);
break;
}
}
--
Display->formB-Properties->RunOn: Calledform// this allow for formA.
----
Report Query using for To get record in fetch
------------
//Suud is Table(DS)
//qr is object for QueryRun class
------------
public boolean fetch()
{
boolean ret;
QueryRun qr;
;
qr = new QueryRun(this.query());//
// following statement is executes depends on count of records in table
while(qr.next())
{
Stud = qr.get(tablenum(Stud));// getting table num
while select Stud
{
this.send(Stud);
}
}
//ret = super();
return true;
}
-------
//Suud is Table(DS)
//qr is object for QueryRun class
------------
public boolean fetch()
{
boolean ret;
QueryRun qr;
;
qr = new QueryRun(this.query());//
// following statement is executes depends on count of records in table
while(qr.next())
{
Stud = qr.get(tablenum(Stud));// getting table num
while select Stud
{
this.send(Stud);
}
}
//ret = super();
return true;
}
-------
Report avoid null records
-------------
1
-------------
public boolean fetch()
{
boolean ret;
//ret = super();
while select Stud where Stud.Address != ''
{
this.send(Stud);
}
return true;
}
--------------
2
--------------
Report->ds->ranges->field->properties->value: !=""
1
-------------
public boolean fetch()
{
boolean ret;
//ret = super();
while select Stud where Stud.Address != ''
{
this.send(Stud);
}
return true;
}
--------------
2
--------------
Report->ds->ranges->field->properties->value: !=""
09 November 2010
Validate The salesLine unit price should not less than the item cost price
SalesTable(form)->DS->SalesLine->salePrice(Field)->Validate()
public boolean validate()
{
boolean ret;
ret = super();
ret = element.validate_price();
return ret;
}
--
SalesTable(form)->Methods->
public boolean validate_price()
{
boolean ret = true;
InventTableModule inventTableModule;
;
//in this line we are using our own find method, or we can use select query.
//inventTableModule = InventTableModule::find_price(SalesLine.ItemId);
select firstonly inventTableModule where inventTableModule.ItemId == SalesLine.ItemId;
if(inventTableModule.Price > SalesLine.SalesPrice)
{
ret = false;
info("the cost price is grater then the sales price ");
}
return ret;
}
public boolean validate()
{
boolean ret;
ret = super();
ret = element.validate_price();
return ret;
}
--
SalesTable(form)->Methods->
public boolean validate_price()
{
boolean ret = true;
InventTableModule inventTableModule;
;
//in this line we are using our own find method, or we can use select query.
//inventTableModule = InventTableModule::find_price(SalesLine.ItemId);
select firstonly inventTableModule where inventTableModule.ItemId == SalesLine.ItemId;
if(inventTableModule.Price > SalesLine.SalesPrice)
{
ret = false;
info("the cost price is grater then the sales price ");
}
return ret;
}
08 November 2010
Get the selected record in form
1.
void clicked()
{
common common;
salesTable salesTableRef;
;
// using DataSource cursor() methos will get the cursor selected record
common = element.dataSource().cursor();
switch (common.TableId)
{
case tableNum(salesTable) :
{
salesTableRef = common;
info(salesTableRef.SalesId);
break;
}
}
super();
}
----------
2.
In Datasource->Active()
We can get using the DataSource name like
info(SalesTable.SalesId)
----------
3.
We can use that DataSource Name like SalesTable//this will get the selected record
info(SalesTable.SalesId)
void clicked()
{
common common;
salesTable salesTableRef;
;
// using DataSource cursor() methos will get the cursor selected record
common = element.dataSource().cursor();
switch (common.TableId)
{
case tableNum(salesTable) :
{
salesTableRef = common;
info(salesTableRef.SalesId);
break;
}
}
super();
}
----------
2.
In Datasource->Active()
We can get using the DataSource name like
info(SalesTable.SalesId)
----------
3.
We can use that DataSource Name like SalesTable//this will get the selected record
info(SalesTable.SalesId)
29 October 2010
data from all companies to a report, using cross company
Report->Fetch method
public boolean fetch()
{
boolean ret;
CustTable custTable;
;
// ret = super();
while select crosscompany custTable
{
this.send(custTable);
}
return true;
}
public boolean fetch()
{
boolean ret;
CustTable custTable;
;
// ret = super();
while select crosscompany custTable
{
this.send(custTable);
}
return true;
}
27 October 2010
pass the parameter to report in Dynamics AX
1. Calling menuItem. Task
This is in Report to get selected record parameter like sales id ,this code is making the defalut range value the selected record of S.O -> salesId. this will pront the selected record only on report
Here we are controlling the query range prompt.
Sales Tabel form -> MenuItembutton clicked()- properties remove the menuItemName:
void clicked()
{
Args args = new Args();
MenuFunction menuFunction;
;
args.parm(SalesTable.SalesId);
menuFunction = new MenuFunction(menuitemoutputstr(Report9), MenuItemType::Output);// Report9 is menuItem
menuFunction.run(args);
super();
}
--------
In Report-> init()
public void init()
{
try
{
if(element.args().parm())
{
this.query().dataSourceTable(tablenum(SalesTable)).addRange(fieldnum(SalesTable,SalesId)).value(element.args().parm());
salesId = element.args().parm();
this.query().userUpdate(false);
this.query().interactive(false);
super();
}
}
catch(exception::Error)
{
info("Errosr in init");
}
}
-----------------------------------------------
2.calling report
form->Button
void clicked()
{
Args args = new args();
ReportRun reportRun;
;
args.parm(PurchReqTable.PurchReqId);
args.name(reportstr(PurchRequisitionDetails));
reportRun = classFactory.reportRunClass(args);
reportRun.init();
reportrun.run();
//hello
super();
}
Report and click on ‘Override Method –> init’
In this init method, you need to enter the following code to allow the report to read the parameters from the form.
public void init()
{
;
try
{
if(element.args().parm())
{
this.query().dataSourceTable(tablenum(PurchReqTable))
.addRange(fieldnum(PurchReqTable, PurchReqId)).value(element.args().parm());
this.query().userUpdate(false);
this.query().interactive(false);
super();
}
}
catch(exception::Error)
{
info(“Error in init method”);
}
}
This is in Report to get selected record parameter like sales id ,this code is making the defalut range value the selected record of S.O -> salesId. this will pront the selected record only on report
Here we are controlling the query range prompt.
Sales Tabel form -> MenuItembutton clicked()- properties remove the menuItemName:
void clicked()
{
Args args = new Args();
MenuFunction menuFunction;
;
args.parm(SalesTable.SalesId);
menuFunction = new MenuFunction(menuitemoutputstr(Report9), MenuItemType::Output);// Report9 is menuItem
menuFunction.run(args);
super();
}
--------
In Report-> init()
public void init()
{
try
{
if(element.args().parm())
{
this.query().dataSourceTable(tablenum(SalesTable)).addRange(fieldnum(SalesTable,SalesId)).value(element.args().parm());
salesId = element.args().parm();
this.query().userUpdate(false);
this.query().interactive(false);
super();
}
}
catch(exception::Error)
{
info("Errosr in init");
}
}
-----------------------------------------------
2.calling report
form->Button
void clicked()
{
Args args = new args();
ReportRun reportRun;
;
args.parm(PurchReqTable.PurchReqId);
args.name(reportstr(PurchRequisitionDetails));
reportRun = classFactory.reportRunClass(args);
reportRun.init();
reportrun.run();
//hello
super();
}
Report and click on ‘Override Method –> init’
In this init method, you need to enter the following code to allow the report to read the parameters from the form.
public void init()
{
;
try
{
if(element.args().parm())
{
this.query().dataSourceTable(tablenum(PurchReqTable))
.addRange(fieldnum(PurchReqTable, PurchReqId)).value(element.args().parm());
this.query().userUpdate(false);
this.query().interactive(false);
super();
}
}
catch(exception::Error)
{
info(“Error in init method”);
}
}
25 October 2010
Storing Last Form Values
Dynamics AX has a very useful feature, which allows saving the latest user choices per user per form. This feature is implemented across a number of standard reports, periodic jobs, and other objects, which require user input.
In this recipe, we will see how to store the latest user filter selections. To make it as simple as possible, we will use existing filters on the General journal form, which can be opened from General ledger | Journals | General journal. This form contains two filters—Show and Show user-created only. Show allows displaying journals by their posting status and Show user-created only toggles between all journals and the currently logged user's journals.
1.Find the LedgerJournalTable form in AOT, and add the following code to the bottom of its class declaration:
AllOpenPosted showStatus;
NoYes showCurrentUser;
#define.CurrentVersion(1)
#localmacro.CurrentList
showStatus,
showCurrentUser
#endmacro
------------------------------------------------
2.Create these additional form methods:
public void initParmDefault()
{
;
showStatus = AllOpenPosted::Open;
showCurrentUser = true;
}
public container pack()
{
return [#CurrentVersion,#CurrentList];
}
-----------------------------------------------------------
public boolean unpack(container packedClass)
{
int version = RunBase::getVersion(packedClass);
;
switch (version)
{
case #CurrentVersion:[version,#CurrentList] = packedClass;
return true;
default:
return false;
}
return false;
}
------------------------------------------
public identifiername lastValueDesignName()
{
return element.args().menuItemName();
}
------------------------------------------
public identifiername lastValueElementName()
{
return this.name();
}
----------------------------------------
public UtilElementType lastValueType()
{
return UtilElementType::Form;
}
----------------------------------------
public userId lastValueUserId()
{
return curuserid();
}
----------------------------------------
public dataAreaId lastValueDataAreaId()
{
return curext();
}
In this recipe, we will see how to store the latest user filter selections. To make it as simple as possible, we will use existing filters on the General journal form, which can be opened from General ledger | Journals | General journal. This form contains two filters—Show and Show user-created only. Show allows displaying journals by their posting status and Show user-created only toggles between all journals and the currently logged user's journals.
1.Find the LedgerJournalTable form in AOT, and add the following code to the bottom of its class declaration:
AllOpenPosted showStatus;
NoYes showCurrentUser;
#define.CurrentVersion(1)
#localmacro.CurrentList
showStatus,
showCurrentUser
#endmacro
------------------------------------------------
2.Create these additional form methods:
public void initParmDefault()
{
;
showStatus = AllOpenPosted::Open;
showCurrentUser = true;
}
public container pack()
{
return [#CurrentVersion,#CurrentList];
}
-----------------------------------------------------------
public boolean unpack(container packedClass)
{
int version = RunBase::getVersion(packedClass);
;
switch (version)
{
case #CurrentVersion:[version,#CurrentList] = packedClass;
return true;
default:
return false;
}
return false;
}
------------------------------------------
public identifiername lastValueDesignName()
{
return element.args().menuItemName();
}
------------------------------------------
public identifiername lastValueElementName()
{
return this.name();
}
----------------------------------------
public UtilElementType lastValueType()
{
return UtilElementType::Form;
}
----------------------------------------
public userId lastValueUserId()
{
return curuserid();
}
----------------------------------------
public dataAreaId lastValueDataAreaId()
{
return curext();
}
21 October 2010
create a new Table by using a X++ code
static void newTableCreate(Args _args)
{
TreeNode treeNode;
#AOT
;
treeNode = TreeNode::findNode(#TablesPath);
treeNode.AOTadd("Table_Test");
SqlDataDictionary::synchronize();
}
{
TreeNode treeNode;
#AOT
;
treeNode = TreeNode::findNode(#TablesPath);
treeNode.AOTadd("Table_Test");
SqlDataDictionary::synchronize();
}
18 October 2010
Created EDT with code
static void EDT_By_Code(Args _args)
{
AOTTableFieldList aTFL;
AOTTableFieldList aEDTL;
TreeNode fieldNode;
Types _enum = Types::String;
str property;
;
aEDTL = infolog.findNode('\\Data Dictionary\\Extended Data Types');
if (!aEDTL.AOTFindChild('test'))
{
aEDTL.AOTaddExtendedDataType('test', _enum);
fieldNode = aEDTL.AOTFindChild('test');
fieldNode.AOTsave();
}
property = setProperty(fieldnode.AOTgetProperties(), 'StringSize', '30');
fieldNode.AOTsave();
info(property);
fieldNode.AOTsetProperties(property);
fieldNode.AOTrefresh();
}
{
AOTTableFieldList aTFL;
AOTTableFieldList aEDTL;
TreeNode fieldNode;
Types _enum = Types::String;
str property;
;
aEDTL = infolog.findNode('\\Data Dictionary\\Extended Data Types');
if (!aEDTL.AOTFindChild('test'))
{
aEDTL.AOTaddExtendedDataType('test', _enum);
fieldNode = aEDTL.AOTFindChild('test');
fieldNode.AOTsave();
}
property = setProperty(fieldnode.AOTgetProperties(), 'StringSize', '30');
fieldNode.AOTsave();
info(property);
fieldNode.AOTsetProperties(property);
fieldNode.AOTrefresh();
}
08 October 2010
To add lookup in form control
we are adding Form control lookup Vend accountNum and Vend name
public void lookup()
{
SysTableLookup sysTableLookup;
VendTable vendTable;
;
sysTableLookup = SysTableLookup::newParameters(tablenum(VendTable), this);
sysTableLookup.addLookupfield(fieldnum(vendTable, AccountNum),true);
sysTableLookup.addLookupfield(fieldnum(vendTable, Name),true);
sysTableLookup.performFormLookup();
//super();
}
public void lookup()
{
SysTableLookup sysTableLookup;
VendTable vendTable;
;
sysTableLookup = SysTableLookup::newParameters(tablenum(VendTable), this);
sysTableLookup.addLookupfield(fieldnum(vendTable, AccountNum),true);
sysTableLookup.addLookupfield(fieldnum(vendTable, Name),true);
sysTableLookup.performFormLookup();
//super();
}
06 October 2010
WorkCalendarSched
When programming Dynamics AX it is very easy to add days to a date. You can take todays date and just add an integer of five to get the date five days from now. But because this is easy to do it doesn’t mean that this always is the right way to go about this date business.
If you look closer at how the dates are calculated on the sales order lines or the purchase order lines in Dynamics AX you see that a class called WorkCalendarSched is used. This is because deliveries are dependant on when the company using Dynamics AX actually can send the order. Not all companies work on weekends.
This is when WorkCalendarSched comes in handy, with this class and the class method “shedDate” you can make sure that the delivery is set to a day when the company actually is going to be able deliver.
This is a basic job that uses the class WorkCalendarSched and the method “shedDate”:
static void FO_stepCalendar(Args _args)
{
SchedDate schedDate;
date fromDate = systemDateGet(),
testDate;
WorkCalendarSched workCalendarSched;
int days2step = 4;
boolean calendarDays = false;
CustTable cust = CustTable::find("4000");
;
// Without using schedDate.
testDate = fromDate + days2step;
workCalendarSched = new WorkCalendarSched();
schedDate = workCalendarSched.schedDate(
SchedDirection::Forward,
fromDate,
days2step,
calendarDays,
cust.SalesCalendarId,
CompanyInfo::find().ShippingCalendarId);
print strFmt("From date: %1", fromDate);
print strFmt("Test date: %1", testDate);
print strFmt("Scheddate: %1", schedDate);
print strFmt("%1", workCalendarSched.isDateOpen(
CompanyInfo::find().ShippingCalendarId,
testDate));
print strFmt("%1", workCalendarSched.isDateOpen(
CompanyInfo::find().ShippingCalendarId,
schedDate));
pause;
}
If you look closer at how the dates are calculated on the sales order lines or the purchase order lines in Dynamics AX you see that a class called WorkCalendarSched is used. This is because deliveries are dependant on when the company using Dynamics AX actually can send the order. Not all companies work on weekends.
This is when WorkCalendarSched comes in handy, with this class and the class method “shedDate” you can make sure that the delivery is set to a day when the company actually is going to be able deliver.
This is a basic job that uses the class WorkCalendarSched and the method “shedDate”:
static void FO_stepCalendar(Args _args)
{
SchedDate schedDate;
date fromDate = systemDateGet(),
testDate;
WorkCalendarSched workCalendarSched;
int days2step = 4;
boolean calendarDays = false;
CustTable cust = CustTable::find("4000");
;
// Without using schedDate.
testDate = fromDate + days2step;
workCalendarSched = new WorkCalendarSched();
schedDate = workCalendarSched.schedDate(
SchedDirection::Forward,
fromDate,
days2step,
calendarDays,
cust.SalesCalendarId,
CompanyInfo::find().ShippingCalendarId);
print strFmt("From date: %1", fromDate);
print strFmt("Test date: %1", testDate);
print strFmt("Scheddate: %1", schedDate);
print strFmt("%1", workCalendarSched.isDateOpen(
CompanyInfo::find().ShippingCalendarId,
testDate));
print strFmt("%1", workCalendarSched.isDateOpen(
CompanyInfo::find().ShippingCalendarId,
schedDate));
pause;
}
Strange behaviour when calling form
I was building an extended search form for one of our customers. When called from one form everything worked fine, but when called from a second form my grid only contained one record… Exact same parameters, same menu item etc. When looking around I found that when the error occured, I was calling from a form which had same table (InventTable) as one of it’s main Data Sources. This is one of the non-documented features in AX, if same table exists in the Data Sources in both forms, AX tryes to link them together. To break this connection I had to call ClearDynaLinks() on the second form. Like below, in my search form’s init method.
void init()
{
....
InventTable_ds.query().dataSourceTable(
tablenum(InventTable)).clearDynalinks();
}
void init()
{
....
InventTable_ds.query().dataSourceTable(
tablenum(InventTable)).clearDynalinks();
}
Jump between InterCompany order lines
This is a basic job that describes how you can jump from one order line to another in the intercompany order structure.
In this example I have created an intercompany order that also has a linked purchase order in the production company to a vendor. This is one way you can use to jump up between the linked order lines.
I start out in the sales company “FO1” and go all the way up to the intercompany sales line in the production company “FO”, then I change company to “FO” so that I can gain access to the production company’s purchase line. From this purchase line I change the direction and move all the way back to the original sales line that is located in the sales company FO1.
As you can see I run the code while being in the sales company “FO1″. I start out with a specific sales line that I get by searching for its RecId. This code it meant to be run with a sales line as its basis. Preferably from the SalesTable form, the SalesLine table or some other object where you have sales line data that you want to explore.
static void FO_InterCompanyRefs(Args _args)
{
SalesLine salesLine =
SalesLine::findRecId(5637552101),
icSalesLine = null;
PurchLine purchLine,
icPurchLine;
;
// Sales company = FO1
// Production company = FO
// Original Sales Company SalesLine
print salesLine.SalesId;
print salesLine.ItemId;
print salesLine.dataAreaId;
print "------------------";
purchLine =
PurchLine::findInventTransId(
salesLine.InventRefTransId);
// Sales Company PurchLine
print purchLine.PurchId;
print purchLine.ItemId;
print purchLine.dataAreaId;
print "------------------";
icSalesLine =
purchLine.interCompanySalesLine();
// Production company SalesLine
print icSalesLine.SalesId;
print icSalesLine.ItemId;
print icSalesLine.dataAreaId;
print "------------------";
changecompany(icSalesLine.dataAreaId)
{
purchLine = PurchLine::findInventTransId(
icSalesLine.InventRefTransId);
// Production company PurchLine
print purchLine.PurchId;
print purchLine.ItemId;
print purchLine.dataAreaId;
print "------------------";
icSalesLine =
SalesLine::findInventTransId(
purchLine.InventRefTransId);
// Production company SalesLine
print icSalesLine.SalesId;
print icSalesLine.ItemId;
print icSalesLine.dataAreaId;
print "------------------";
purchLine =
icSalesLine.interCompanyPurchLine();
// Sales Company PurchLine
print purchLine.PurchId;
print purchLine.ItemId;
print purchLine.dataAreaId;
print "------------------";
salesLine =
purchLine.interCompanySalesLineOriginal();
// Sales Company PurchLine
print salesLine.SalesId;
print salesLine.ItemId;
print salesLine.dataAreaId;
print "------------------";
}
pause;
}
In this example I have created an intercompany order that also has a linked purchase order in the production company to a vendor. This is one way you can use to jump up between the linked order lines.
I start out in the sales company “FO1” and go all the way up to the intercompany sales line in the production company “FO”, then I change company to “FO” so that I can gain access to the production company’s purchase line. From this purchase line I change the direction and move all the way back to the original sales line that is located in the sales company FO1.
As you can see I run the code while being in the sales company “FO1″. I start out with a specific sales line that I get by searching for its RecId. This code it meant to be run with a sales line as its basis. Preferably from the SalesTable form, the SalesLine table or some other object where you have sales line data that you want to explore.
static void FO_InterCompanyRefs(Args _args)
{
SalesLine salesLine =
SalesLine::findRecId(5637552101),
icSalesLine = null;
PurchLine purchLine,
icPurchLine;
;
// Sales company = FO1
// Production company = FO
// Original Sales Company SalesLine
print salesLine.SalesId;
print salesLine.ItemId;
print salesLine.dataAreaId;
print "------------------";
purchLine =
PurchLine::findInventTransId(
salesLine.InventRefTransId);
// Sales Company PurchLine
print purchLine.PurchId;
print purchLine.ItemId;
print purchLine.dataAreaId;
print "------------------";
icSalesLine =
purchLine.interCompanySalesLine();
// Production company SalesLine
print icSalesLine.SalesId;
print icSalesLine.ItemId;
print icSalesLine.dataAreaId;
print "------------------";
changecompany(icSalesLine.dataAreaId)
{
purchLine = PurchLine::findInventTransId(
icSalesLine.InventRefTransId);
// Production company PurchLine
print purchLine.PurchId;
print purchLine.ItemId;
print purchLine.dataAreaId;
print "------------------";
icSalesLine =
SalesLine::findInventTransId(
purchLine.InventRefTransId);
// Production company SalesLine
print icSalesLine.SalesId;
print icSalesLine.ItemId;
print icSalesLine.dataAreaId;
print "------------------";
purchLine =
icSalesLine.interCompanyPurchLine();
// Sales Company PurchLine
print purchLine.PurchId;
print purchLine.ItemId;
print purchLine.dataAreaId;
print "------------------";
salesLine =
purchLine.interCompanySalesLineOriginal();
// Sales Company PurchLine
print salesLine.SalesId;
print salesLine.ItemId;
print salesLine.dataAreaId;
print "------------------";
}
pause;
}
How to catch special keystrokes and use them as shortcuts
Rightclick on a form and go down tracking a specific field or other data, is a tedious work if you do it dozens of times per day.
We wanted to catch the key combination ctrl+Z (since it is rarelly used when running axapta), so we could use it to display common data about a form, field or other info. This is a code example we nowdays always install in all new test and development environments (not production, since it would give normal users unwanted access).
The key to this method is adding code in the Task method of the SysSetupFormRun class. Open your AOT, go to the class SysSetupFormRun, expand the Task method and add the code below between the start/end comments. Save the changes. Start up for example SalesTable form, position on a field and press Ctrl+Z, voila - a complete list of that field is listed in the infolog. Maybe you need to restart your client, to get the changes active.
There is a very similar example on kashperuk.blogspot.com but that example seems to be dependt on a external DLL file, this version is not. Originally this code comes from AxaptaPedia but I can not find it now. We do not claim to be the first with this idea, just showing something very useful. This code goes long back. Our changes is minor.
public int task(int _p1)
{
#task
FormDataSource formDataSource;
int ret;
// START 070921 FourOne/JoJ (FO_EnvironmentAddOns4)
// -- Description: quick-command for checking
// field and/or form data.
SysDictField df;
FormControl fc;
formStringControl fsc;
DictEnum dictEnum = new DictEnum(enumnum(Types));
DictEnum dictEnums;
;
if (_p1 == 769) //Ctrl + Z
{
fc = this.selectedControl();
formDataSource = this.objectSet();
if(fc && formDataSource)
{
fsc = fc;
if(fsc.dataField() && formDataSource.table())
{
info(strfmt('Tbl. Fld -> %2. %1',
fieldId2Name(formDataSource.table(),
fsc.dataField() - 65536),
tableId2Name(formDataSource.table())));
df=new SysDictField(formDataSource.table(),
fsc.dataField() - 65536);
if(df)
{
info(strfmt('Type -> %1',
dictEnum.index2Symbol(
df.baseType())));
if(df.baseType() == typeOf(Types::Enum))
{
dictEnums = new dictEnum(
df.enumId());
info(strfmt('Enum -> %1',
dictEnums.name()));
}
info(strfmt('Ext type -> %1',
extendedTypeId2name(df.typeId())));
info(strfmt('Size -> %1',
int2str(df.stringLen())));
info(strfmt('max.rght -> %1',
(df.rights())));
info(strfmt('Label -> %1: %2',
(df.labelLabel()),(df.label()) ));
info(strfmt('Help -> %1: %2',
(df.helpLabelId()),(df.help()) ));
}
}
if(fsc.dataMethod())
{
info(strfmt('METHOD %1.%2',
tableId2Name(formDataSource.table()),
fsc.dataMethod()));
}
}
}
// END 070921 FourOne/JoJ (FO_EnvironmentAddOns4)
if (_p1 == #taskFilter)
{
formDataSource = this.objectSet();
if (formDataSource &&
formDataSource.queryRun() &&
formDataSource.queryRun().args() &&
!formDataSource.queryRun().args().caller())
{
formDataSource.queryRun().args().caller(this);
}
}
ret = super(_p1);
return ret;
}
We wanted to catch the key combination ctrl+Z (since it is rarelly used when running axapta), so we could use it to display common data about a form, field or other info. This is a code example we nowdays always install in all new test and development environments (not production, since it would give normal users unwanted access).
The key to this method is adding code in the Task method of the SysSetupFormRun class. Open your AOT, go to the class SysSetupFormRun, expand the Task method and add the code below between the start/end comments. Save the changes. Start up for example SalesTable form, position on a field and press Ctrl+Z, voila - a complete list of that field is listed in the infolog. Maybe you need to restart your client, to get the changes active.
There is a very similar example on kashperuk.blogspot.com but that example seems to be dependt on a external DLL file, this version is not. Originally this code comes from AxaptaPedia but I can not find it now. We do not claim to be the first with this idea, just showing something very useful. This code goes long back. Our changes is minor.
public int task(int _p1)
{
#task
FormDataSource formDataSource;
int ret;
// START 070921 FourOne/JoJ (FO_EnvironmentAddOns4)
// -- Description: quick-command for checking
// field and/or form data.
SysDictField df;
FormControl fc;
formStringControl fsc;
DictEnum dictEnum = new DictEnum(enumnum(Types));
DictEnum dictEnums;
;
if (_p1 == 769) //Ctrl + Z
{
fc = this.selectedControl();
formDataSource = this.objectSet();
if(fc && formDataSource)
{
fsc = fc;
if(fsc.dataField() && formDataSource.table())
{
info(strfmt('Tbl. Fld -> %2. %1',
fieldId2Name(formDataSource.table(),
fsc.dataField() - 65536),
tableId2Name(formDataSource.table())));
df=new SysDictField(formDataSource.table(),
fsc.dataField() - 65536);
if(df)
{
info(strfmt('Type -> %1',
dictEnum.index2Symbol(
df.baseType())));
if(df.baseType() == typeOf(Types::Enum))
{
dictEnums = new dictEnum(
df.enumId());
info(strfmt('Enum -> %1',
dictEnums.name()));
}
info(strfmt('Ext type -> %1',
extendedTypeId2name(df.typeId())));
info(strfmt('Size -> %1',
int2str(df.stringLen())));
info(strfmt('max.rght -> %1',
(df.rights())));
info(strfmt('Label -> %1: %2',
(df.labelLabel()),(df.label()) ));
info(strfmt('Help -> %1: %2',
(df.helpLabelId()),(df.help()) ));
}
}
if(fsc.dataMethod())
{
info(strfmt('METHOD %1.%2',
tableId2Name(formDataSource.table()),
fsc.dataMethod()));
}
}
}
// END 070921 FourOne/JoJ (FO_EnvironmentAddOns4)
if (_p1 == #taskFilter)
{
formDataSource = this.objectSet();
if (formDataSource &&
formDataSource.queryRun() &&
formDataSource.queryRun().args() &&
!formDataSource.queryRun().args().caller())
{
formDataSource.queryRun().args().caller(this);
}
}
ret = super(_p1);
return ret;
}
How to add current profile name to the window title
If you use a descriptive text on your profiles you use to startup axapta with, you have here another way of a very clear presentation of which installation, db, etc settings you are running under.
Open your AOT and locate the Info class. Expand the method workspaceWindowCreated and add the following code. Next time you start axapta, your profile name will be part of the axapta window title.
void workspaceWindowCreated(int _hWnd)
{
// Put workspace window specific initialization here.
// -- START 070307 FourOne/HL (EnvironmentAddOns4)
// -- Description: Show profile-name in the title bar
session s=new Session();
;
WinAPI::setWindowText(_hWnd, strFmt("%1 - %2 - %3",
xInfo::configuration(),
s.userId(),
WinAPI::getWindowText(_hWnd) ));
// -- END 070307 FourOne/HL (EnvironmentAddOns4)
}
Open your AOT and locate the Info class. Expand the method workspaceWindowCreated and add the following code. Next time you start axapta, your profile name will be part of the axapta window title.
void workspaceWindowCreated(int _hWnd)
{
// Put workspace window specific initialization here.
// -- START 070307 FourOne/HL (EnvironmentAddOns4)
// -- Description: Show profile-name in the title bar
session s=new Session();
;
WinAPI::setWindowText(_hWnd, strFmt("%1 - %2 - %3",
xInfo::configuration(),
s.userId(),
WinAPI::getWindowText(_hWnd) ));
// -- END 070307 FourOne/HL (EnvironmentAddOns4)
}
How to colour code different companies inside axapta
During development and test we often switch between different companies in our installation. To not mistaken us, so we always make changes in the correct one, we made this small change in the code. With different background-colours for each company, you never delete something importent by mistake. This example shows how it could be done.
Again we use the SysSetupFormRun class, but this time we look into the Run method. Add below code between the start/end comments and restart your client. Next time you start, all forms will have the background colours you set for each specific company.
// --- START 071001 Fourone/JOJ (EnvironmentAddOns4)
// --- Description: Display company 'xxx' with different
// background color
public void run()
{
FormDesign formDesign = this.design();
super();
if (companyinfo::find().dataAreaId=="dmo")
{
if (formdesign)
{
formDesign.colorScheme(2);
formDesign.backgroundColor(0x00ff);
formdesign.caption("-- dmo -- ");
}
}
// --- END 071001 Fourone/JOJ (EnvironmentAddOns4)
}
Again we use the SysSetupFormRun class, but this time we look into the Run method. Add below code between the start/end comments and restart your client. Next time you start, all forms will have the background colours you set for each specific company.
// --- START 071001 Fourone/JOJ (EnvironmentAddOns4)
// --- Description: Display company 'xxx' with different
// background color
public void run()
{
FormDesign formDesign = this.design();
super();
if (companyinfo::find().dataAreaId=="dmo")
{
if (formdesign)
{
formDesign.colorScheme(2);
formDesign.backgroundColor(0x00ff);
formdesign.caption("-- dmo -- ");
}
}
// --- END 071001 Fourone/JOJ (EnvironmentAddOns4)
}
Open filtered forms with X++
When using forms in Dynamics AX we usually get access to them by clicking a button that uses a menu item, this along with the args that is sent we get a form that displays the requested information. But if you want to do this using code, how is this done?
You usually see this used in classes such as SalesFormLetter or PurchFormLetter that uses an existing form instead of a creating a temporary one. The user enters the information and the class uses the new information to perform the tasks at hand.
This is a pretty simple job that first displays a filtered CustTable form for the customer “4004”, when this form is closed the CustTrans form will be opened and display the relevant data of the customer we are using. As this is done you will also see that it’s possible to either halt the code while a form is open or simply detach it and let the code continue.
static void FO_OpenFilteredForms(Args _args)
{
Args argsCust, argsTrans;
FormRun formRun, formRun2;
CustTable custTable = CustTable::find("4004");
;
argsCust = new Args(formStr(CustTable));
argsCust.record(custTable);
formRun = classFactory.formRunClass(argsCust);
formRun.init();
formRun.run();
formRun.wait();
print "This should be printed when " +
"the CustTable form is closed.";
pause;
argsTrans = new Args(formStr(CustTrans));
argsTrans.record(custTable);
formRun2 = classFactory.formRunClass(argsTrans);
formRun2.init();
formRun2.run();
formRun2.detach();
print "This should be printed as " +
"the CustTrans form opens.";
pause;
}
You usually see this used in classes such as SalesFormLetter or PurchFormLetter that uses an existing form instead of a creating a temporary one. The user enters the information and the class uses the new information to perform the tasks at hand.
This is a pretty simple job that first displays a filtered CustTable form for the customer “4004”, when this form is closed the CustTrans form will be opened and display the relevant data of the customer we are using. As this is done you will also see that it’s possible to either halt the code while a form is open or simply detach it and let the code continue.
static void FO_OpenFilteredForms(Args _args)
{
Args argsCust, argsTrans;
FormRun formRun, formRun2;
CustTable custTable = CustTable::find("4004");
;
argsCust = new Args(formStr(CustTable));
argsCust.record(custTable);
formRun = classFactory.formRunClass(argsCust);
formRun.init();
formRun.run();
formRun.wait();
print "This should be printed when " +
"the CustTable form is closed.";
pause;
argsTrans = new Args(formStr(CustTrans));
argsTrans.record(custTable);
formRun2 = classFactory.formRunClass(argsTrans);
formRun2.init();
formRun2.run();
formRun2.detach();
print "This should be printed as " +
"the CustTrans form opens.";
pause;
}
How to Copy Args Object Data
server static void CopyingArgs(Args _args)
{
FormRun _fr;
SysArgs sysArgs;
;
_args = new Args("CustTable");
sysArgs = SysArgs::createFromArgs(_args);
_fr = classFactory.formRunClass(sysArgs);
_fr.init();
_fr.run();
_fr.wait();
}
{
FormRun _fr;
SysArgs sysArgs;
;
_args = new Args("CustTable");
sysArgs = SysArgs::createFromArgs(_args);
_fr = classFactory.formRunClass(sysArgs);
_fr.init();
_fr.run();
_fr.wait();
}
Microsoft Dynamics AX 2009 EP Development Cookbook
Microsoft Dynamics AX 2009 EP Development Cookbook
Click here
Click here
System Classes in Dynamics AX
RandomGenerate Class:
This class generates random numbers.
static void RandomGenerateEg(Args _args)
{
RandomGenerate objRG = new RandomGenerate();
Random objRandom = new Random();
;
//This generates random numbers specified within the given range
info(int2Str(objRG.randomInt(10,55)));
//This generates random numbers
info(int2Str(objRandom.nextInt()));
}
Executing this job generates random numbers. But it doesn’t guarantee that the numbers will not be repeated. So if the user needs unique number, he has to provide explicit check for that
Sequence Class:
Contrary to above class is Sequence class which generates the numbers in order.
static void SequenceEg(Args _args)
{
Sequence objSeq = new Sequence("Test Sequence",8,10,250,1);
print objSeq.currval(); // Displays the current value of the object
while(1)
{
print objSeq.nextval(10);
pause;
}
}
Sequence class takes the following parameters: SequenceName which can be a string of your choice, Identification No for the sequence, Initial Value, Maximum value
and a flag which indicates whether the cycle has to be repeated if maximum value is reached.
The method “nextVal” takes the value to be incremented for next number as parameter.
LastAOTSelection Class:
This class prints the last accessed AOT object by the user.
static void LastAOTSelectionEg(Args _args)
{
LastAOTSelection LS = new LastAOTSelection();
;
print LS.first().toString();
pause;
}
Keywords Class:
Class to list the available functions and keywords in Axapta.
static void KeywordsFunction(Args _args)
{
Keywords objKG = new Keywords();
str strOutput;
;
print Keywords::isValidIdentifier('dddd34'); // This method checks if the identifier is valid or nor
print Keywords::isValidIdentifier('*4532');
pause;
strOutput = objKG.firstFunction();
while(objKG.nextFunction()!= '')
{
strOutput = objKG.nextFunction();
info(stroutput);
}
}
static void KeywordsSymbol(Args _args)
{
Keywords objKG = new Keywords();
str strOutput;
;
strOutput = objKG.firstSymbol();
while (objKG.nextSymbol ()!='')
{
strOutput = objKG.nextSymbol();
info(stroutput);
}
}
This class generates random numbers.
static void RandomGenerateEg(Args _args)
{
RandomGenerate objRG = new RandomGenerate();
Random objRandom = new Random();
;
//This generates random numbers specified within the given range
info(int2Str(objRG.randomInt(10,55)));
//This generates random numbers
info(int2Str(objRandom.nextInt()));
}
Executing this job generates random numbers. But it doesn’t guarantee that the numbers will not be repeated. So if the user needs unique number, he has to provide explicit check for that
Sequence Class:
Contrary to above class is Sequence class which generates the numbers in order.
static void SequenceEg(Args _args)
{
Sequence objSeq = new Sequence("Test Sequence",8,10,250,1);
print objSeq.currval(); // Displays the current value of the object
while(1)
{
print objSeq.nextval(10);
pause;
}
}
Sequence class takes the following parameters: SequenceName which can be a string of your choice, Identification No for the sequence, Initial Value, Maximum value
and a flag which indicates whether the cycle has to be repeated if maximum value is reached.
The method “nextVal” takes the value to be incremented for next number as parameter.
LastAOTSelection Class:
This class prints the last accessed AOT object by the user.
static void LastAOTSelectionEg(Args _args)
{
LastAOTSelection LS = new LastAOTSelection();
;
print LS.first().toString();
pause;
}
Keywords Class:
Class to list the available functions and keywords in Axapta.
static void KeywordsFunction(Args _args)
{
Keywords objKG = new Keywords();
str strOutput;
;
print Keywords::isValidIdentifier('dddd34'); // This method checks if the identifier is valid or nor
print Keywords::isValidIdentifier('*4532');
pause;
strOutput = objKG.firstFunction();
while(objKG.nextFunction()!= '')
{
strOutput = objKG.nextFunction();
info(stroutput);
}
}
static void KeywordsSymbol(Args _args)
{
Keywords objKG = new Keywords();
str strOutput;
;
strOutput = objKG.firstSymbol();
while (objKG.nextSymbol ()!='')
{
strOutput = objKG.nextSymbol();
info(stroutput);
}
}
Number sequence implementation in Dynamics ax
You can download the document for implementing the number sequence form here
Using while select firstonly to avoid validations in Dynamics Ax
static void WhileSelectInsteadoFSelect(Args _args)
{
InventTable inventTable;
;
-----General way---------
//fetch the record first
select firstonly forupdate inventtable;
//add an additional validation
if (inventTable.recid)
{
inventTable.itemName = 'newname';
inventTable.update();
}
------Alternate--------------
//prevents the extra 'if' chek
while select firstonly forupdate inventTable
{
inventTable.itemName = 'newname';
inventTable.update();
}
//can also be used for simple readonly
while select firstonly inventTable
{
Info(inventTable.ItemId);
}
}
{
InventTable inventTable;
;
-----General way---------
//fetch the record first
select firstonly forupdate inventtable;
//add an additional validation
if (inventTable.recid)
{
inventTable.itemName = 'newname';
inventTable.update();
}
------Alternate--------------
//prevents the extra 'if' chek
while select firstonly forupdate inventTable
{
inventTable.itemName = 'newname';
inventTable.update();
}
//can also be used for simple readonly
while select firstonly inventTable
{
Info(inventTable.ItemId);
}
}
Finding if a node is existing in lower layers Dynamics Ax
UtilEntryLevel getHighestBelowCurLayer(TreeNode _treeNode)
{
UtilEntryLevel layer, highestLayer;
;
for (layer=UtilEntryLevel::sys; layer < UtilEntryLevel::bus; layer++)
{
if (SysTreeNode::isNodeInLayer(_treeNode, layer))
{
highestLayer = layer;
break;
}
}
return highestLayer;
}
{
UtilEntryLevel layer, highestLayer;
;
for (layer=UtilEntryLevel::sys; layer < UtilEntryLevel::bus; layer++)
{
if (SysTreeNode::isNodeInLayer(_treeNode, layer))
{
highestLayer = layer;
break;
}
}
return highestLayer;
}
Opening the Project node automatically in Dynamics Ax
static void JobOpeningProjectNodeInAoT(Args _args)
{
ProjectNode sharedProject = Infolog.projectRootNode().AOTfindChild('Shared');
ProjectNode projectNode = sharedProject.AOTfindChild('Docu');
;
if (projectNode)
{
projectNode.getRunNode();
}
}
{
ProjectNode sharedProject = Infolog.projectRootNode().AOTfindChild('Shared');
ProjectNode projectNode = sharedProject.AOTfindChild('Docu');
;
if (projectNode)
{
projectNode.getRunNode();
}
}
Exists methods don’t need table declaration in Dynamics Ax
static boolean SelectStatementInBooleanConditions()
{
//no declaration for table object has been made.
boolean test;
;
//testing a variable
test = (select firstonly salesTable).salesId ? true : false;
//if condition
if ((select firstonly salesTable).recid)
{
return true;
}
//switch statement
switch ((select firstonly salesTable).recid)
{
case 0:
return true;
case 1:
return false;
default:
return false;
}
//return statement
return ((select firstonly salesTable).recid);
}
{
//no declaration for table object has been made.
boolean test;
;
//testing a variable
test = (select firstonly salesTable).salesId ? true : false;
//if condition
if ((select firstonly salesTable).recid)
{
return true;
}
//switch statement
switch ((select firstonly salesTable).recid)
{
case 0:
return true;
case 1:
return false;
default:
return false;
}
//return statement
return ((select firstonly salesTable).recid);
}
Design Pattern used in Dynamics Ax Click here
Design Pattern used in Dynamics Ax Click here
Click here for Image
Click here for Image
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. Please be aware, that SQL can be really powerful, and it should be used as such.
Example #1: Retrieve data:
Since this example uses a Connecion class, data is retrieved from the database where Axapta is currently connected.
void Sample_1(void)
{
Connection Con = new Connection();
Statement Stmt = Con.createStatement();
ResultSet R =Stmt.executeQuery(‘SELECT VALUE FROM SQLSYSTEMVARIABLES’);
while ( R.next() )
{
print R.getString(1);
}
}
Example #2: Manipulating data (deletion):
void Sample_2(void)
{
str sql;
Connection conn;
SqlStatementExecutePermission permission;
;
sql = ‘delete from custTable’;
permission = new SqlStatementExecutePermission(sql);
conn = new Connection();
permission = new SqlStatementExecutePermission(sql);
permission.assert();
conn.createStatement().executeUpdate(sql);
// the permissions needs to be reverted back to original condition.
CodeAccessPermission::revertAssert();
}
Example #1: Retrieve data:
Since this example uses a Connecion class, data is retrieved from the database where Axapta is currently connected.
void Sample_1(void)
{
Connection Con = new Connection();
Statement Stmt = Con.createStatement();
ResultSet R =Stmt.executeQuery(‘SELECT VALUE FROM SQLSYSTEMVARIABLES’);
while ( R.next() )
{
print R.getString(1);
}
}
Example #2: Manipulating data (deletion):
void Sample_2(void)
{
str sql;
Connection conn;
SqlStatementExecutePermission permission;
;
sql = ‘delete from custTable’;
permission = new SqlStatementExecutePermission(sql);
conn = new Connection();
permission = new SqlStatementExecutePermission(sql);
permission.assert();
conn.createStatement().executeUpdate(sql);
// the permissions needs to be reverted back to original condition.
CodeAccessPermission::revertAssert();
}
how to capitalize all letters
tsBegin;
while
select forUpdate myTable
{
myTable.Description = strUpr(myTable.Description);
myTable.update();
}
ttsCommit
while
select forUpdate myTable
{
myTable.Description = strUpr(myTable.Description);
myTable.update();
}
ttsCommit
Multidimensional Expressions (MDX) click here
Introduction to Multidimensional Expressions (MDX) Click Here for PDF
This tutorial introduces multidimensional expressions (MDX), a highly
functional expression syntax for querying multidimensional data in Microsoft SQL
Server OLAP Services. It also discusses the structure of OLAP Services cubes and
explores the features of MDX.
See the attached file for more details
This tutorial introduces multidimensional expressions (MDX), a highly
functional expression syntax for querying multidimensional data in Microsoft SQL
Server OLAP Services. It also discusses the structure of OLAP Services cubes and
explores the features of MDX.
See the attached file for more details
Advance Data Types || Collection classes in AX 2012
Advance Data Types
1.List Class
2.Map Class
3.Set Class
4.Container
5.RecordSortedList
6.RecordInsertList
7.Temp table.
1.List Class
2.Map Class
3.Set Class
4.Container
5.RecordSortedList
6.RecordInsertList
7.Temp table.
Add AOT query to SysQueryForm
Below code can be used to add any AOT query to SysQueryForm.
SysQueryRun queryRun = new SysQueryRun(queryStr(TestQuery));
queryRun.form(formstr(SysQueryForm));
queryRun.title(‘Select a record’);
queryRun.prompt();
SysQueryRun queryRun = new SysQueryRun(queryStr(TestQuery));
queryRun.form(formstr(SysQueryForm));
queryRun.title(‘Select a record’);
queryRun.prompt();
Restoring the Database with the SQL command
RESTORE DATABASE AXDB
FROM DISK = ‘d:\test.bak’
WITH REPLACE
FROM DISK = ‘d:\test.bak’
WITH REPLACE
List class
List Class
Contains any number of elements that are accessed sequentially.
Lists are structures that can contain values of any X++ type.
All the values in the list must be of the same type. Type is defined when the list is created and cannot be changed.
All X++ types can be accessable using enum Types::
Lists can be traversed by using the Enumerator , ListEnumerator class. To create a ListEnumerator object, use List.getEnumerator.
First Example
List list = new List(Types::Integer);
Enumerator en ;
list.addEnd(333333); // add the value at last
list.addEnd(111111);
list.addEnd(222222);
en = list.getEnumerator();
print list.elements(); //"print number of element"
while (en.moveNext())
{
print en.current();
}
pause;
Second Example
List list1 = new List(Types::Integer);
List list2 = new List(Types::Integer);
List combinedList = new List(Types::Integer);
int i;
;
for(i=1; i<6; i++)
{
List1.addEnd(i);
}
for(i=6; i<11; i++)
{
List2.addEnd(i);
}
combinedList = List::merge(list1, list2);
print combinedList.toString();
pause;
Contains any number of elements that are accessed sequentially.
Lists are structures that can contain values of any X++ type.
All the values in the list must be of the same type. Type is defined when the list is created and cannot be changed.
All X++ types can be accessable using enum Types::
Lists can be traversed by using the Enumerator , ListEnumerator class. To create a ListEnumerator object, use List.getEnumerator.
First Example
List list = new List(Types::Integer);
Enumerator en ;
list.addEnd(333333); // add the value at last
list.addEnd(111111);
list.addEnd(222222);
en = list.getEnumerator();
print list.elements(); //"print number of element"
while (en.moveNext())
{
print en.current();
}
pause;
Second Example
List list1 = new List(Types::Integer);
List list2 = new List(Types::Integer);
List combinedList = new List(Types::Integer);
int i;
;
for(i=1; i<6; i++)
{
List1.addEnd(i);
}
for(i=6; i<11; i++)
{
List2.addEnd(i);
}
combinedList = List::merge(list1, list2);
print combinedList.toString();
pause;
Query “join table A with table B and table A with table C”
//
Query query = new Query();
QueryBuildDataSource qbds,qbds1,qbds2;
qbds = query.addDataSource(tableNum(CustTable));
qbds1 = qbds.addDataSource(tableNum(CustTrans));
qbds2 = qbds1.addDataSource(tableNum(CustLedgerTransTypeMapping));
qbds1.addLink(fieldNum(CustTrans,AccountNum),fieldNum(CustTable,AccountNum));
qbds2.addLink(fieldNum(CustTrans,TransType),fieldNum(CustLedgerTransTypeMapping,CustSettleTransType));
info(query.toString());
------------------
static void Job20(Args _args)
{
Query q;
QueryRun qr;
QueryBuildDatasource qbds1, qbds2;
QueryBuildRange qbr;
LedgerTable _LedgerTable;
;
q = new Query();
qbds1 = q.addDataSource(tablenum(LedgerTable));
qbds2 = qbds1.addDataSource(tablenum(LedgerTrans));
qbds2.relations(TRUE); //this enforces a relationship between this datasource and its parent. Relationships defined in the Data Dictionary are used by default.
qbr = qbds1.addRange(fieldnum(LedgerTable,
AccountNum));
//qbr.value(SysQuery::value("10000")); //SysQuery object provides various static methods to assist in defining Query criteria. The SysQuery::value() method should always be used when defining a singular value for a range.
qr = new QueryRun(q);
while(qr.next())
{
//do something
info(_LedgerTable.AccountNum);
}
}
Query query = new Query();
QueryBuildDataSource qbds,qbds1,qbds2;
qbds = query.addDataSource(tableNum(CustTable));
qbds1 = qbds.addDataSource(tableNum(CustTrans));
qbds2 = qbds1.addDataSource(tableNum(CustLedgerTransTypeMapping));
qbds1.addLink(fieldNum(CustTrans,AccountNum),fieldNum(CustTable,AccountNum));
qbds2.addLink(fieldNum(CustTrans,TransType),fieldNum(CustLedgerTransTypeMapping,CustSettleTransType));
info(query.toString());
------------------
static void Job20(Args _args)
{
Query q;
QueryRun qr;
QueryBuildDatasource qbds1, qbds2;
QueryBuildRange qbr;
LedgerTable _LedgerTable;
;
q = new Query();
qbds1 = q.addDataSource(tablenum(LedgerTable));
qbds2 = qbds1.addDataSource(tablenum(LedgerTrans));
qbds2.relations(TRUE); //this enforces a relationship between this datasource and its parent. Relationships defined in the Data Dictionary are used by default.
qbr = qbds1.addRange(fieldnum(LedgerTable,
AccountNum));
//qbr.value(SysQuery::value("10000")); //SysQuery object provides various static methods to assist in defining Query criteria. The SysQuery::value() method should always be used when defining a singular value for a range.
qr = new QueryRun(q);
while(qr.next())
{
//do something
info(_LedgerTable.AccountNum);
}
}
An eaxmple of List data structure in AX
static void ListSample(Args _args)
{
List list = new List(Types::Record);
Enumerator en ;
list.addEnd(333333);
list.addEnd(111111);
list.addEnd(222222);
en = list.getEnumerator();
while (en.moveNext())
{
print en.current();
}
pause;
}
{
List list = new List(Types::Record);
Enumerator en ;
list.addEnd(333333);
list.addEnd(111111);
list.addEnd(222222);
en = list.getEnumerator();
while (en.moveNext())
{
print en.current();
}
pause;
}
How to delete the Enum value at runtime
//if i need to delete the enum value at run time then what i need to do?
//Example has 3 values
//Enum::value1
//Enum::value2
//Enum::value3
//Answer: you need to overview the enter event of control from design and write the following //line.
combobox:enter()
{
super();
this.delete(enum2str(Enum::value2));
}
//Example has 3 values
//Enum::value1
//Enum::value2
//Enum::value3
//Answer: you need to overview the enter event of control from design and write the following //line.
combobox:enter()
{
super();
this.delete(enum2str(Enum::value2));
}
05 October 2010
04 October 2010
Creating Table with X++ Code
static void Create_Table_with_Code(Args _args)
{
SysDictTable sysdictTable;
treenode trv;// its a class
AOTTableFieldList fieldnode;
str prop;
int pos;
#AOT
#Properties
;
//#Table path refer the \\Data Dictionary\\Tables and finding the path
trv = treenode::findNode(#TablesPath);
//AOTadd method is to add table in tables//AAA is table name
trv.AOTadd('AAA');
trv = trv.AOTfindChild('AAA');
trv.AOTcompile(1);
trv.AOTsave();
trv.AOTfindChild('AAA');
fieldnode = trv.AOTfirstChild();
fieldnode.addString('AccountNum');
fieldnode = fieldnode.AOTfindChild('AccountNum');
prop = fieldnode.AOTgetProperties();
pos = findPropertyPos(prop,#PropertyExtendeddatatype); //find right place to put extended data type
pos = strFind(prop,'ARRAY',pos,strLen(prop));
pos = strFind(prop,'#',pos,strLen(prop));
prop = strins(prop,extendedTypeId2name(ExtendedtypeNum(CustAccount)),pos + 1);
// insert field of extended data type 'CustAccount'
fieldnode.AOTsetProperties(prop);
trv.AOTcompile(1);
trv.AOTsave();
trv.AOTRestore(); //to load assigned extended data type properties
sysdictTable = sysdictTable::newTreeNode(trv);
appl.dbSynchronize(sysdictTable.id());
}
{
SysDictTable sysdictTable;
treenode trv;// its a class
AOTTableFieldList fieldnode;
str prop;
int pos;
#AOT
#Properties
;
//#Table path refer the \\Data Dictionary\\Tables and finding the path
trv = treenode::findNode(#TablesPath);
//AOTadd method is to add table in tables//AAA is table name
trv.AOTadd('AAA');
trv = trv.AOTfindChild('AAA');
trv.AOTcompile(1);
trv.AOTsave();
trv.AOTfindChild('AAA');
fieldnode = trv.AOTfirstChild();
fieldnode.addString('AccountNum');
fieldnode = fieldnode.AOTfindChild('AccountNum');
prop = fieldnode.AOTgetProperties();
pos = findPropertyPos(prop,#PropertyExtendeddatatype); //find right place to put extended data type
pos = strFind(prop,'ARRAY',pos,strLen(prop));
pos = strFind(prop,'#',pos,strLen(prop));
prop = strins(prop,extendedTypeId2name(ExtendedtypeNum(CustAccount)),pos + 1);
// insert field of extended data type 'CustAccount'
fieldnode.AOTsetProperties(prop);
trv.AOTcompile(1);
trv.AOTsave();
trv.AOTRestore(); //to load assigned extended data type properties
sysdictTable = sysdictTable::newTreeNode(trv);
appl.dbSynchronize(sysdictTable.id());
}
Add Fields to a table, using X++ code_not the AOT In Dynamics Ax
// Create a New table in AOT with the name of moDocuref
static void createFieldFromCode(Args _args)
{
#AOT
TreeNode tableNode;
AotTableFieldList myAOTTablefieldList;
SysDictTable sysDictTable = new SysDictTable(tablenum(moDocuref));
;
if (! hasSecuritykeyAccess(securitykeynum(SysDevelopment),AccessType::View))
{
return;
}
myAOTTablefieldList = new AotTableFieldList();
tableNode = TreeNode::findNode(#TablesPath+'\\'+sysDictTable.name());
myAOTTablefieldList = TreeNode::findNode(#TablesPath+'\\'+sysDictTable.name() + "\\Fields");
if(!myAOTTablefieldList.AOTfindChild("newField")) // check if the field alredy exists
{
myAOTTablefieldList.addString("newField");
}
tableNode.AOTsave();
}
static void createFieldFromCode(Args _args)
{
#AOT
TreeNode tableNode;
AotTableFieldList myAOTTablefieldList;
SysDictTable sysDictTable = new SysDictTable(tablenum(moDocuref));
;
if (! hasSecuritykeyAccess(securitykeynum(SysDevelopment),AccessType::View))
{
return;
}
myAOTTablefieldList = new AotTableFieldList();
tableNode = TreeNode::findNode(#TablesPath+'\\'+sysDictTable.name());
myAOTTablefieldList = TreeNode::findNode(#TablesPath+'\\'+sysDictTable.name() + "\\Fields");
if(!myAOTTablefieldList.AOTfindChild("newField")) // check if the field alredy exists
{
myAOTTablefieldList.addString("newField");
}
tableNode.AOTsave();
}
29 September 2010
How to Use Temporary tables in reports
Ex:1 Report with datasource added
//Take a Report and Add a Table.
//Make sure that Table Properties set as "Temporary: YES" or
//In Report init method write this code "Tmtab.setTmp();" to make tamp
//Write the following code in the report Fetch Method
public boolean fetch()
{
str acc;
boolean ret;
// ret = super();
while select custTable
{
Tmtab_1.CustAccount = custTable.AccountNum;
Tmtab_1.doInsert();
this.send(Tmtab_1);
}
return true;
}
Ex:2 Report without Datasource
Step:1
Write the below code in fetch method
public boolean fetch()
{
str acc;
boolean ret;
// ret = super();
while select custTable
{
Tmtab.CustAccount = custTable.AccountNum;
Tmtab.doInsert();
//this.send(Tmtab);
element.execute(1);
}
return true;
}
Step:2
Create a display method and return the field value
//BP Deviation Documented
display CustAccount acc()
{
return Tmtab.CustAccount;
}
//Take a Report and Add a Table.
//Make sure that Table Properties set as "Temporary: YES" or
//In Report init method write this code "Tmtab.setTmp();" to make tamp
//Write the following code in the report Fetch Method
public boolean fetch()
{
str acc;
boolean ret;
// ret = super();
while select custTable
{
Tmtab_1.CustAccount = custTable.AccountNum;
Tmtab_1.doInsert();
this.send(Tmtab_1);
}
return true;
}
Ex:2 Report without Datasource
Step:1
Write the below code in fetch method
public boolean fetch()
{
str acc;
boolean ret;
// ret = super();
while select custTable
{
Tmtab.CustAccount = custTable.AccountNum;
Tmtab.doInsert();
//this.send(Tmtab);
element.execute(1);
}
return true;
}
Step:2
Create a display method and return the field value
//BP Deviation Documented
display CustAccount acc()
{
return Tmtab.CustAccount;
}
Working with Temporary Tables in forms
Ex: 1 Temp Table in Job
-----
static void tempTableData(Args _args)
{
CustTable custTable,tmpCustTable;
;
// Here setting custtable as Temprorary Table
tmpCustTable.setTmp();
while select custTable
{
//Here we are puting data to tempTable
tmpCustTable.data(custTable.data());
//printing tmpCustTable data
info(tmpCustTable.AccountNum);
}
}
----
Ex 2: Forms with datasource added
//Take a Form and Add a Table.
//Make sure that Table Properties set as "Temporary: YES" or
//In Form init method write this code "Tmtab.setTmp();" to make tamp
//Write the following code in the Form DataSource init() Method
public void init()
{
super();
while select custTable
{
TempTab.CustAccount = custTable.AccountNum;
TempTab.doInsert();
}
}
Ex 3: Forms without datasource added
.
.
.
Soon
-----
static void tempTableData(Args _args)
{
CustTable custTable,tmpCustTable;
;
// Here setting custtable as Temprorary Table
tmpCustTable.setTmp();
while select custTable
{
//Here we are puting data to tempTable
tmpCustTable.data(custTable.data());
//printing tmpCustTable data
info(tmpCustTable.AccountNum);
}
}
----
Ex 2: Forms with datasource added
//Take a Form and Add a Table.
//Make sure that Table Properties set as "Temporary: YES" or
//In Form init method write this code "Tmtab.setTmp();" to make tamp
//Write the following code in the Form DataSource init() Method
public void init()
{
super();
while select custTable
{
TempTab.CustAccount = custTable.AccountNum;
TempTab.doInsert();
}
}
Ex 3: Forms without datasource added
.
.
.
Soon
28 September 2010
Using DictTable
static void dictTable_Ex(Args _args)
{
DictTable dictTable;
DictField dictField;
TableId tableId;
FieldId fieldId;
;
tableId = tablenum(CustTable);
dictTable = new DictTable(tableId);
if(dictTable)
{
fieldId = dictTable.primaryKeyField();
if(0 != fieldId)
{
dictField = new DictField(tableId, fieldId);
if(dictField)
{
print strfmt("Primary key field name: %1", dictField.name());
pause;
}
}
}
}
{
DictTable dictTable;
DictField dictField;
TableId tableId;
FieldId fieldId;
;
tableId = tablenum(CustTable);
dictTable = new DictTable(tableId);
if(dictTable)
{
fieldId = dictTable.primaryKeyField();
if(0 != fieldId)
{
dictField = new DictField(tableId, fieldId);
if(dictField)
{
print strfmt("Primary key field name: %1", dictField.name());
pause;
}
}
}
}
Write EXCEL Document, export data to excel with X++
static void CreateExcelDocument (Args _args)
{
SysExcelApplication xlsApplication;
SysExcelWorkBooks xlsWorkBookCollection;
SysExcelWorkBook xlsWorkBook;
SysExcelWorkSheets xlsWorkSheetCollection;
SysExcelWorkSheet xlsWorkSheet;
SysExcelRange xlsRange;
CustTable custTable;
int row = 1;
str fileName;
;
// Name of the Excel document.
fileName = "C:\\test.xslx";
// Excel open and initialize.
xlsApplication = SysExcelApplication:: construct ();
xlsApplication.visible (true);
// Create an Excel Worksheet produce.
xlsWorkBookCollection = xlsApplication.workbooks();
xlsWorkBook = xlsWorkBookCollection.add();
xlsWorkSheetCollection = xlsWorkBook.worksheets();
xlsWorkSheet = xlsWorkSheetCollection.itemFromNum (1);
// Write to the worksheet cells headings.
xlsWorkSheet.cells (). item (row, 1). value ('Account Number');
xlsWorkSheet.cells (). item (row,2). value ('name');
row ++;
// Excel Worksheet with data fill / (Excel cells fill).
while select custTable
{
xlsWorkSheet.cells (). item (row, 1). value (custTable.AccountNum);
xlsWorkSheet.cells (). item (row, 2). value (custTable.Name);
row ++;
}
// Check whether the document already exists.
if (WINAPI:: fileExists (fileName))
{
Winapi:: DeleteFile (fileName);
}
// Save Excel document.
xlsWorkbook.saveAs(fileName);
// Close Excel.
xlsApplication.quit ();
xlsApplication.finalize ();
}
{
SysExcelApplication xlsApplication;
SysExcelWorkBooks xlsWorkBookCollection;
SysExcelWorkBook xlsWorkBook;
SysExcelWorkSheets xlsWorkSheetCollection;
SysExcelWorkSheet xlsWorkSheet;
SysExcelRange xlsRange;
CustTable custTable;
int row = 1;
str fileName;
;
// Name of the Excel document.
fileName = "C:\\test.xslx";
// Excel open and initialize.
xlsApplication = SysExcelApplication:: construct ();
xlsApplication.visible (true);
// Create an Excel Worksheet produce.
xlsWorkBookCollection = xlsApplication.workbooks();
xlsWorkBook = xlsWorkBookCollection.add();
xlsWorkSheetCollection = xlsWorkBook.worksheets();
xlsWorkSheet = xlsWorkSheetCollection.itemFromNum (1);
// Write to the worksheet cells headings.
xlsWorkSheet.cells (). item (row, 1). value ('Account Number');
xlsWorkSheet.cells (). item (row,2). value ('name');
row ++;
// Excel Worksheet with data fill / (Excel cells fill).
while select custTable
{
xlsWorkSheet.cells (). item (row, 1). value (custTable.AccountNum);
xlsWorkSheet.cells (). item (row, 2). value (custTable.Name);
row ++;
}
// Check whether the document already exists.
if (WINAPI:: fileExists (fileName))
{
Winapi:: DeleteFile (fileName);
}
// Save Excel document.
xlsWorkbook.saveAs(fileName);
// Close Excel.
xlsApplication.quit ();
xlsApplication.finalize ();
}
22 September 2010
Convert date type to datetime type in ax
static void convertDateToDateTime(Args _arg)
{
date d = today();
int timeOfDay;
UTCDateTime datetime;
;
timeOfDay = str2time('00:00:00');
datetime = DateTimeUtil::newDateTime(d, timeOfDay);
pause;
}
{
date d = today();
int timeOfDay;
UTCDateTime datetime;
;
timeOfDay = str2time('00:00:00');
datetime = DateTimeUtil::newDateTime(d, timeOfDay);
pause;
}
15 September 2010
Code To Copy Table records between Companies, crosscompnay
static void Transfer_Rec(Args _args)
{
DictTable dicttable;
DictField dictfield;
Common common,common1;
int fieldcnt,i;//Returns the number of fields for the table
fieldId fieldid; //Field from usertable
UserTable TempTable,TempTable1; // UserTable is the table, whose data u want to copy
;
while select TempTable
{
common = TempTable;
dicttable = new DictTable(common.TableId);
changeCompany("tst")
{
TempTable1 = null;
common1 = TempTable1;
fieldcnt = dicttable.fieldCnt();
for (i = 1; i <= fieldcnt; i++)
{
fieldid = dicttable.fieldCnt2Id(i);
dictfield = new dictfield(common.TableId,fieldid);
if (dictfield.id() == fieldname2id(common.TableId,identifierstr(dataareaid)))
continue;
else
common1.(dictfield.id()) = common.(dictfield.id());
}
common1.insert();
}
}
print strfmt('done');
pause;
}
{
DictTable dicttable;
DictField dictfield;
Common common,common1;
int fieldcnt,i;//Returns the number of fields for the table
fieldId fieldid; //Field from usertable
UserTable TempTable,TempTable1; // UserTable is the table, whose data u want to copy
;
while select TempTable
{
common = TempTable;
dicttable = new DictTable(common.TableId);
changeCompany("tst")
{
TempTable1 = null;
common1 = TempTable1;
fieldcnt = dicttable.fieldCnt();
for (i = 1; i <= fieldcnt; i++)
{
fieldid = dicttable.fieldCnt2Id(i);
dictfield = new dictfield(common.TableId,fieldid);
if (dictfield.id() == fieldname2id(common.TableId,identifierstr(dataareaid)))
continue;
else
common1.(dictfield.id()) = common.(dictfield.id());
}
common1.insert();
}
}
print strfmt('done');
pause;
}
14 September 2010
Microsoft Dynamics 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
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
Microsoft Dynamics AX Design Patterns
The Microsoft Dynamics AX design patterns listed below enable you to use existing code patterns
to resolve common design issues Click here
1. Instantiating Application Objects
2. Searching for Records
3. Searching for Multiple Occurrences
4. Parameter
5. static find Method
6. static exist Method
7. Pack-Unpack
8. Persistent Data Storage
9. Containers as Parameter Bags
10. Multi-selection
11. Partner Hooks
12. Use the Type System
13. Data Validation
14. Change Company
15. Storno
----
15.Change Company
static void main()
{
CustTable custTable;
;
// Assume that you are running in company 'aaa'.
changeCompany('bbb') // Default company is now 'bbb'.
{
custTable = null;
while select custTable
{
// custTable is now selected in company 'bbb'.
}
}
// Default company is again set back to 'aaa'.
changeCompany('ccc') // Default company is now 'ccc'.
{
// Clear custTable to let the select work
// on the new default company.
custTable = null;
while select custTable
{
// custTable is now selected in company 'ccc'.
}
}
// Default company is again 'aaa'.
}
to resolve common design issues Click here
1. Instantiating Application Objects
2. Searching for Records
3. Searching for Multiple Occurrences
4. Parameter
5. static find Method
6. static exist Method
7. Pack-Unpack
8. Persistent Data Storage
9. Containers as Parameter Bags
10. Multi-selection
11. Partner Hooks
12. Use the Type System
13. Data Validation
14. Change Company
15. Storno
----
15.Change Company
static void main()
{
CustTable custTable;
;
// Assume that you are running in company 'aaa'.
changeCompany('bbb') // Default company is now 'bbb'.
{
custTable = null;
while select custTable
{
// custTable is now selected in company 'bbb'.
}
}
// Default company is again set back to 'aaa'.
changeCompany('ccc') // Default company is now 'ccc'.
{
// Clear custTable to let the select work
// on the new default company.
custTable = null;
while select custTable
{
// custTable is now selected in company 'ccc'.
}
}
// Default company is again 'aaa'.
}
13 September 2010
insert_recordset & update_recordset
insert_recordset
void copySQLDictionary2DictionaryLine()
{
SqlDictionary sqlDictionary;
;
ttsBegin;
insert_recordset bufferDictionary(tabId, fieldId, array,
name, sqlName, fieldType, strSize, shadow,
rightJustify, nullable, flags)
select tabId, fieldId, array, name, sqlName, fieldType,
strSize, shadow, rightJustify, nullable, flags
from sqlDictionary
where sqlDictionary.tabId > 0;
ttsCommit;
}
------
update_recordset
MyTable myTableBuffer;
;
update_recordset myTableBuffer
setting
field1 = 1,
field2 = fieldX + fieldY
where field1 == 0;
void copySQLDictionary2DictionaryLine()
{
SqlDictionary sqlDictionary;
;
ttsBegin;
insert_recordset bufferDictionary(tabId, fieldId, array,
name, sqlName, fieldType, strSize, shadow,
rightJustify, nullable, flags)
select tabId, fieldId, array, name, sqlName, fieldType,
strSize, shadow, rightJustify, nullable, flags
from sqlDictionary
where sqlDictionary.tabId > 0;
ttsCommit;
}
------
update_recordset
MyTable myTableBuffer;
;
update_recordset myTableBuffer
setting
field1 = 1,
field2 = fieldX + fieldY
where field1 == 0;
13 August 2010
In SalesOrder (active Record) check the record is first packing slip has done or not,
form->DS->Methods->Active()
select firstonly custPackingSlipTrans
where custPackingSlipTrans.salesId == salesTable.salesId;
if(CustPackingSlipTrans)
{
element.toChangeTheNumSeq();//Method will exicute
}
select firstonly custPackingSlipTrans
where custPackingSlipTrans.salesId == salesTable.salesId;
if(CustPackingSlipTrans)
{
element.toChangeTheNumSeq();//Method will exicute
}
26 July 2010
To get the selected record into Report:
We can use this in Fetch or init in Report:
if(element.args().dataset() == tableNum(SalesTable))
{
salesTable = element.args().record();
salesId = salesTable.SalesId;
}
if(element.args().dataset() == tableNum(SalesTable))
{
salesTable = element.args().record();
salesId = salesTable.SalesId;
}
Barcode for Invent Serial Id
Reference Report:
INV->Reports->Labels->Serial number lable(RFID)
RFIDInventSerialLabels
INV->Reports->Labels->Serial number lable(RFID)
RFIDInventSerialLabels
21 July 2010
Validation for Field in Form level
Form->DS->Field->Validate()
public boolean validate()
{
boolean ret;
ret = super();
ret = Salestable.validateInventSite();
return ret;
}
-->
SalesTable->Methods->UserDefined Method
public boolean validateInventSite()
{
boolean ret = true;
SalesTable st;
if(this.DPT_NumberSequenceGroupId != this.InventSiteId)
{
ret = false;
info("Not allow to change the site");
}
return ret;
}
--------------------
public boolean validate()
{
boolean ret;
ret = super();
ret = Salestable.validateInventSite();
return ret;
}
-->
SalesTable->Methods->UserDefined Method
public boolean validateInventSite()
{
boolean ret = true;
SalesTable st;
if(this.DPT_NumberSequenceGroupId != this.InventSiteId)
{
ret = false;
info("Not allow to change the site");
}
return ret;
}
--------------------
17 July 2010
New Number Sequence for existing module AX 2009
New Number Sequence for existing module
1.Creare a EDT
2.Create a table
3.Class modify(NumberSeqReference_customer.. ->loadmodule())
4.table modify(salesParameter..purchParameters->numRefSalesId())
5.Create NumberSequence formtat(basic-setup-numbersequence)
6.Select the Reference field(basic-setup-ref)
(To use existing numberSequence in new form follow from the 7th step.)
7.Form modify(custTable..)Method-numberSeqFormHandler().
8.FormDatasource methods Modify(CustTable-DS-Create(),Write())
9.Open the form create new field.
1.Creare a EDT
2.Create a table
3.Class modify(NumberSeqReference_customer.. ->loadmodule())
4.table modify(salesParameter..purchParameters->numRefSalesId())
5.Create NumberSequence formtat(basic-setup-numbersequence)
6.Select the Reference field(basic-setup-ref)
(To use existing numberSequence in new form follow from the 7th step.)
7.Form modify(custTable..)Method-numberSeqFormHandler().
8.FormDatasource methods Modify(CustTable-DS-Create(),Write())
9.Open the form create new field.
16 July 2010
TO pop up the Field Like Sales crete order
Form: Sales crete order->Datasource
//SalesCreateOrderForm is class this return True
if (salesCreateOrderForm.lookupCustAccount())
{
salesTable_custAccount.setFocus();
salesTable_custAccount.lookup();
}
//SalesCreateOrderForm is class this return True
if (salesCreateOrderForm.lookupCustAccount())
{
salesTable_custAccount.setFocus();
salesTable_custAccount.lookup();
}
14 July 2010
numerals to text convert amout in rupees in axapta AX 2009 AX 2012 or Amount In words amount value to indian rupees word format
To change Numarals to text.
EX: 100 changed to One hundred Rupees Only
Global method:
static TempStr amountInWords(real _num)
{
int numOfPennies = (decround(frac(_num), 2) * 100) mod 100;
real test = _num - frac(_num);
int numOfTenths;
str 20 ones[19], tenths[9], hundreds, thousands, millions, billions, trillions;
int64 temp;
str 200 returntxt;
real modOperator(real a1, real a2)
{
int tmpi;
real tmp1, tmp2;
tmp1 = a1 / a2;
tmpi = real2int(tmp1);
tmp2 = tmpi;
return (tmp1 - tmp2)*a2;
}
real checkPower(real _test, int64 _power)
{
int64 numOfPower;
if (_test >= _power)
{
numOfPower = _test div _power;
if (numOfPower >= 100)
{
temp = numOfPower div 100;
returntxt = returntxt + ' ' + ones[temp] + ' ' + hundreds;
numOfPower = numOfPower mod 100;
}
if (numOfPower >= 20)
{
temp = numOfPower div 10;
returntxt = returntxt + ' ' + tenths[temp];
numOfPower = numOfPower mod 10;
}
if (numOfPower >= 1)
{
returntxt = returntxt + ' ' + ones[numOfPower];
numOfPower = numOfPower mod 10;
}
switch(_power)
{
case 1000000000000 :
{
returntxt = returntxt + ' ' + trillions;
_test = modOperator(_test, 1000000000000.00);
break;
}
case 1000000000 :
{
returntxt = returntxt + ' ' + billions;
_test = modOperator(_test, 1000000000);
break;
}
case 1000000 :
{
returntxt = returntxt + ' ' + millions;
_test = modOperator(_test, 1000000);
break;
}
case 1000 :
{
returntxt = returntxt + ' ' + thousands;
_test = modOperator(_test, 1000);
break;
}
case 100 :
{
returntxt = returntxt + ' ' + hundreds;
_test = modOperator(_test, 100);
break;
}
}
}
return _test;
}
ones[1] = "@SYS26620";
ones[2] = "@SYS26621";
ones[3] = "@SYS26622";
ones[4] = "@SYS26626";
ones[5] = "@SYS26627";
ones[6] = "@SYS26628";
ones[7] = "@SYS26629";
ones[8] = "@SYS26630";
ones[9] = "@SYS26631";
ones[10] = "@SYS26632";
ones[11] = "@SYS26633";
ones[12] = "@SYS26634";
ones[13] = "@SYS26635";
ones[14] = "@SYS26636";
ones[15] = "@SYS26637";
ones[16] = "@SYS26638";
ones[17] = "@SYS26639";
ones[18] = "@SYS26640";
ones[19] = "@SYS26641";
tenths[1] = 'Not used';
tenths[2] = "@SYS26643";
tenths[3] = "@SYS26644";
tenths[4] = "@SYS26645";
tenths[5] = "@SYS26646";
tenths[6] = "@SYS26647";
tenths[7] = "@SYS26648";
tenths[8] = "@SYS26649";
tenths[9] = "@SYS26650";
hundreds = "@SYS26651";
thousands = "@SYS26652";
millions = "@SYS26653";
billions = "@SYS26654";
trillions = "@SYS101697";
test = checkPower(test, 1000000000000);
test = checkPower(test, 1000000000);
test = checkPower(test, 1000000);
test = checkPower(test, 1000);
test = checkPower(test, 100);
if (test >= 20)
{
numOfTenths = test div 10;
returntxt = returntxt + ' ' + tenths[numofTenths];
numOfTenths = numOfTenths mod 10;
test = test mod 10;
}
if (test >= 1)
{
numOfTenths = real2int(test);
returntxt = returntxt + ' ' + ones[numOfTenths];
}
if (numOfPennies)
{
returntxt = '***' + returntxt + ' ' + "Rupees"+" "+"@SYS5534" + ' ' + numeralsToTxt(numOfPennies);
}
else
{
returntxt = '***' + returntxt + ' ' + "Rupees" + ' ' + "@SYP1450";
}
return returntxt;
}
EX: 100 changed to One hundred Rupees Only
Global method:
static TempStr amountInWords(real _num)
{
int numOfPennies = (decround(frac(_num), 2) * 100) mod 100;
real test = _num - frac(_num);
int numOfTenths;
str 20 ones[19], tenths[9], hundreds, thousands, millions, billions, trillions;
int64 temp;
str 200 returntxt;
real modOperator(real a1, real a2)
{
int tmpi;
real tmp1, tmp2;
tmp1 = a1 / a2;
tmpi = real2int(tmp1);
tmp2 = tmpi;
return (tmp1 - tmp2)*a2;
}
real checkPower(real _test, int64 _power)
{
int64 numOfPower;
if (_test >= _power)
{
numOfPower = _test div _power;
if (numOfPower >= 100)
{
temp = numOfPower div 100;
returntxt = returntxt + ' ' + ones[temp] + ' ' + hundreds;
numOfPower = numOfPower mod 100;
}
if (numOfPower >= 20)
{
temp = numOfPower div 10;
returntxt = returntxt + ' ' + tenths[temp];
numOfPower = numOfPower mod 10;
}
if (numOfPower >= 1)
{
returntxt = returntxt + ' ' + ones[numOfPower];
numOfPower = numOfPower mod 10;
}
switch(_power)
{
case 1000000000000 :
{
returntxt = returntxt + ' ' + trillions;
_test = modOperator(_test, 1000000000000.00);
break;
}
case 1000000000 :
{
returntxt = returntxt + ' ' + billions;
_test = modOperator(_test, 1000000000);
break;
}
case 1000000 :
{
returntxt = returntxt + ' ' + millions;
_test = modOperator(_test, 1000000);
break;
}
case 1000 :
{
returntxt = returntxt + ' ' + thousands;
_test = modOperator(_test, 1000);
break;
}
case 100 :
{
returntxt = returntxt + ' ' + hundreds;
_test = modOperator(_test, 100);
break;
}
}
}
return _test;
}
ones[1] = "@SYS26620";
ones[2] = "@SYS26621";
ones[3] = "@SYS26622";
ones[4] = "@SYS26626";
ones[5] = "@SYS26627";
ones[6] = "@SYS26628";
ones[7] = "@SYS26629";
ones[8] = "@SYS26630";
ones[9] = "@SYS26631";
ones[10] = "@SYS26632";
ones[11] = "@SYS26633";
ones[12] = "@SYS26634";
ones[13] = "@SYS26635";
ones[14] = "@SYS26636";
ones[15] = "@SYS26637";
ones[16] = "@SYS26638";
ones[17] = "@SYS26639";
ones[18] = "@SYS26640";
ones[19] = "@SYS26641";
tenths[1] = 'Not used';
tenths[2] = "@SYS26643";
tenths[3] = "@SYS26644";
tenths[4] = "@SYS26645";
tenths[5] = "@SYS26646";
tenths[6] = "@SYS26647";
tenths[7] = "@SYS26648";
tenths[8] = "@SYS26649";
tenths[9] = "@SYS26650";
hundreds = "@SYS26651";
thousands = "@SYS26652";
millions = "@SYS26653";
billions = "@SYS26654";
trillions = "@SYS101697";
test = checkPower(test, 1000000000000);
test = checkPower(test, 1000000000);
test = checkPower(test, 1000000);
test = checkPower(test, 1000);
test = checkPower(test, 100);
if (test >= 20)
{
numOfTenths = test div 10;
returntxt = returntxt + ' ' + tenths[numofTenths];
numOfTenths = numOfTenths mod 10;
test = test mod 10;
}
if (test >= 1)
{
numOfTenths = real2int(test);
returntxt = returntxt + ' ' + ones[numOfTenths];
}
if (numOfPennies)
{
returntxt = '***' + returntxt + ' ' + "Rupees"+" "+"@SYS5534" + ' ' + numeralsToTxt(numOfPennies);
}
else
{
returntxt = '***' + returntxt + ' ' + "Rupees" + ' ' + "@SYP1450";
}
return returntxt;
}
13 July 2010
eccNo in report through Programmable section
Programmable section->
//BP Deviation Documented
display TaxRegistrationNumberExcise_IN eccNumber()
{
CompanyInfo companyInfo;
;
companyInfo = CompanyInfo::find();
//select companyInfo;
return companyInfo.ECCNumber_IN;
}
---
//BP Deviation documented
display TaxRegistrationNumber_IN tinNo()
{
;
select TIN_IN from custTable
where custTable.AccountNum == salesTable.CustAccount
&& salesTable.SalesId == salesId;
return custTable.TIN_IN;
}
//BP Deviation Documented
display TaxRegistrationNumberExcise_IN eccNumber()
{
CompanyInfo companyInfo;
;
companyInfo = CompanyInfo::find();
//select companyInfo;
return companyInfo.ECCNumber_IN;
}
---
//BP Deviation documented
display TaxRegistrationNumber_IN tinNo()
{
;
select TIN_IN from custTable
where custTable.AccountNum == salesTable.CustAccount
&& salesTable.SalesId == salesId;
return custTable.TIN_IN;
}
03 June 2010
Hi,You can use 'TextBuffer' for manipulating the text.
___________________________________
static void Job4(Args _args)
{
TextBuffer buffer;
str source;
;
source = "I am first.I am second.I am third";
buffer = new TextBuffer();
buffer.setText(source);
while (buffer.nextToken(0, '.'))
{
info (buffer.token());
}
}
static void Job4(Args _args)
{
TextBuffer buffer;
str source;
;
source = "I am first.I am second.I am third";
buffer = new TextBuffer();
buffer.setText(source);
while (buffer.nextToken(0, '.'))
{
info (buffer.token());
}
}
06 May 2010
TO Move the records Up and Down in Form Grid
TO Move the records up and down in Form Grid
Check the following Form:
AOT->Form-> HRCCompLevel
Check the following Form:
AOT->Form-> HRCCompLevel
07 April 2010
How to read one element from dimensions in Forms and Reports
Use Display Method
Display SysDim department()
{
return VendTable_1.Dimension[1];//Here 1 means Department Element
}
Display SysDim department()
{
return VendTable_1.Dimension[1];//Here 1 means Department Element
}
29 March 2010
AOT MAPs in Dynamicis AX with example
mapping different fields with the same EDT from different tables to each other.
Please click here for better example
For example let's that you have an a customer Table and a vendors table and
you want to fill in the fields of a new table from these tables.
If maps did not exist you would have to do this in your new table:
void initFromCustTable(CustTable _custTable)
{
this.AccountNum = _custTable.AccountNum;
this.Name = _custTable.Name;
this.country = _custTable.Country;
this.language = _custTable.Language;
}
AND
void initFromCustTable(VendTable _vendable)
{
this.AccountNum = _vendable.AccountNum;
this.Name = _vendable.Name;
this.country = _vendable.Country;
this.language = _vendable.Language;
}
BUT
if you use a map (mapping newTable, CustTable and Vendor) all you need is
this:
void initFromCustVendMap(CustVendMap _custVendMap)
{
this.AccountNum = _custVendMap.AccountNum;
this.Name = _custVendMap.Name;
this.country = _custVendMap.Country;
this.language = _custVendMap.Language;
}
ONLY once on the map and then you just call the same method with different
buffers:
this.initFromCustVendMap(YourCustTableBuffer);
this.initFromCustVendMap(YOurVendTableBuffer); // NOTE same method but
different buffer.
for more info visit:
http://msdn.microsoft.com/en-us/library/bb278211(AX.10).aspx
Please click here for better example
For example let's that you have an a customer Table and a vendors table and
you want to fill in the fields of a new table from these tables.
If maps did not exist you would have to do this in your new table:
void initFromCustTable(CustTable _custTable)
{
this.AccountNum = _custTable.AccountNum;
this.Name = _custTable.Name;
this.country = _custTable.Country;
this.language = _custTable.Language;
}
AND
void initFromCustTable(VendTable _vendable)
{
this.AccountNum = _vendable.AccountNum;
this.Name = _vendable.Name;
this.country = _vendable.Country;
this.language = _vendable.Language;
}
BUT
if you use a map (mapping newTable, CustTable and Vendor) all you need is
this:
void initFromCustVendMap(CustVendMap _custVendMap)
{
this.AccountNum = _custVendMap.AccountNum;
this.Name = _custVendMap.Name;
this.country = _custVendMap.Country;
this.language = _custVendMap.Language;
}
ONLY once on the map and then you just call the same method with different
buffers:
this.initFromCustVendMap(YourCustTableBuffer);
this.initFromCustVendMap(YOurVendTableBuffer); // NOTE same method but
different buffer.
for more info visit:
http://msdn.microsoft.com/en-us/library/bb278211(AX.10).aspx
23 March 2010
Select Multiple records in Grid ,update and print and read the data source records
//THis Code can use for to select multiple record in Grid and we can updater the status of the field, and in
// to enable while in selection of records, menuitem->properties->multiselect= Yes.
void clicked()
{
HRMApplication hrmApplicationlocal,local;
;
super();
for (hrmApplicationlocal = hrmApplication_ds.getFirst(true) ? hrmApplication_ds.getFirst(true) : hrmApplication; hrmApplicationlocal; hrmApplicationlocal = hrmApplication_ds.getNext())
{
ttsbegin;
select forupdate local where local.hrmApplicationId == hrmApplicationlocal.hrmApplicationId;
local.status = HRMApplicationStatus::Interview;
local.update();
ttscommit;
}
hrmApplication_ds.executeQuery();
}
--------------------
void clicked()
{
Table2 custTransOpenLoc;
Counter c;
;
super();
for (custTransOpenLoc = Table2_ds.getFirst(0,1);
custTransOpenLoc;
custTransOpenLoc=Table2_ds.getNext())
{
c++;
info(strfmt("%1",C));
}
}
------------------
void clicked()
{
FormDataSource fdS = CustTransOpen_ds;
CustTransOpen custTransOpenLoc;
;
breakpoint;
for (custTransOpenLoc = fdS.getFirst(true) ? fdS.getFirst(true) : CustTransOpen;
custTransOpenLoc;
custTransOpenLoc=fdS.getNext())
{
info();
}
super();
}
// to enable while in selection of records, menuitem->properties->multiselect= Yes.
void clicked()
{
HRMApplication hrmApplicationlocal,local;
;
super();
for (hrmApplicationlocal = hrmApplication_ds.getFirst(true) ? hrmApplication_ds.getFirst(true) : hrmApplication; hrmApplicationlocal; hrmApplicationlocal = hrmApplication_ds.getNext())
{
ttsbegin;
select forupdate local where local.hrmApplicationId == hrmApplicationlocal.hrmApplicationId;
local.status = HRMApplicationStatus::Interview;
local.update();
ttscommit;
}
hrmApplication_ds.executeQuery();
}
--------------------
void clicked()
{
Table2 custTransOpenLoc;
Counter c;
;
super();
for (custTransOpenLoc = Table2_ds.getFirst(0,1);
custTransOpenLoc;
custTransOpenLoc=Table2_ds.getNext())
{
c++;
info(strfmt("%1",C));
}
}
------------------
void clicked()
{
FormDataSource fdS = CustTransOpen_ds;
CustTransOpen custTransOpenLoc;
;
breakpoint;
for (custTransOpenLoc = fdS.getFirst(true) ? fdS.getFirst(true) : CustTransOpen;
custTransOpenLoc;
custTransOpenLoc=fdS.getNext())
{
info();
}
super();
}
22 March 2010
TO select multiple Records Using check box field in form and To change the status in field values like Openorder, invoiced, recevied
Table level
Add a field to ur table which is used as data source in ur form ,
for that field use enum type : noyes in field property:
Form level:
-
public void init()
{
super();
ttsbegin;
while select forupdate custTable where custTable.Choose == NOYes::Yes
{
custTable.Choose = NOYes::No;
custTable.update();
}
ttscommit;
}
--
--
void clicked()
{
super();
//if(CustTable.Choose)
ttsbegin;
// while select CustTable
// where CustTable.Choose == noyes::Yes
while select forupdate CustTable
where CustTable.Choose == noyes::Yes
{
CustTable.StatusSag = statussag::OpenStatus;
CustTable.Choose = noyes::No;
CustTable.Update();
}
ttscommit;
CustTable_ds.executeQuery();
}
--
void clicked()
{
super();
//if(CustTable.Choose)
ttsbegin;
while select forupdate CustTable
where CustTable.Choose == noyes::Yes
{
CustTable.StatusSag = statussag::CloseTrans;
CustTable.Choose = noyes::No;
CustTable.Update();
}
ttscommit;
CustTable_ds.executeQuery();
}
Add a field to ur table which is used as data source in ur form ,
for that field use enum type : noyes in field property:
Form level:
-
public void init()
{
super();
ttsbegin;
while select forupdate custTable where custTable.Choose == NOYes::Yes
{
custTable.Choose = NOYes::No;
custTable.update();
}
ttscommit;
}
--
--
void clicked()
{
super();
//if(CustTable.Choose)
ttsbegin;
// while select CustTable
// where CustTable.Choose == noyes::Yes
while select forupdate CustTable
where CustTable.Choose == noyes::Yes
{
CustTable.StatusSag = statussag::OpenStatus;
CustTable.Choose = noyes::No;
CustTable.Update();
}
ttscommit;
CustTable_ds.executeQuery();
}
--
void clicked()
{
super();
//if(CustTable.Choose)
ttsbegin;
while select forupdate CustTable
where CustTable.Choose == noyes::Yes
{
CustTable.StatusSag = statussag::CloseTrans;
CustTable.Choose = noyes::No;
CustTable.Update();
}
ttscommit;
CustTable_ds.executeQuery();
}
Subscribe to:
Posts (Atom)
Ledger Voucher creation Framework and x++ code to create ledger voucher
Please click her for MS reference file Below is the out of the box example reference and code. SalesInvoiceJournalPostSubBill_Extension->...
-
{ "Message" : "Please verify that the user is valid and set up correctly." } Sol: System Administration > Se...
-
Please click here to access Custom Workflow step by step process:
-
FormRun formRun = sender.formRun(); Object inventTrans_ds = formRun.dataSource(formDataSourceStr(InventMarking,InventTransO...