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!