Jan 25, 2012

Three rules when declaring variables in X++?


  1.  Declare all variables before anything else in the code
  2.  Use a ';' (semicolon) after each declaration.
  3.  Use a ';' (semicolon) to separate the declarations from the rest of
the code.

Classes & methods that can be created in X++ and their differences.



The different kinds classes in AX are as follows:

1 Application classes - we implement them in X++, and they are located at AOT --> Classes.

2 System classes (or kernel classes) - They are implemented in C++. The source for these classes is not available in AX.
Ex :- xSession , xApplication ,xCompany ,xInfo ,xClassFactory ,xGlobal ,xVersionControl

3 Application substituted kernel classes are extensions of system classes.
EX :- Session , Application ,Company ,Info ,ClassFactory ,Global ,VersionControl


Object methods can only be activated by an object that has been

instantiated from the specific class. An object method is called as

follows:

Class_name ref_name = new Class_name ();
ref_name.testmethod();


Class methods can be attached directly to a class and do not need an

instantiated object to work. Use the 'static' modifier when you create

class methods. A class method is called as follows:

Class_name::testmethod();

If a report attached to a form ,how can the report display the values of the selected one in form?


suppose i put my report on the  CustPackingSlipJour  form then i selected on e record,i want to display the information of that particular record only in my report then the following code helps    

public class ReportRun extends ObjectRun
{
    CustPackingSlipJour     externalCustPackingSlipJour;
}

public void init()
{
    element.initFromArgs(element.args());
    super();
}

void initFromArgs(Args args)
{
    if (args && args.dataset())
    {
        switch(args.dataset())
        {
               case tablenum(CustPackingSlipJour) :
                                        externalCustPackingSlipJour  =   args.record();        
        }
     } 
}

How to change the item if we want to change the item ?


  • Click stockManagement à Items
  • Rightclick the Item number field .
  • Select record info ,and then click rename.
  • Type the new item number 
  • Click Ok. 

How to convert the amount into words ?


display tempStr amountStr()
{
    if(netAmount <= 0)

    return   '-'+ ' ' + '(' + currCode + ') ' + numeralsToTxt(-(netAmount))+' '+'Only';

    else

    return   '(' + currCode + ') ' + numeralsToTxt_EN(netAmount)+' ' +'Only';
}

How to update only few records?


Sample code in X++ to update the few records...

Static void main updateIds(Args  args)
{
EmplTable  empltable;
 
Ttsbegin;
while select forUpdate EmplTable Index hint EmplIdIdx
                              where EmplTable.EmplId == ‘10001’;
If(emplTable.recId != 0)
{
    emplTable.EmplId = ‘10101’(New EmplId);
    EmplTable.renamePrimaryKey();
    EmplTable.update()
}
Else
{
    Info(‘employee not found’);
}
ttsCommit;
}

How to update the existing records?


For example to change old emplId’s with new emplId’s

Create CSV file with two columns – one Old EmplId ans second new emplId

Write a job to – step 1) Read the CSV file
                           step 2) the job should look for old EmplId’s
                           step 3) once the EmplId found it should replace with new EmplId

All long the job should keep a count of number of employees read and number of employees updated

How to get current time in AX ?


Simple code to display timeNow()  in X++ which returns current time

static void timeNowExample(Args _arg)
{
    TimeInMS  i;
    ;

    i = timeNow();
    info(time2str(i,0,0));

}
str time2Str( int _time, int _separator, int _timeFormat)

The parameters of the function time2Str are described as below:

_time            : The number of seconds since midnight.
_separator   : The characters to be used as separators in the text string. Possible values  follow:  
0 – regional settings for the operating system
1 – colon (:) 
2 – point (.)
3 – space ( )
4 – comma (,)
5 – forward slash (/)

_timeFormat  : Determines whether a 12-hour or 24-hour clock is used. Possible values  follow:

How to display date and time according to time zone ?


