Lists in Dynamics 365 for Operation

There are 4 different data structures/collection classes/ that can be used when developing in D365.

  • Lists
  • Maps
  • Sets
  • Arrays
  • Structs

Most of these can be familiar from other languages. I will highlight the main points for these data structures, as well as provide examples of their usage. These data structures can be used to store any data types including objects.

List

List sequentially holds elements assigned to it. All values in the list must be of the same type.

Initiate

To initiate the list you have to write following piece of code where instead of Types::Integer, you can use any type including objects.

List             list  = new List(Types::Integer);

Add values

To add values to already initialized list you can use one of the following functions.

list.addEnd(25);
list.addStart(3);

Function addEnd ends a value in the end of the list. Alternatively, function addStart inserts new value in the beginning of the list.

Read values

To output all values from the list you can use following function.

list.toString();

if you want to get a specific value from the list, then you will have to use following code.

ListIterator     iterator;
enumerator = list.getEnumerator();
enumerator.reset();
enumerator.moveNext()
int i = enumerator.current();

ListEnumerator is the class that helps to iterate through list, by accessing each element of the list individually. To get a value of the list we are using function current()

Example

    public static void main(Args _args)
    {    

        List                list  = new List(Types::Integer);
        ListEnumerator      enumerator;

        list.addEnd(1);
        list.addEnd(21);
        list.addEnd(22);
        list.addEnd(23);
        list.addEnd(24);
        list.addEnd(25);
        list.addStart(3);

        info( list.toString());

        enumerator = list.getEnumerator();
        enumerator.reset();
        while(enumerator.moveNext())
        {
            info(int2str(enumerator.current()));
        }     
    }

 

Line by line with visual explanation:

This line of code executes the initialization of the list.

List                list  = new List(Types::Integer);

14

description of the variable fro listEnumerator, that will help to get values from the list

ListEnumerator      enumerator;

15

Adding the first element with value 1 to the list from the end

list.addEnd(1);

3

Adding the second element with value 21 to the list from the end

list.addEnd(21);

4

Adding the third element with value 22 to the list from the end

list.addEnd(22);

5

Adding the fourth element with value 23 to the list from the end

list.addEnd(23);

6

Adding the fifth element with value 24 to the list from the end

list.addEnd(24);

7

Adding the sixth element with value 25 to the list from the end

list.addEnd(25);

8

Adding the seventh element with value 3 to the list from the beginning. If we were to start reading our list, the first element we will get will be the element with value 3

list.addStart(3);

9

Initialization of the enumerator. Now enumerator is attached to the list. On the image below you may notice that enumerator looks like an arrow, and this arrow doesn’t point at any particular element.

enumerator = list.getEnumerator();

10

Because of that we have to reset the enumerators value to make sure that we will be pointing at the beginning of our list. After we use the function reset, the list enumerator “points” at the beginning of the list, not at the first element!

enumerator.reset();

11

To move enumerator to the first element, you have to executed move next method. After that you can work with list elements. You can get the value of the list by using method current();

enumerator.moveNext())

12

to move to the next element you can use the same operation. Notice you cannot move back, only move forward. If you need to start over,  you can use reset();

 

enumerator.moveNext())

13

 

You can notice that there is no description of how to remove the value from the list. To do that you can use class listIterator method delete. As you may suggest , you have to be careful when using it, if you insert/ delete something from the list using iterator, when you have initialized enumerator, you will not be able to use enumerator without invoking error.

Advertisements

Jobs or Hello World in Dynamics 365 for Operations

There are no more jobs in D365 for Operations. Instead now you can use a runnable class.

Create project. Right click on the project/ add item/ dynamics 365 Items/code/ Runnable class (Job)

1

Enter the name,

Add some code to the method main.2

Right click on the new class select “Set as a startup object”

And press run

Delete connection between not existing worker and existing user

Which stops you from assigning worker to the user ( this happens usually after migrations of data or something similar)

 

static void DelConBetweenNotExistWorkerandUser(Args _args)
{
    DirPersonUser         dirPersonUser;
    UserInfo                   userInfo;
    int                             counter;
    while select forUpdate dirPersonUser notExists join UserInfo
        where DirPersonUser.User == userinfo.id
    {
        info ( DirPerson::find(dirPersonUser.PersonParty).Name);
        dirPersonUser.delete();
    }
    info(int2str(counter));

}

How to check weather all customers have nameAlias defined

I think one of the easier methods would be to run  this job, which will show number of all customers, and customer with Name Alias defined.

static void AmountOfCustomersWithNAmeAlias(Args _args)
{
    CustTable custtable;
    int counter1, counter2;

    while select CustTable
    {
        counter1++;
        if (CustTable.nameAlias())
        {
            counter2++;
        }
    }
   info (strFmt(“Counter1 %1, counter2 %2”,counter1, counter2));
}

open task manager from cmd

sometimes when you use the Azure connection to AX, but you have no connection to the environment where AX is run, you can face situations when you have to terminate some kind of process.

For example you accidentally tried to copy all records of the really big table, and everything is hanging, and you can’t continue working because nothing is responsive.

If you have a connection to the cmd on the same environment you cans invoke task manager by entering taskmgr. and then you can terminate everything that you want 🙂

How to know if user has a worker assigned to it

If your user has a worker then you will have connected records in following two table DirPersonUser  and hcmWorker.

In dirPersonUser table you can have a look at the user id, and using PersonParty field, try to find related record in the hcmWorker table,( field Person)

 

Or you can use the easy way ( by using hcmWorker.serid to worker method 🙂

Check with Regexp if company name follows certain pattern

In my case I was looking for 2 U letters anywhere in the name or the short name of the company.

static void Job107(Args _args)
{
    TextBuffer companyShort = new TextBuffer();
    TextBuffer companyName = new TextBuffer();

    companyShort.setText(curext());
    companyShort.regularExpressions(true);
    companyName.setText(CompanyInfo::find().Name);
    companyName.regularExpressions(true);
    if (companyName.find(‘u.*u’) ||companyShort.find(‘u.*u’))
    {
        info(‘^.^’);
    }
}

Nice links to check regexp stuff : http://www.zytrax.com/tech/web/regex.htm 

And online editor to check if you were right: https://regex101.com/

unable to connect to the microsoft visual studio remote debugging monitor

When debugging on server do not forget to check if the Visual Studio Remote Debugging Monitor   was run.

If not find it here:

Program Files\Microsoft Visual Studio 1x.0\Common7\IDE\Remote Debugger\x86\msvsmon.exe

Program Files\Microsoft Visual Studio 1x.0\Common7\IDE\Remote Debugger\x64\msvsmon.exe

and run it as administrator

Happy debugging