Enums and localization… in X++

On Msdn enumerators (Enums) are described as:

X++ does not support constants but has an enumerable type (Enum), which is a list of literals. You need to create an Enum in the Application Object Tree (AOT) before you can use it.

Enum values are represented internally as integers. The first literal has number 0, the next has number 1, the next has number 2, and so on. You can use enums as integers in expressions.

This definition is not the whole truth and I will show you why.

I’m going to use the Enum SMATransactionType and I’d like to transform a string value (for example “Hour”) into an Enum of this type. For that I’m using the following code:

    1:  SMATransactionType  transactionType;
    2:  ;
    3:   
    4:  transactionType = str2enum(transactionType, "Hour"); 
    5:  info(enum2str(transactionType));

The online help (F1) will give you the following help for the function str2enum:

Converts a text string into an enumerated text of the type specified by _type.

and if your Dynamics Ax is configured in English, this code will work fine. But unfortunately this will not work for other languages (as for example German). On Msdn you’ll find a slightly different explanation:

Converts a localized text string into one of the values of the specified enum type.

The difference is the "localized”, and in fact if your Dynamics Ax configuration is German, the following code will work for you:

    1:  SMATransactionType  transactionType;
    2:  ;
    3:   
    4:  transactionType = str2enum(transactionType, "Stunde");
    5:  info(enum2str(transactionType));

Unfortunately X++ offers you only a function that transforms a string into an Enum which is based on the localized value (here it is “Stunde”) and not on the symbol (which is in this case “Hour”).

In order to have an generalized way of transforming a string value (corresponding to a symbol) to en Enum, we need another approach.

In the following code I do first get the name for the enum SMATransactionType::Hour (line 12) which will be in a German configured client "Stunde" and not "Hour", since "Hour" is the symbol and "Stunde" is the name. In line 14 I'm trying to transform "Hour" into an Enum, but this line would only work if the client is configured in English. Since this isn't the case, this operation will fail. I'm a little bit surprised that this operation does not throw an exception (since "Hour" isn't a name that is part of the Enum SMATransactionType) but it's just that the variable transactionType will not be initialized, so line 16 will display an empty string.

    1:  SMATransactionType  transactionType;
    2:  str transactionTypeValue;
    3:  DictEnum dict;
    4:   
    5:  str valueText;
    6:  str nameText;
    7:   
    8:  int value;
    9:  int indexValue;
   10:  ;
   11:   
   12:  valueText = enum2str(SMATransactionType::Hour); //the value will be "Stunde"
   13:   
   14:  transactionType = str2enum(transactionType, "Hour"); //Will only work in english
   15:   
   16:  info(enum2str(transactionType));
   17:   
   18:  dict = new DictEnum(enumNum(SMATransactionType));
   19:  value = dict.symbol2Value("Hour"); //Gets the value in int
   20:  nameText = dict.value2Name(value); //Gets the localized Name (for example "Stunde" in german)
   21:   
   22:  transactionType = str2enum(transactionType, nameText); //now it transforms the string to the enumerator
   23:   
   24:  info(enum2str(transactionType));

With the DictEnum-class I'm getting the value of the symbol with the method symbol2Value (in line 19) and in line 20 I'm transforming with value2Name this value to the localized name. Now we are able to use the str2enum function to transform the translated symbol into the Enum (line 22).

Whenever you are transforming a string to an Enum, please check that the string you are going to transform is already localized. So don’t use the Enums in X++ like simple constants (as the text on Msdn lead you to think) and be aware that they might be localized!