Hello,
I am new to the issue of pack/unpack (On classes: Dynamics AX 2009).
I would like knowing about this issue, and like some samples, please.
Thanks :)
*This post is locked for comments
Hello,
I am new to the issue of pack/unpack (On classes: Dynamics AX 2009).
I would like knowing about this issue, and like some samples, please.
Thanks :)
*This post is locked for comments
Follow this link you will find in detail
Use the pack-unpack pattern to save and/or store the state of an object, and then later re-instantiate the same object.
if you do not use these methods in class values of the object will not save
Dear Jonathan, thanks a lot for your great explanation,
however, i have another case, and i would like to add it here is case somebody faced it :
i added two parameters (FromDate , ToDate) to a report that already has its own pack method, and the pack method calls another pack method in a class (to keep the inventory dimensions) as follows :
the original pack method code was :
public container pack()
{
return [#CurrentVersion,inventReport_DimParm.pack()];
}
i actually wanted to override the pack and unpack methods to add my two parameters (FromDate and ToDate). thus, i overrided them as follows :
public container pack()
{
return [#CurrentVersion,inventReport_DimParm.pack(), fromdate, todate]; // here i added them
}
///// and in the unpack method i also added my two parameters :
public boolean unpack(container _packedClass)
{
boolean ret;
Integer version = RunBase::getVersion(_packedClass);
container inventReport_DimParmPack;
;
switch (version)
{
case #CurrentVersion:
[version, inventReport_DimParmPack, fromdate, todate] = _packedClass; /// here i added them
if (!inventReport_DimParm)
inventReport_DimParm = new InventReport_DimParm();
inventReport_DimParm.unpack(inventReport_DimParmPack);
ret = true;
break;
default:
ret = false;
}
return ret;
}
If you're making your own, you should use CurrentVersion. ParentVersion is likely a way to support older versions of packed information, or it's doing something fancy. Here's an example of multiple version support in an unpack():
boolean unpack(container _packedClass)
{
int version = RunBase::getVersion(_packedClass); // this is a better way of conpeek(_packedClass, 1)
boolean ret = true;
;
switch (version)
{
case #CurrentVersion:
[version, #CurrentList] = _packedClass;
break;
case 2:
[version, startDate, endDate] = _packedClass;
break;
default:
ret = false;
break;
}
return ret;
}
As you can see, it's just a switch on the version number so old data can be handled at least partially. If you want more clarification on ParentVersion, please provide an unpack example that uses it.
Hope this helps.
There are cases of "ParentVersion" and "CurrentVersion" - When should I use "ParentVersion" and when should I use "CurrentVersion"?
Eitan,
Pack and unpack is Dynamics language for serialization -- putting object-specific data in a writeable format and later reading it back to create an object in the exact same state.
Most of the interactive objects in Dynamics will automatically check for saved user data when invoked and instantiate accordingly. Perhaps you remember running a report and the next time you opened the report your previous query and parameter values were already there. This happens because of pack and unpack.
The majority of what makes pack and unpack confusing is macros, so let's do a simple example not using macros at all. Let's say we have a class that has two date values I need to persist between runs: startDate and endDate.
So when pack() gets called, I need to store both variables. (If you don't understand the way containers work, look them up on MSDN first, otherwise this won't make sense).
container pack()
{
return [startDate, endDate];
}
The framework will take whatever pack returns and store it in user data. So when the object is instantiated, unpack() gets called in order to reinitialize the values.
boolean unpack(container _packedValues)
{
[startDate, endDate] = _packedValues;
return true;
}
Follow what's happening here? We expect _packedValues to contain startDate and endDate in that order, so we assign those values to our class variables.
Now let's imagine we want to add another class variable that needs to be stored: isPosted
To do this, we'll have to modify our pack to return
[startDate, endDate, isPosted]
and our unpack to assign all three:
[startDate, endDate, isPosted] = _packedValues;
Hm, but what about values that were stored before our modification? That container assignment won't work because _packedValues will only contain 2 values (startDate and endDate). So let's make the first value in our packed data identify the version of the packed data so we can handle old values without crashing.
container pack()
{
return [1, startDate, endDate, isPosted];
}
boolean unpack(container _packedValues)
{
boolean ret = true;
int version;
;
if (conpeek(_packedValues) == 1)
{
[version, startDate, endDate, isPosted] = _packedValues;
}
else
{
ret = false;
}
return ret;
}
Ok, so now if I need to add more variables, I need to change the version number in both pack and unpack, but now old data will make unpack() return false, which will initialize the parameter defaults.
So now let's add some macros so we only have to change one spot when we change what we want to pack. In our classDeclaration, we'll create 2 macros: one for the version of the data, and one for the values we wish to store.
classDeclaration()
{
#define.CurrentVersion(1)
#localMacro.CurrentList
startDate,
endDate,
isPosted
#endMacro
}
If you're unfamiliar with 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'. So now we can change our pack() and unpack() to look like this:
container pack()
{
return [#CurrentVersion, #CurrentList];
}
boolean unpack(container _packedValues)
{
int version;
boolean ret = true;
;
if (conpeek(_packedValues) == #CurrentVersion)
{
[version, #CurrentList] = _packedValues;
}
else
{
ret = false;
}
return ret;
}
This is pretty close to what you see in most pack() and unpack() methods. I hope this helped clear things up.
Jonathan
Pack and unpack save settings you need to remember between usage of a class or form in containers. For example of use you can check the Tutorial_Runbase classes.
André Arnaud de Cal... 291,711 Super User 2024 Season 2
Martin Dráb 230,466 Most Valuable Professional
nmaenpaa 101,156