Thursday, 24 December 2015

How to Change Date format in Ax 2012

static void CON_DateFormat(Args _args)
{
    date todaydate = today();
    str s;

    s = date2str(todaydate,123,DateDay::Digits2,DateSeparator::Hyphen,
DateMonth::Short,DateSeparator::Hyphen,DateYear::Digits4);

    info(strFmt("Today date is " + s));
}

Types of Form Templates in AX 2012

Types of Form Templates in AX 2012:
There are seven different predefined form templates in ax 2012.
  • ListPage
  • DetailsFormMaster
  • DetailsFormTransaction
  • SimpleListDetails
  • SimpleList
  • TableOfContents
  • Dialog
  • DropDialog
ListPage – 
                 A list page is a form that displays a list of data related to a particular entity or business object. A list page provides provisions for displaying data and taking actions on this data. Every module has at least a couple of list pages. List pages are further classified as primary and secondary list pages. A secondary list page will only display a subset of data from the primary list page. Example, CustTableListPage, VendTableListPage, ProjProjectsListPage. Best practice is to have ListPage as a suffix in the name of the form for all list pages.
DetailsFormMaster
              This template is used for forms which display data for stand-alone entities or business objects. Example includes Customers, Vendors, and Projects etc. If you look at the forms for these, i.e. CustTable, VendTable, ProjTable, their style property will be set to DetailsFormMaster.
DetailsFormTransaction
             This template is used for forms which display data for entities which have child records associated with it. In other words, if the data being displayed is header-lines type in nature, use this template. Example, Sales orders, Purchase orders etc. If you look at the style property of SalesTable, VendTable, their properties will be set to DetailsFormTransaction.
SimpleListDetails – 
             This template is used to display primary fields in a list and detailed data in a tab page. This style is useful to view all records in a form and selecting a particular record will bring up their details. Example includes HcmSkillMapping, etc.
SimpleList – 
            This template is a very basic form which displays data in a grid. No extra or fancy detail is displayed. This style is best suited for forms where data being shown is not very detailed in nature or has limited fields. Example includes AifAction, etc.
TableOfContents – 
          This template is the new style which should be adopted for all parameter forms in Dynamics AX 2012. Take a look at any parameters form and its style property will be set to TableOfContents. This style sets all the tabs as a hot link in the left hand side navigation pane. Clicking on the link will bring up the controls on that tab page. This style is a very neat and appealing UI design which is surely welcome. Example includes Custparameters, vendparameters, etc.
Dialog –  
         This template is used on forms which show static data or are intended to capture some user input for further actions. These forms are mostly modal in nature and should be dismissed before any further actions can be taken.
DropDialog – 
          This template is used for forms that are used to gather quick user inputs to perform an action. Drop dialog forms are generally attached to an action pane button. They appear to be dropping from the menu button when clicked. Example includes HcmWorkerNewWorker,  HcmPositionWorkerAssignmentDialog.

Monday, 21 December 2015

How to Install Complete Ax 2012 R3

How to Create Sales Quotation through X++ code in Ax 2012

