Microsoft_MVP_banner

Collection classes in AX – What, When and How to use

Data inserting, traversing and retrieving can be done with
many different ways in AX. We do have different collection classes for it and
each one has its own importance and performance impact. Let’s talk about each
one by one and compare it.

  •          
    are structures, contain values of any
    X++ type that are accessed sequentially
  •          
    all values must be of same X++ type (specified
    through baseEnum types)
  •          
    type is defined on creation and cannot be
    modified after initialization
  •          
    can be traversed through ListEnumerator class
  •          
    values can be added from both sides e.g. using addEnd()
    and addStart() methods
     



Example 1

static void
ListExample1(Args _args)
{
    List list
= new List(Types::String);    // Declare and
initialize List of String type
   
ListEnumerator  enumerator;             //
Declare ListEnumerator class to traverse list
       
   
list.addEnd(“Faisal”);                  //
Add values at End of the List
   
list.addEnd(“Fareed”);                  //
Add values at End of the List
   
list.addStart(“AX Developer”);          // Add
values at Start of the List
   
   
enumerator = list.getEnumerator();     
// initialize listEnumerator class object
   
    while (enumerator.moveNext())
    {
        print enumerator.current();
    }
    pause;   
} 

 Output:
Traverse from left to right

Example 2



Lists can be initialized from container too.
static void
ListExample2(Args _args)
{
    Container       companyRange;               //
Declare container
    List            list;                       // Declare List
   
ListEnumerator  enumerator;                 //
Declare ListEnumerator class to traverse list       
   
   
companyRange = [curext()];                  //
initialize container with current company
       // we can pass
multiple values here but need to be of same  
          datatype as this
is used in List in below code
       
    list =
con2List(companyRange);
   
   
enumerator = list.getEnumerator();          //
initialize listEnumerator class object
   
    while (enumerator.moveNext())
    {
        print enumerator.current();
    }
    pause;   
}
Example 3

Below code is actually an example to copy user roles from
one user to another. Where I used ‘List’ to store records what roles have been
moved across.
static void
ListExample3(Args _args)
{
    boolean                 ret = true;
   
SecurityRole           
securityRole;
   
SecurityUserRole       
securityUserRole;
   
SecurityUserRole       
securityUserRoleExist;
   
SecurityUserRole       
securityUserRoleInsert;
   
OMUserRoleOrganization  userRoleOrganization,
userRoleOrganization_Insert;
    List                    copiedUserRoles = new List(Types::String);
    ListEnumerator          lEnumerator;   
    try
    {       
        while select
securityUserRole
               
where securityUserRole.User
== fromUser
            notExists join
* from securityUserRoleExist
               
where
securityUserRoleExist.SecurityRole    ==
securityUserRole.SecurityRole
                   
&& securityUserRoleExist.User           == toUser
        {
            select securityRole where securityRole.RecId ==
securityUserRole.SecurityRole;
            copiedUserRoles.addStart(securityRole.Name);
           
securityUserRoleInsert.initValue();
           
securityUserRoleInsert.SecurityRole = securityUserRole.SecurityRole;
           
securityUserRoleInsert.User        
= toUser;
           
securityUserRoleInsert.insert();
           
securityUserRoleInsert.clear();
            while select
userRoleOrganization
                   
where userRoleOrganization.User
== fromUser
                        &&
userRoleOrganization.SecurityRole == securityUserRole.SecurityRole
            {
               
userRoleOrganization_Insert.initValue();
               
userRoleOrganization_Insert.OMHierarchyType             = userRoleOrganization.OMHierarchyType;
               
userRoleOrganization_Insert.OMInternalOrganization      =
userRoleOrganization.OMInternalOrganization;
               
userRoleOrganization_Insert.SecurityRole                = userRoleOrganization.SecurityRole;
               
userRoleOrganization_Insert.SecurityRoleAssignmentRule  =
userRoleOrganization.SecurityRoleAssignmentRule;
               
userRoleOrganization_Insert.User                        = toUser;
               
userRoleOrganization_Insert.insert();
               
userRoleOrganization_Insert.clear();
            }
        }
    }
    catch
    {
        ret =
false;
    }
    if (ret)
    {
        lEnumerator =
copiedUserRoles.getEnumerator();
        if
(copiedUserRoles.empty())
            info(strFmt(“User %1 and %2 already have the same user
role”
,fromUser, toUser));
        while
(lEnumerator.moveNext())
        {
            info(strFmt(‘%1’,lEnumerator.current()));
        }
    }
    else
        error(strFmt(“Aborted please review error list above”));
}
You can also have a
look on this post
to find difference between Iterators and Enumerators.                     
  •          
    can be used as a temp data store for the given
    scope of a process
  •          
    are much quicker than temp tables
  •          
    allows you to associate one value (the key) with
    another value
  •          
    values can be any valid X++ type