static void Job7(Args _args)
{
   ;
   //Current Date and Time according to time zone
   info(strFmt('%1',DateTimeUtil::newDateTime(systemdateget(),                                                                    timenow(),Timezone::GMT_CASABLANCA_MONTROVIA_REYKJAVIK)));

 //Todays Max Date and Time
info(strfmt("%1",DateTimeUtil::newDateTime(SystemDateGet(),Global::timeMax())));

}            

How to supress the infolog which opens after opening a report?


Write the following code in init()  of the report

                              this.printJobSettings().supressScalingMessage(true);

The report property ‘FitToPage’(Check under Design node) indicates whether resized to fit the width of the page

How to set the shared folder to VPC ?


In VPC à Edit à Settings à Shared folders à browse the location

If ur shared folders are disabled then run your VPC and click action à install all updated Virtual machines and install them ,after installation ur shared folders will be enabled 

Jan 24, 2012

How to delete all the transactional data in AX ?


Run the class " SysDataBaseTransDelete " à It will prompt wheather you want to delete all the transactional data

How to reverse a string in AX?

A simple job to reverse a string


static void strReverve(Args _args)
{
str  s;
int  i;
;
s =  'Test Info';
info(strReverse(s));
}

How to display a Bitmap ?


Simple code to display a bitmap image

display Bitmap footerImage()
{
    ;
    return SysResource::getResourceNodeData(SysResource : : getResourceNode('Name of the Image'));
}

The image should be in AOT --> Resources

How to filter the data based on combo selection ?


DataDic-->Tables--->MedicineTable-->Fields

ItemId(string)
ItemExpired(enum)
ExpiryDate(date)

Medicine-->BaseEnums-->ItemExpired
ItemExpired :: Yes
                      No
                      All

MedicineInfoForm-->Methods-->classDeclaration

public class FormRun extends ObjectRun
{
    QueryBuildRange qbr;
}

 MedicineInfoForm -->DataSources--> MedicineTable -->Methods-->init()

public void init()
{
;
    super();
    qbr =    MedicineTable_ds.query().dataSourceTable(tablenum( MedicineTable )).addRange(fieldnum( MedicineTable ,ItemExpired));
    qbr.value(queryValue(ComboBox.selection()));
}

MedicineInfoForm-->Design--->Design-->Group : ItemExpired--->ComboBox:combobox-->Methods-->
modified()

public boolean modified()
{
    boolean ret;

    ret = super();

    if(combobox.selection()== ItemExpired::All)
    {
    qbr.value('');
    }
    else
    {
    qbr.value(queryValue(ComboBox.selection()));
    }

     MedicineTable_ds .executeQuery();

    return ret;
}

Display the data on the title bar


Code to disply the emp_id on the title bar of the form

Path : MyEmplForm-->Data Sources-->MyEmplTable-->Methods-->active()


public int active()
{
    int  ret;
    ret  = super();
    element.design().caption(EmpLeaveDetails.Emp_Id);
    return  ret;
}



Jan 22, 2012

How to create EDT ?


How create Extended Data Types in AOT : EDT’s are User Defined Datatypes which are extended by another Datatypes or another EDT

·         Go to AOT àData Dictionaryà Extended Data Types àNew Data Types


·         Go to Properties of the New EDT and set the properties.

Relations in EDT :

·         If we want to reuse the the values of parent table field in child tables field then we can create a relation on EDT to that particular field of parent table .
·         By extending this EDT in a same type of field in child table then the values from parent table field should come in look up of child tables field.

At  EDT Level we have the following relations

·         Normal

EDT == table.field ;

·         Related Field Fix

How to create table


How to create a table in AOT :

·         Select  Data Dictionary à select Tables



  •          Right Click àSelect New TableàRight on the New Table Click àSelect Properties and set the properties
  •       Expand the Table à select Fields à right click àselect required data type for that particular field and set        properties
  •           You can also drag and drop the existing fields from another tables