static void CreateSalesQuotation(Args _args)
{
    AxSalesQuotationTable       axSalesQuotationTable;
    AxSalesQuotationLine        axSalesQuotationLine ;
    SalesQuotationTable         salesQuotationTable;
    SalesQuotationLine          salesQuotationLine;
    CustTable                   custTable;
    InventTable                 inventTable;
    SalesQty                    salesQty;
    SalesPrice                  salesPrice;
    SalesLineDisc               salesLineDisc;
    SalesLinePercent            salesLinePercent;
    container                   conItems = ["ItemA","Dell","HP"];
    int                         i =0;
    InventDim                   inventDim;
    SalesQuotationEditLinesForm salesQuotationEditLinesForm;
    ParmId                      parmId;
    SalesQuotationUpdate        salesQuotationUpdate;
    ;

    salesQty                    = 10;
    SalesPrice                  = 100;
    salesLineDisc               = 1;
    salesLinePercent            = 1;
    axSalesQuotationTable =  new AxSalesQuotationTable();
    axSalesQuotationTable.parmCustAccount('Jaga');
    axSalesQuotationTable.parmCurrencyCode('USD');
    axSalesQuotationTable.save();

    for(i = 1; i<= conLen(conItems); i++)
    {
        axSalesQuotationLine =  new AxSalesQuotationLine();//::construct(smmQuotationLine);

        axSalesQuotationLine.axSalesQuotationTable(axSalesQuotationTable);

        axSalesQuotationLine.parmQuotationId(axSalesQuotationTable.parmQuotationId());
        axSalesQuotationLine.axSalesQuotationTable(axSalesQuotationTable);
        axSalesQuotationLine.parmItemId(conPeek(conItems,i));

        axSalesQuotationLine.parmSalesQty(salesQty);
        axSalesQuotationLine.parmSalesPrice(SalesPrice);
        axSalesQuotationLine.parmLineDisc(SalesLineDisc);
        axSalesQuotationLine.parmLinePercent(SalesLinePercent);
        inventDim.InventSiteId      = "1";
        inventDim.InventLocationId  = "11";


        axSalesQuotationLine.parmInventDimId('002504');
        axSalesQuotationLine.parmcurrencyCode('USD');
        axSalesQuotationLine.save();
    }

    //Quotation status -- sent
    if(!axSalesQuotationTable.salesQuotationTable()) return;
    salesQuotationEditLinesForm =
    SalesQuotationEditLinesForm::construct(DocumentStatus::Quotation); //DocumentStatus
    parmId                      = salesQuotationEditLinesForm.parmId();


    salesQuotationEditLinesForm.initParmSalesQuotationTable(axSalesQuotationTable.salesQuotationTable());

    salesQuotationEditLinesForm.parmId(parmId);
    salesQuotationEditLinesForm.parmTransDate(systemdateget());

    salesQuotationEditLinesForm.prePromptInit();

    salesQuotationEditLinesForm.initParameters(NoYes::No, //printFormletter,
                                               NoYes::No,
//transferHours2Forecast,
                                               NoYes::No,
//transferExpenses2Forecast,
                                               NoYes::No,
//transferFees2Forecast,
                                               NoYes::No,
//transferItems2Forecast,
                                               'Competency',
//reasonCode,
                                               NoYes::No);
//usePrintManagement)
    salesQuotationEditLinesForm.run();

    /// Quotation status -- Confirmation
    if(!axSalesQuotationTable.salesQuotationTable())
        return;
    salesQuotationEditLinesForm =
    SalesQuotationEditLinesForm::construct(DocumentStatus::Confirmation); //DocumentStatus
    //Quotation o Confirm
    parmId                      = salesQuotationEditLinesForm.parmId();


    salesQuotationEditLinesForm.initParmSalesQuotationTable(axSalesQuotationTable.salesQuotationTable());

    salesQuotationEditLinesForm.parmId(parmId);
    salesQuotationEditLinesForm.parmTransDate(systemdateget());

    salesQuotationEditLinesForm.prePromptInit();

    salesQuotationEditLinesForm.initParameters(NoYes::No, //printFormletter,
                                               NoYes::No,
//transferHours2Forecast,
                                               NoYes::No,
//transferExpenses2Forecast,
                                               NoYes::No,
//transferFees2Forecast,
                                               NoYes::No,
//transferItems2Forecast,
                                               'Competency',
//reasonCode,
                                               NoYes::No);
//usePrintManagement)
    salesQuotationEditLinesForm.run();

}

How to Open Project through X++ Code in Ax 2012

static void OpenProjectThroughCode(Args _args)
{
    ProjectNode     projectType,projectNode;

    projectType = infolog.projectRootNode().AOTfindChild('Shared');
    projectNode = projectType.AOTfindChild('Your Project Name Which You want to open');
    if(projectNode)
    {
        projectNode.getRunNode();
    }

}

Tuesday, 15 December 2015