static void
mapExample1(Args _args)
{
    Map             mapExample;
   
MapEnumerator  
mapEnumeratorExample;
   
CustTable       custTable;
   
   
mapExample = new
Map(Types::String,Types::String);
   
    select custTable where
custTable.AccountNum == “144212”;
   
   
mapExample.insert(CustTable.AccountNum, CustTable.name());
   
   
mapEnumeratorExample = new
MapEnumerator(mapExample);
   
    while (mapEnumeratorExample.moveNext())
    {
        if (!mapExample.empty())
       
{           
            print
mapExample.lookup(custTable.AccountNum);
       
}       
    }
    pause;
}
Good information about Maps is
also shared here

Containers can be
used to get multiple values returned from any method.

Original method
private container
getActualAmount()
{
    Container  
amountContainer;
    container  
textContainer;   
    ;
    for()
    {       
       
amountContainer = conIns(amountContainer);
       
textContainer   = conIns(textContainer);       
    }
    return [amountContainer, textContainer];
}
Called From
container  
AmountsC = conNull();
container  
TextC    = conNull();
[AmountsC, TextC]  
= this.getActualAmount();
Set values to use for
your logic
ExampleTable.Field1 = conPeek(AmountsC,1);

ExampleTable.Field2 = conPeek(AmountsC,2);

Important points about Containers

  • They are value based structure. So no class based object stored on it.
  • They are similar to linked list or array like structured.
  • Their size fixed at time of declaration. When you insert update or delete any value from container, a new container is created.
  • They always copied by value.
  • Containers are base 1 not like array based zero.



Share:

Related Posts

Microsoft Copilot
admin

Exploring Microsoft Copilot Architecture

Microsoft Copilot isn’t just another AI tool; it’s a comprehensive platform designed to be your indispensable companion, enhancing productivity, fostering creativity, and facilitating information comprehension all through a user-friendly chat interface. The concept of Copilot emerged two years ago when Microsoft introduced GitHub Copilot, aiming to assist developers in writing

Read More »
How to enable new Microsoft teams - Public Preview!
Microsoft Teams
Faisal Fareed

How to enable new Microsoft teams – Public Preview!

New Microsoft Teams is just AWESOME, quick but useful post below shows how you have this preview feature to make your life EASY!  Open Microsoft Teams admin center [Ask admin in your organization if you don’t have access] and follow path Teams > Teams update policies > Click on an existing

Read More »

Send Us A Message

Leave a Reply

Your email address will not be published. Required fields are marked *

Recent Post

Exploring Microsoft Copilot Architecture

Exploring Microsoft Copilot Architecture

Microsoft Copilot isn’t just another AI tool; it’s a comprehensive platform designed to be your indispensable companion, enhancing productivity, fostering creativity, and facilitating information comprehension all through a user-friendly chat interface. The concept of Copilot emerged two years ago when Microsoft introduced GitHub Copilot, aiming to assist developers in writing…

How to enable new Microsoft teams – Public Preview!

How to enable new Microsoft teams – Public Preview!

New Microsoft Teams is just AWESOME, quick but useful post below shows how you have this preview feature to make your life EASY!  Open Microsoft Teams admin center [Ask admin in your organization if you don’t have access] and follow path Teams > Teams update policies > Click on an existing…

Electronic Reporting: Send vendor payments to external azure storage via X++

Electronic Reporting: Send vendor payments to external azure storage via X++

Electronic Reporting module in Microsoft Dynamics 365 Finance Operation lets you archive file generated by ER at SharePoint location and in Azure Storage as per this link Archive ER destination type – Finance & Operations | Dynamics 365 | Microsoft Learn. APIs can be used to check message status and read…

FaisalFareed@2025. All rights reserved

Design by T3chDesigns