Notes:

  •          The properties marked with bold text have been changed specifically for the selected element.
  •           The pink background that you will see in the Name property means that it is mandatory








How to create dialog and how to filter on dialog values of the report


   public class ReportRun extends ObjectRun
   {
   TransDate                           startDate , endDate;
   DialogField                         dialogfield1,dialogfield2;
   MyTable                             myTable;

    #define.CurrentVersion(2)
    #localMacro.CurrentList
        startDate,
        endDate
    #endMacro 
   }

   public Object dialog(Object _dialog)
  {
    DialogRunbase dialog = _dialog;
    ;
    dialog.caption('Dialog for date details');
    dialog.addGroup('Period :');
    dialogfield1 = dialog.addField(typeid(Transdate),'From date');
    dialogfield1.value(startDate);
    dialogfield2 = dialog.addField(typeid(Transdate),'To date');
    dialogfield2.value(endDate);
    return dialog;
  }


boolean getFromDialog()
{
    ;
    startDate   =   dialogfield1.value();
    endDate     =   dialogfield2.value();
    return true;
}


public container pack()
{
    return [#CurrentVersion, #CurrentList];
}


public boolean unpack(container _packedClass)
{
    Version version = RunBase::getVersion(_packedClass);
    switch (version)
    {
        case(#CurrentVersion) :
            [version, #CurrentList] = _packedClass;
            break;
        default :
            return false;
    }
    return true;
}


public boolean fetch()
{
    boolean ret;
    ;
    ret      = super();
   queryRun = new QueryRun(this);
   //queryRun.query().clearBaseQueries();
   queryRun.query().addDataSource(tablenum( myTable )).addRange(
                    fieldnum( myTable ,mydateField)).value(queryRange(startDate,endDate));
   return  true;
}





How to create dynamic column in a report



    container                                    projectId , projectIdLabel , projCon;
    MyTable                                    externalTable ;
    ProjTable                                   ProjTable ;
    ReportTextControl                      reportText , custName ;
    ReportPromptControl                 headerPrompt1 , headerPrompt2 , headerPrompt3 ;
    ReportSection                            bodySection , bodyHeaderSec ;
    int                                               i;
   CustTable                                   custTable ;


public void executeSection()
{

    int    i;
    ;
    super();

    bodyHeaderSec = element.report().design().addProgrammableSection(2);
    bodyHeaderSec.leftMargin(2,Units::char);
    bodyHeaderSec.bottomMargin(1.5,units::char);



    bodySection = element.report().design().addProgrammableSection(1);
    bodySection.leftMargin(2,Units::char);
    custName = bodySection.addControl(tableNum(CustTable),fieldNum(CustTable,AccountNum));
    custName.name('CustNameLabel');

    headerPrompt1 = bodyHeaderSec.addPromptControl(tablenum(CustTable));
    headerPrompt1.label('Customer name');
    headerPrompt1.modelFieldName(custName.name());

    i = 0;

    while select count(ProjId) from externalTable group by  externalTable.CategoryId
                                              join ProjTable
                                              where  externalTable. ProjId == ProjTable.ProjId
                                              &&  ProjTable.CustAccount == custTable.AccountNum

        {
            if( externalTable .CategoryId)
            {
            i++;
            projectId  =  conins(projectId,i, externalTable . ProjId) ;
            reportText =  bodySection.addTextControl(conpeek(projectId,i));
            reportText.width(6,units::char);
            projCon = conins(projCon, i ,'ProjIdCountLabel' + int2str(i));
            reportText.name('ProjIdCountLabel'+int2str(i));

            projectIdLabel = conins(projectIdLabel,i,'FAM'+ int2str(i));
            headerPrompt2 = bodyHeaderSec.addPromptControl(tablenum( externalTable ));

            headerPrompt2.label(conpeek(projectIdLabel,i));
            headerPrompt2.modelFieldName('ProjIdCountLabel'+int2str(i));

            }

        }

    bodyHeaderSec.executeSection();
    bodySection.executeSection();

}

Jan 9, 2012

How to change the date format


static void dateJob(Args _args)
{
    date currentDate = today();
    str s;
    ;
    s = date2Str
        (currentDate,
        123,
        DateDay::Digits2,

        DateSeparator::Dot, // separator1
        DateMonth::Short,
        DateSeparator::Dot, // separator2

        DateYear::Digits2
        );
    info("Today is:  " + s);
}

Filter through the query


static void Medical_Info(Args _args)
{
    Query q;
    QueryRun qr;
    QueryBuildDatasource qbd;
    QueryBuildRange qbr;
    Medicine m;
    ;
    q = new Query();
    qbd = q.addDataSource(tablenum(Medicine));
    qbr = qbd.addRange(fieldNum(medicine,Item_Expired));
    qbr.value(queryValue(Item_Expired::No));
    qr = new SysQueryRun(q);

    while(qr.next())
    {
    m = qr.get(tableNum(Medicine));
    info(m.Item_id);

    }

}


Lexical and Syntax errors in Macros


When you are developing code that contains macros, you must understand whether an error message is generated during the precompile or the compile phase. The two key words to look for are:
            
                           Lexical – This indicates a precompile error.
                           Syntax – This indicates a compile error.

#define.MyMacro1(info("Hello");)  -  Lexical error caused by the first closing parenthesis, which marks the end of the directive. Therefore the precompiler is confused by the last two characters ;)

#define.MyMacro2(++++iTest;)  (or) #MyMacro2  -  A Syntax error caused by using the non-existent ++++ operator. The X++ compiler encounters this operator after #MyMacro2 is replaced by the macro value.
The macro definition is correct even though its value is not accepted X++ syntax.

X++ Functions


In Microsoft Dynamics AX, the X++ language provides more than 100 system functions that are not part of any class. The two types of functions are as follows:
  • Run time – functions that are executed during run time.
  • Compile time – functions that are executed during compile time.

Run time functions used for data type conversions, mathematical operations, and so on. Some common run time functions are as follows:
                 str2Int – creates an int value from a str value.
                 abs – creates a positive real value from a real value that is either positive or negative.
                 conFind – retrieves the location of an element in a container.


Call Runtime Functions from .Net


       The logic of the X++ run time functions is also implemented in the following .NET assembly:
        Microsoft.Dynamics.AX.Xpp.Support.DLL


         Inside the previous assembly, the X++ run time functions are implemented as static methods of the following class:Microsoft.Dynamics.AX.Xpp.PredefinedFunctions


Compile time functions are executed early in the compile of X++ code. Most of these functions retrieve metadata about items that are in the Application Object Tree (AOT). Some common compile time functions are as follows:
                 classNum – retrieves the ID of a class.
                 classStr – verifies during compile time that a class by that name exists. This is better than discovering the error later during run time.
                 evalBuf – evaluates the input string of X++ code, and then returns the results as a string.
                 literalStr – retrieves a label ID when given the string representation of a label, such as the string "@SYS12345".       For example, myLabel.exists(literalStr("@SYS12345"));


Note:
1) Compile time functions are sometimes called intrinsic functions.
2) X++ compile time functions cannot be called from a .NET program.


How to doInsert the values to a table ?


A new record is inserted with the name 'My name' in the name field and the value 100 in the value field.
ttsBegin;
 
myTable.name = 'My name';
myTable.value = 100;
 
myTable.doInsert();
 
ttsCommit;

How to insert and update a record into a table?


Following example inserts a new record into the MyTable table, with the AccountNum set to 1000 and the Name set to MyName (other fields in the record will be blank).

MyTable  MyTable
;
ttsBegin;

select MyTable ;
MyTable.AccountNum = '1000';
MyTable.Name = 'MyName';
MyTable.insert();
  
ttsCommit;

Following example updates the record in the MyTable table  with the AccountNum  1000 ,AccountNum set 1000 to "100012" and  the Name set MyName to NewName 
MyTable  MyTable
;
ttsBegin;
  
select forUpdate MyTable where MyTable.AccountNum = "1000";
 ;
MyTable.AccountNum = '100012';
MyTable.Name = 'NewName';
MyTable.update();
  
ttsCommit;

How to update a table ?


For example selects the table myTable for update. Any records with the name equal to 'my name' are updated. The AmountMST field has 100 added to its current value, and the AccountNum field is changed to account number 1050.
tsBegin;
select forUpdate myTable
         where myTable.Name=='My name';
 
myTable.AmountMST += 100;
myTable.AccountNum = 1050;
 
MyTable.update();
 
ttsCommit;

how to design a form through the code


static void createForm(Args _args)
{
    Args args;
    Form form;
    FormRun formRun;
    FormBuildDesign formBuildDesign;
    FormBuildDataSource formBuildDataSource;
    FormBuildDataSource formBuildDataSource2;
    FormBuildGridControl formBuildGridControl;
    FormDataSource formDataSource;
    DictTable dictTable;
    DictTable dictTable2;
    int idx;
    ;
    // Create the form header.
    form = new Form();

    // Add data sources to the form.
    dictTable = new DictTable(tablenum(CustTable));
    formBuildDataSource = form.addDataSource(dictTable.name());
    formBuildDataSource.table(dictTable.id());
    dictTable2 = new DictTable(78);
    formBuildDataSource2 = form.addDataSource(dictTable2.name());
    formBuildDataSource2.table(dictTable2.id());

    // Create the form design.
    formBuildDesign = form.addDesign("Design");

    // Add a grid control.
    formBuildGridControl =
 formBuildDesign.addControl(FormControlType::Grid, "Table Grid");
    formBuildGridControl.dataSource(dictTable.name());

    // Add a data field to the grid control.
    formBuildGridControl.addDataField(formBuildDataSource.id(),
    dictTable.fieldName2Id("AccountNum"));

    args = new Args();
    args.object(form);

    // Create the run-time form.
    formRun = new FormRun(Args);
    formRun.run();
    formRun.detach();

    // Return an object for the first data source,
    // and then display a query form.
    formdatasource = formRun.dataSource(1);
    formdatasource.prompt();
}

Jan 4, 2012

How to write a find() in a table


 
static  MyTable find(PrimarykeyEDT  _PrimaryKey)
{
MyTable  MyTable  ;
;
select firstonly   MyTable  ;

return (  MyTable);
}

=============  (OR) =============


public static  MyTable  find(EDTDocumentId _DocumentId, boolean _forupdate = false)
{
     MyTable   MyTable  = null;
    ;

     MyTable .selectForUpdate(_forupdate);

    if(_DocumentId)
    {
        select firstonly MyTable
        where  MyTable DocumentId == _DocumentId;
    }

    return  MyTable ;
}

      Example of find()
=================


static COL_ShipmentTerms find(COL_ShipmentTermId     ShipmentTermId,
                       boolean          _forUpdate = false,
                       ConcurrencyModel _concurrencyModel = ConcurrencyModel::Auto)
{
    COL_ShipmentTerms  shipmentTerms;
    ;

    if (ShipmentTermId)
    {
        if (_forUpdate)
        {
            shipmentTerms.selectForUpdate (_forUpdate);
            if (_concurrencyModel != ConcurrencyModel::Auto)
                shipmentTerms.concurrencyModel(_concurrencyModel);
        }
        shipmentTerms.selectLocked    (_forUpdate);

        select firstonly shipmentTerms
            index hint ShipmentTermIdx
            where shipmentTerms.ShipmentTermId == ShipmentTermId;
    }

    return shipmentTerms;
}