How to Get Selected Customer all Transaction using Morphx Reports in Ax 2012


  • Design a Form as Below 

  • Here I Added a Button Named as Print 
             I have Overrided Clicked Method
              void clicked()
              {

                    Args args = new args();
                    ReportRun reportRun;
                    ;

                    args.parm(Customers.valueStr());       //Customers indicates Lookup name
                    args.name(reportstr("Custtrans"));     //Custtrans indicates Morphx report name
                    reportRun = classFactory.reportRunClass(args);
                    reportRun.init();
                    reportrun.run();
                   //reportRun.wait();
                   //args.parmObject( args );
                   super();
                }
  • Added a StringEdit control Named as Customers               //Auto declaration Yes
            I have overrided Lookup Method
          public void lookup()
         {
                Query query = new Query();
                QueryBuildDataSource queryBuildDataSource;
                QueryBuildRange queryBuildRange;
                SysTableLookup sysTableLookup =               SysTableLookup::newParameters(tableNum(custTable), this);
                sysTableLookup.addLookupField(fieldNum(CustTable, AccountNum));
                sysTableLookup.performFormLookup();
               //super();
           }

  • Design a Morphx Report



     Under Report override Init Method
     public void init()

    {
    Query query1 = new Query();
    QueryBuildDataSource queryBuildDataSource;
    QueryBuildRange queryBuildRange;
    str var;
    ;

    var = element.args().parm();

    try
    {
      if(element.args().parm())
      {
           query1.addDataSource(tablenum(CustTrans)).addRange(fieldnum(CustTrans, AccountNum)).value(queryValue(element.args().parm()));
           this.query(query1);
           this.query().userUpdate(false);
           this.query().interactive(false);

           super();

      }
     }
     catch(exception::Error)
     {
       info("Error in init method");
     }
}
  • Now Open Form and Select Customer and Click on Print 



  • Finally Report appears for Selected Customer (Here I selected US-013)





Thursday, 10 December 2015

Containers in Ax

Container

   X++ (Object oriented programming language) the data or values 
   stored in a Variable are of below types:
  • Primitive dataTypes - int, str, real .... etc.
  • Composite dataTypes - Arrays, Containers, Collection Classes
Container Functions

1.ConPeek( )
  • The conPeek() is used to retrieve a specific element from a container.
  • Syntax: anytype conPeek(container container, int number)
    • container - The container to return an element from.
    • number - The position of the element to return. 
                               Specify 1 to get the first element.
  • Return value: The element in the container at the position specified
 by the number parameter. The conPeek function automatically converts
 the peeked item into the expected return type.
Ex :   static void Ex_Conpeek(Args _args)
         {
               container   c = ['Test', 27,'Rajendra',10.000000000];

               info(strFmt('%1 - %2', conPeek(c, 1), conPeek(c, 2)));
               info(strFmt('%1 - %2', conPeek(c, 1),conPeek(c, 3)));
               info(strFmt('%1 - %2', conPeek(c, 1),conPeek(c, 4)));
         }
























2.ConPoke( )

  • The conPoke() is used to modify a container by replacing 
        one or more of the existing elements.
Syntax: 
  • container conPoke(container container, int start, anytype element, ...)
    • container - The container to modify.
    • start - The position of the first element to replace.
    • element - One or more elements to replace, separated by commas.
  • Return value: The new container with the inserted elements.

Ex : static void Ex_Conpoke(Args _args)
       {
            container   con = ["Rajendra",123]; //intial data 
            con     = conPoke(con,2,143143);  // after modification Done
            info(strFmt("%1 - %2",conPeek(con,1),conPeek(con,2)));
        }

























3.ConIns()
  • conIns() is used to insert one or more elements into a container.
  • Syntax: container conIns(container container, int start, anytype element, ...)
    • container - The container into which to insert elements.
    • start - The position at which to insert elements.
    • element - One or more elements to insert, separated by commas.
  • Return value: The new container with the inserted elements.
