Saturday, March 18, 2017

Pack() and Unpack() methods with RunBaseBatch

The pack() and unpack() methods can be override-ed when you extend your class with RunBaseBatch. The pack() and unpack() in Dynamics AX define serialization

Would be ease to understand with an example - Most of the interactive objects in Dynamics AX automatically store the last saved user parameters/values and when you reopen the object, you could already see the values preloaded from where you left. 
This happens because of the pack() and unpack() methods. 

For example, perhaps you remember running a report with a specific parameters and the next time you open the same report, the parameter values are preloaded as per your first selection. 

Have a look into the AOT\Classes\Tutorial_RunBaseBatch, for an example of RunBaseBatch with pack() and unpack() methods.

The confusing part could be the macros if you are a beginner. So let's go through an example without using any macros and then we can improvise it later to understand better. 

Simple example - without macros:


class AJSimpleRunBase extends RunBaseBatch
{
    date    simStartDate, simEndDate;
}

public container pack()

{
    //values stored needs to be returned to user
    
    //Simple
    return [simStartDate, simEndDate];
{

public boolean unpack(container packedValues)

{
    //Saves the user provided packedValues to the variable defined
    
    //Simple
    [simStartDate, simEndDate] = packedValues;
    return true;
}

Next level - adding additional parameter:

Say you need to add an additional parameter (isPosted) to the class. We can do so by adding a simple declaration in the classDeclaration() method and the pack() method. However, for the unpack() method, the previous stored values will become obsolete. So we need to introduce versioning and ensure that unpack() method understands which version of values it has to update. 

 class AJSimpleRunBase extends RunBaseBatch

{
    date    simStartDate, simEndDate;
    boolean isPosted;
}

public container pack()

{
    //values stored needs to be returned to user
    
    //Next level - versioning as new parameter added

    //return [1, simStartDate, simEndDate, isPosted]; //hardcoded version
}

public boolean unpack(container packedValues)

{
    //Saves the user provided packedValues to the variable defined
    
    //Next level - versioning as new parameter added
    boolean ret = true; 
    int version; 
    ;
    if (conPeek(packedValues,1) ==1) //hardcoded version
    {
        [version, simStartDate, simEndDate, isPosted] = packedValues;
    }
    else
    {
        ret=false;
    }
    return ret;
}


Using Macros - to ensure no-rework for versioning. 
If you want to add one more parameter to the class, you would have to repeat the same steps as shown above and then change the hard coded values. This is where, #macros come to the rescue. With #macros we would have to change only one spot when we change what we want to pack(). 

class AJSimpleRunBase extends RunBaseBatch

{
    date    simStartDate, simEndDate;
    boolean isPosted;
    
    //Macros, what they do is fill in exactly what the macro says at compile time. 
    //So whenever you write #CurrentVersion, the compiler fills in '1'.  
    //Whenever you write #CurrentList, the compiler fills in 'startDate, endDate, isPosted'
    #define.CurrentVersion(1)
    
    #localMacro.CurrentList
    simStartDate, 
    simEndDate, 
    isPosted
    #endMacro
}    

public container pack()

{
    //values stored needs to be returned to user
    
    //With Macros
    return [#CurrentVersion, #CurrentList];

}

public boolean unpack(container packedValues)

{
    //Saves the user provided packedValues to the variable defined
    
    //With Macros
    boolean ret = true;
    int version;
    ;
    if (conPeek(packedValues,1) == #CurrentVersion)
    {
        [version, #CurrentList] = packedValues;
    }
    else
    {
        ret=false;
    }
    return ret;

}

Hope this helps in better understanding of the pack() and unpack() methods and also some insights into #macros. 


Happy coding!

Wednesday, March 8, 2017

How to kill tasks on your machine

Sometimes only way to get out a stuck screen is to kill an on going process, if it has been executing for long, say, for example the "Application object server" is in "Starting" state for a pretty long time and you can not take any action from within the Services window. 

Always good to rely on the Windows Task manager (Right click on taskbar > Task manager) and under Services tab you can find the details of all the services available in the system. You can explore more around Processes and Details tab for further actions. 



And if Task manager is not able to help you in your situation. You can always rely on the good old command taskkill using the pid of the process to identify the correct service/process. 

Open command prompt (Run as Administrator)
taskkill /f /pid 4224


Happy coding!