Friday, 17 June 2016

Manipulating Nested Containers

Hi there,

I am sure all the X++ developers at some point might have come across with a situation to use Container type data, and so do I.  At times, a container type field is required for the table, or required for handling the business logic, etc.  The functions around Containers are also very minimal and easy to use.  Here, I am going to discuss about the Nested containers where the situation demands you to store containers within a container.

For example,
    Simple container:     container c = ["blue", "yellow", "red"];
    Mixed container:      container mixed = ["blue", 10.00, 125, true];
    Nested container:     container nested = [c, mixed];

Say, we have a nested container now and we want to retrieve the values from it.  You may want to write something like below:

int i;
container temp;
;
for (i = 1; i <= conlen(nested); i++)
{
    temp = conpeek(nested, i);
    print con2str(temp);  // you can always loop thru it and retrieve each element
}

Adding values to the container is not always straight forward.  For example, you may not simply assign values to the container like c = ["blue", "yellow", "red"];  instead, you might want to fetch the color information from a different source (may be from a table), and add the elements to the container on the go like below:
        while select Color
         {
                c += Color.Name;
                         OR
                 c = conIns(c, i, Color.Name); 
//initialize i to 1 and increment within the loop for the next position.
          }

Have you ever tried to figure out what is the difference between these two approaches.  When can we use "+=" and when can we use "conIns()".
Generally, X++ developers use "+=" approach, because it is easy to write, no need to manage a counter to identify the position, etc.

What if I tell you "+=" approach won't work in certain situation whereas "conIns()" would.  Yes.  Look at the below code:

What do you think the output of the below program would be:

static void ContainerDemo(Args _args)
{
    container baseContainer;
    container childContainer;    
    int i;
    ;
    
    childContainer = ["Vendor Account", "Customer Account"];
    baseContainer += childContainer;    
    
    childContainer = ["V0001", "C0001"];
    baseContainer += childContainer;            
    
    for (i = 1; i <= conLen(baseContainer); i++)
    {
        childContainer = conPeek(baseContainer, i);
        print con2Str(childContainer);
    }
    
    pause;
    
}

It would print,
Vendor Account,Customer Account
V0001,C0001

WRONG!!!  The above program in AX 2012 R2 would throw a run-time error as below on the line: childContainer = conPeek(baseContainer, i);

Error executing code: Wrong argument types in variable assignment.

What's wrong with that line?  Frankly, it is correct and this is the typical way to retrieve values from the container.  But why this error?

Because the values stored inside the "baseContainer" is also a container or set of containers.  This kind of situation demands the usage of "conIns()". Yes, we need to use "conIns()", and here is the modified code:

static void ContainerDemo(Args _args)
{
    container baseContainer;
    container childContainer;    
    int i;
    ;
    
    childContainer = ["Vendor Account", "Customer Account"];
    baseContainer = conins(baseContainer, 1, childContainer);    
    
    childContainer = ["V0001", "C0001"];
     baseContainer = conins(baseContainer, 2, childContainer);          
    
    for (i = 1; i <= conLen(baseContainer); i++)
    {
        childContainer = conPeek(baseContainer, i);
        print con2Str(childContainer);
    }
    
    pause;
    
}

Here is the output,
Vendor Account,Customer Account
V0001,C0001

This the minor thing but very useful to know.

Cheers,
Abdul


No comments:

Post a Comment