Ex : static void Ex_ConIns(Args _args)
{
    container   con = ["Rajendra",410];//intial container Data
    con = conIns(con,3,123456);       //After Data Inserted into Container
    info(strFmt("%1 - %2 - %3",conPeek(con,1),conPeek(con,2),conPeek(con,3)));
}

















4.ConFind( )

  • The conFind() is used to find the first occurrence of an element or a sequence of elements in a container.
  • Syntax: int conFind (container container, anytype element,... )
    • container - The container to search.
    • element - One or more elements to search for, separated by commas.
  • Return value: Returns 0 if the item was not found; otherwise, the sequence number of the item.
Ex:   static void Ex_ConFind(Args _args)
  {
        container   con = ["Rajendra",410];
    // conFind() function finds position in the container that a certain value
    info(strFmt("410 is found at position %1   - Rajendra is found at position %2",conFind(con,410),conFind(con,"Rajendra")));
}


















5.ConLen( )
  • The conLen() is used to retrieve the number of elements in a container.
  • Syntax: int conLen(container container)
    • container - The container in which to count the number of elements.
  • Return value: The number of elements in the container.
Ex : static void Ex_ConLen(Args _args)
{
    container   con = ["Rajendra",123,'A',4.2525];
    info(strFmt("Length of a Container is %1",conLen(con)));
}

















6.ConDel( )
  • The conDel() is used to remove the specified number of elements from a container.
  • Syntax: container conDel(container container, int start, int number)
    • container - The container from which to remove elements.
    • start - The one-based position at which to start removing elements.
    • number - The number of elements to delete.
  • Return value: A new container without the removed elements.
Ex: static void Ex_ConDel(Args _args)
{
    container   con = ["Rajendra",1254];
    con =  conDel(con,2,1);
    info(strFmt("%1--%2 ",conPeek(con,1),conPeek(con,2))); // 0 indicates that 1254 has been deleted & no element is there

}

















7.Connull( )
  • The conNull() is used to retrieve an empty container. Use this function to explicitly dispose of the contents of a container.
  • Syntax: container conNull()
  • Return value: An empty container.
Ex : static void Ex_ConNull(Args _args)
{
    container   con = ["Hello","Welcome","To","Ax",2012,"R3"];
    info(strFmt("Container conNull()  before : %1 - %2 - %3 - %4
 - %5 -%6",conPeek(con,1),conPeek(con,2),conPeek(con,3),conPeek(con,4)
,conpeek(con,5),conPeek(con,6))); 

    con = conNull(); //clears the container

    info(strFmt("Container conNull()  after  : %1 - %2 - %3 - %4 - %5 - %6",conPeek(con,1),conPeek(con,2),conPeek(con,3),conPeek(con,4),
conpeek(con,5),conPeek(con,6)));
    
}


To check the mandatory fields in a table through X++ code

static void checkProperties(Args _args)
{
    DictTable       dictTable;
    DictField       dictField;
    int             i, cnt;
 
    dictTable = new DictTable(tableNum(CustTrans));
    cnt = dictTable.fieldCnt();
    for (i= 1; i<=cnt;i++)
    {
        dictField = new DictField(tableNum(CustTrans),dictTable.fieldCnt2Id(i));
        if (dictField.mandatory())
        {
            info (strFmt("Field %1 is mandatory.",dictField.label()));
        }
    }
   
}


Basic Important SQL Keywords in Ax 2012

Keyword                                  Example
ascSet the sorting order to ascending. All selects are default 
fetching
data ascending.
Syntax: select custTable order by accountNum asc;
descSet the sorting order to descending. Used in combination with 
order by or group by.
Syntax: select custTable order by name desc;
AX Example: See table method CustTable.lastPayment().
avgSelect uses aggregate keyword (avg) using only one call to the
 database calculating a result based on multiple records
Syntax: select avg(amountMST) from custTrans;
AX Example: See class method KMKnowledgeCollectorStatisticsExecute.runQuery().
countAggregate keyword used to count the number of records
 fetched.
