Tuesday, April 7, 2015

Useful functions for container

conLen:

conLen function is used to get the container length.

conPeek:

conPeek is used to get the container content by index. Note: index starts by 1.

conIns:

conIns function is used to insert one or more elements into a container. For example:
static void Hari_Test_ConIns(Args _args)
{
    container   c;
    int         i;
    c = [3, 'third'];
    c = conIns(c, 1, 1, 'first', 2, 'second');
   
    for(i = 1; i <= conLen(c); i++)
    {
        info(strFmt('%1', conPeek(c, i)));
    }
}

Result:
1
first
2
second
3
third

Note: += is faster than conIns function. We can use conIns when you want to insert the element in the particular index.

conDel:

conDel function is used to delete the one or more elements from the container. For example:
static void Hari_ConDel(Args _args)
{
    container   c;
    int         i;
    c = [3, 'third'];
    c = conIns(c, 1, 1, 'first', 2, 'second');
    c = conDel(c, 5, 2);
    for(i = 1; i <= conLen(c); i++)
    {
        info(strFmt('%1', conPeek(c, i)));
    }
}

Result:
1
first
2
second

conFind:

conFind function is used to find the sequence elements in the container. For example:
static void Hari_ConFind(Args _args)
{
    container c = ["item1", "item2", "item3"];
    int i, j, k, l;
    ;

    i = conFind(c, "item2");
    j = conFind(c, "item1", "item2");
    k = conFind(c, "item1", "item3");
    l = conFind(c, "item4");
   
    print "Position of 'item2' in container is " + int2Str(i);
    print "Position of 'item1 item2' in container is " + int2Str(j);
    print "Position of 'item1 item3' in container is " + int2Str(k);
    print "Position of 'item4' in container is " + int2Str(l);
    pause;
}

Result:
Position of 'item2' in container is 2
Position of 'item1 item2' in container is 1
Position of 'item1 item3' in container is 0
Position of 'item4' in container is 0

conNull:

conNull function is used to empty or dispose the contents of the container.

conPoke:

conPoke function is used to replace the contents of the container from the particular index. For example:
static void Hari_TestJob(Args _args)
{
    container c1 = ["item1", "item2", "item3"];
    container c2;
    int i;

    void conPrint(container c)
    {
        for (i = 1 ; i <= conLen(c) ; i++)
        {
            print conPeek(c, i);
        }
    }
    ;
    conPrint(c1);
    c2 = conPoke(c1, 2, "PokedItem", "Test");
    print "";
    conPrint(c2);
    pause;
}

Result:
item1
item2
item3

item1
PokedItem

Test

Container Data Type in AX 2012

Introduction

Container is a one of the data type in ax. We can hold more primitive data type values in a single container. Container index starts by 1 not 0. For example:

container   c = ['Test', 27];
info(strFmt('%1 - %2', conPeek(c, 1), conPeek(c, 2)));

Result: Test – 27

Table Field Type:

Container is one of the table field data type. So, we can store the container directly in to the database table field. In SQL, container table field data type is treated as varbinary datatype field.

Store container in another container:

We can also store one container in another container. For example:

int         i;
container   c = ['Test', 27], d = ['Second'];   
c += d;
   
for(i = 1; i <= conLen(c); i++)
{
    info(strFmt('%1', conPeek(c, i)));
}

Result:
Test
27
Second

Value based:

It is a value based structure. We can’t store any class objects in this container. It is not a reference based data type. If you assign one container in another container, the container will be copied not linked by reference. For example:

int         i;
container   c = ['First'], d;   
c += d;
d += ['Second'];
for(i = 1; i <= conLen(c); i++)
{
    info(strFmt('%1', conPeek(c, i)));
}

Result:
First

When we use container

As per the above code, we add d container in c and adding “Second” string value in the d container after adding. But “Second” value is not added in the c container. So, if you pass container as argument to the method, it creates new container. So, performance will be slow.
If you want to handle different data types, container is the good choice. But, if you add repeated value like list in the container, it is not a good choice, because it will affect performance.

Containers are immutable

Immutable means once the variable is declaration, we can’t change the size. Here container is an immutable object. When we add, delete and update the container, new container will create.

The following statements all create a new container.

myContainer = [1]; // new container created for myContainer
myContainer += [2]; // new new container created for myContainer
myContainer4 = myContainer5; // new container created for myContainer4

Insert performance:


+= is faster than conIns function. We can use conIns when you want to insert the element in the particular index.

Sunday, April 5, 2015

Primitive data types in AX 2012

1. Anytype Data Type:

Anytype is a placeholder for any data types (integer, real, string, container, class, etc.).
Please refer this link for more information.

2. Booleans

We can use Boolean for true or false values.

3. Dates

Dates data type is used to handle date value (date, month, year).

Assign value:
date d1 = 31\3\2015;

We can add days and subtract date easily. For example:
date d1 = 31\3\2015;
d1 = d1 + 3; //Add two day, result: Apr 3, 2015
d1 = d1 - 1; //Subtract one day, Result Apr 2, 2015

Date range is Jan 1, 1900 to Dec 31, 2154

4. Enums

Enum is an abbreviation of enumerated text. It contains list of literals. Enum literals represented as integer values. First Enum literal value is 0, next literal value is 1 and so on. We can use maximum 251 literals in single Enum.

We can create Enum in the AOT -> Base Enums.  We can declare this Enum in X++ like other data types (ex: Integer)

Declaration:
NoYes    isCompleted;

Assign value:
isCompleted = NoYes::Yes;

If you assign this Enum data type EDT in the combo box, the Enum literals are coming as combo box options.

Enums as Radio button
If you drag the form data source enum field in the design, the combo box control will be added (combo box is default control for enums). If you want radio button (radiobutton) control instead of combo box, add the radio button control by right click on design node and go to New Control -> RadioButton. Set the data source and data field property of the radio button.

If you want to set Enums in the un bound radio button control, select the Enum Type or use ExtendedDataType properties.

5. GUIDS

GUID is a Globally Unique Identifier. It is a unique no across all computers and networks. The unique identifier is generated by Microsoft algorithm. We can use this data type if we need globally unique no.

Hint: To check the GUID empty value, we can use the nullValueBaseType Global class method.
Example:
if(this.PurchReqLineRefId == nullValueBaseType(Types::Guid))

6. Integers

It is a number without decimal point.
Two integer types are there:
int (32 bit)
int64 (64 bit)
int range is - 2,147,483,648 to 2,147,483,647
int64 range is - 9,223,372,036,854,775,808 to 9,223,372,036,854,775,807

Declaration:
int a = 27;

7. Reals

Real data type is used to hold decimal numbers.

Declaration:
real   r1 = 10.03;

8. Strings

It is used for strings (number of characters). Range is unlimited.
We can set the length in the StringSize property of the EDT or table field. In X++, we can set maximum length in the declaration section. For example:
str 60 testStr;
As per the above declaration code, we can assign only 60 characters.

9. TimeOfDay

TimeOfDay datatype variable is used to hold time of the day. It represents integer value. Its range is 0 to 86400 (86400 means 23:59:59).

TimeOfDay   t1 = 28800;
info(strFmt('%1', time2str(t1, TimeSeparator::Colon, TimeFormat::AMPM)));

Result: 08:00:00 am

time2str function is used to display the time in the specify format.

10. UtcDateTime

UtcDateTime variable is used to hold date and time value.

Assign value:
utcdatetime myUtc2 = 1988-07-20T13:34:45;

Friday, April 3, 2015

Anytype Data Type

What is Anytype Data Type

Anytype is a placeholder for any data types (integer, real, string, container, class, etc.). The data type will be initialized to the anytype variable when you assign a value. For example:

anytype test; //Declare anytype variable
test = 10; //assign a integer value

Variable initialize

After assigned the integer value we can treat anytype variable as integer variable.
Once the data type initialized to the anytype variable, we can’t assign other data type values. For example:

anytype test; //Declare anytype variable 
test = 10; //assign a integer value 
test = 'strValue'; 
info(strFmt('%1', test)); 

The info window will show the message “0”

Avoid "Wrong argument type for function" Error

One more thing, you will get a runtime error message when you use the anytype variable before you assign the value. But, we won’t get any compilation error. For example:

anytype test; //Declare anytype variable 
info(strFmt('%1', test));

Error message:
Error executing code: Wrong argument type for function.

So, before use the anytype variable, we can check the anytype variable is initialized or not. For Example:

anytype test; //Declare anytype variable 
if(!(typeOf(test) == Types::AnyType)) 

    info(strFmt('%1', test)); 
}

If we want to know the which datatype was set in the anytype variable, we can use the typeOf() method.

Using Anytype in Map class

We can use Anytype in the map class. For example:

Map TestMap = new Map(Types::Int64, Types::String); 
TestMap.insert(1, 'Test'); 
TestMap.insert(2, 1); 
TestMap.insert(3, 3.5); 
info(strFmt('%1', TestMap.lookup(3)));