Syntax: select count(recId) from custTrans;
AX Example: See class method KMKnowledgeCollectorStatisticsExecute.runQuery().
sumAggregate keyword used to sum values of a field fetched.
Syntax: select sum(amountMST) from custTrans;
AX Example: See class method KMKnowledgeCollectorStatisticsExecute.runQuery().
maxofAggregate keyword used to return the highest field value 
fetched
Syntax: select maxOf(amountMST) from custTrans;
AX Example: See class method KMKnowledgeCollectorStatisticsExecute.runQuery().
minofAggregate keyword used to return the lowest field value fetched.
Syntax: select minOf(amountMST) from custTrans;
AX Example: See class method KMKnowledgeCollectorStatisticsExecute.runQuery().
delete_fromWill delete multiple records in one call to the database.
Syntax
delete_from myTable where myTable.amountMST <='1000';
AX Example
See class method InventCostCleanUp.updateDelSettlement().
exists joinExists join is used to fetch records where at least one record
 in the secondary table matches the join expression.
No records will be fetched from the secondary table using 

exists join.
Syntax: while select custTable exists join custTrans
where custTable.accountNum == custTrans.accountNum
AX Example
See class method InventAdj_Cancel.cancelInventSettlements().
notexists joinOpposite of exists join. Will fetch records from the primary table, 
where no records in the secondary table match the join expression.
Syntax: while select custTable notexists join custTrans
where custTable.accountNum == custTrans.accountNum
AX Example
See class method InventConsistencyCheck_Trans.run().
outer joinOuter join will select records from both tables regardless 
if there are any records in the secondary table matching the
 join expression.
Syntax: while select custTable outer join custTrans
AX Example: See class method SysHelpStatistics.doTeams().
joinJoin will fetch Records matching the join expression from 
both tables. (inner join)
Syntax: while select custTable join custTrans
where custTable.accountNum == custTrans.accountNum
AX Example: See table method SalesTable.LastConfirm().
firstfastInstruct to select the first record faster. used in situations 
where only one record is shown, like in a dialog.
Syntax: select firstfast custTable order by accountNum;
AX Example
See class method ProjPeriodCreatePeriod.dialog().
firstonlyFirst record will be selected. Firstonly should always be
 used when not using while in selects.
Syntax
select firstonly custTable where custTable.AccountNum 
== _custAccount (variable)
AX Example: See Table method CustTable.find().
forupdateUsed If records in a select are to be updated
Syntax: while select forupdate reqTransBOM where reqTransBOM.ReqPlanId    ==  this.ReqPlanId
AX Example
See Table method ReqTrans.deleteExplosionCoverage().
fromDefault all fields of a table is selected. From is used to
 select only the fields specified.
Use it for optimization only, as it makes the code more complex.
Syntax: select accountNum, name from custTable;
group bySort the fetched data group by the fields specified. 
Only the fields specified in the group by will be fetched.
Syntax: while select custTable group by custGroup;
AX Example: See class method InventStatisticsUS.calcTotals().
indexUsed to set the sorting order of the fetched data. 
The kernel will convert the keyword index to an order by
 using the fields from the index.
Index should only be used if the fetched data must 

be sorted in a specific way, as the database will choose a proper index.
Syntax: while select custTable index accountIdx.
index hintIndex hint will force the database to use the specified index.
Syntax: while select custTable index hint accountIdx.
AX Example: See Table method ReqTrans.deleteExplosionCoverage().
insert_recordsetUsed to insert multiple records in a table. Insert_recordset
 is useful when copying data from one table to another as
 it only requires one call to the database
Syntax: insert_recordset myTable (myNum,mySum)
select myNum, sum(myValue) from anotherTable group 

by myNum where myNum <= 100;
AX Example: See class method SysLicenseCodeReadFile.handleDomainLicenseChanges().
update_recordsetUsed  to update multiple records in one database call. 
Useful to initialize fields in a fast way.
The fields updated are specified after thekeyword setting.
Syntax: update_recordset myTable setting field1 = myTable.field1 * 1.10;
AX Example: See class method ProdUpdHistoricalCost.postScrap().