Here’s a friendly, hands-on tour of getting and using enum values in X++—framed around an electronics retail warehousing scenario (think: validating WHS work, showing readable statuses on forms, and parsing config). Enums in D365FO are strongly typed sets of named constants (e.g., WHSWorkStatus::Open, NoYes::Yes). For beginners, the key is to compare against the enum literals (not magic numbers) and convert to/from text only when you need UI strings, logs, or configuration.
When you need a human-readable string, use:
enum2Str()→ the element name (technical name like"Open").enum2Label()→ the localized label (what users see).enum2int()→ the underlying integer (useful for storage or integrations).
// Check and display WHS work status for a TV restock
WHSWorkTable work = WHSWorkTable::find("WORK-00999");
if (work.Status == WHSWorkStatus::InProgress && work.SystemDirected == NoYes::Yes)
{
info(strFmt("Auto-close candidate %1: %2 / %3",
work.WorkId,
enum2Str(work.Status), // "InProgress"
enum2Label(work.Status) // localized, e.g., "In progress"
));
}
For intermediate scenarios—like building dropdowns, validating input, or exploring all elements—use SysDictEnum (the runtime metadata for an enum). Important: index2Name() returns the element name by index, and index2Value() returns the underlying integer value associated with that element. The index is just a 0..N position in metadata; the value is the enum’s stored integer.
// List all values of WHSWorkStatus (value, name, label) for a dialog or log
SysDictEnum sde = new SysDictEnum(enumNum(WHSWorkStatus));
for (int i = 0; i < sde.values(); i++)
{
int value = sde.index2Value(i); // underlying int (e.g., 0,1,2…)
str name = sde.index2Name(i); // element name (e.g., "Open")
str labelTxt = sde.index2Label(i); // localized label (e.g., "Open")
info(strFmt("%1 (%2) → %3", name, value, labelTxt));
}
Sometimes you receive configuration text (like "Closed" from a parameter table) and need to convert it back to the enum. Use str2Enum(enumId, name)—note it expects the element name (not the label). If you only have a stored int, use any2Enum(enumId, intValue).
// From config name → enum
str cfg = "Closed";
WHSWorkStatus parsed = str2Enum(enumNum(WHSWorkStatus), cfg);
if (parsed == WHSWorkStatus::Closed)
{
info("Parsed work status is Closed.");
}
// From stored int → enum
int stored = 2;
WHSWorkStatus fromInt = any2Enum(enumNum(WHSWorkStatus), stored);
To display friendly values on forms and reports, a display method is perfect. A display method is a calculated field exposed to the UI. For table-backed display methods, the classic pattern is the display keyword and (optionally) the SysClientCacheDataMethod attribute to cache values on the client. Here, we’ll return the localized label for the status:
// In WHSWorkTable (or a view/extension as appropriate)
[SysClientCacheDataMethod(true)]
public display str WorkStatusLabel()
{
return enum2Label(this.Status); // localized text for the current record
}
A couple of guardrails as you grow:
- Many D365FO enums are extensible. In
switchstatements, include adefault:branch to handle new values gracefully. - Prefer enum literals like
WHSWorkStatus::Openfor comparisons. Reach forenum2Label()when showing users a value, andenum2Str()for logs/config that refer to the element name. - Be mindful that
index2Name()/index2Label()traverse by index, which is metadata order; useindex2Value()when you truly need the stored integer.
With these patterns, you can confidently read, display, and round-trip enum values across warehousing flows—whether you’re auto-closing system-directed put work for TVs, populating dialog picklists for status filters, or parsing admin-provided settings.
Have a Question ?
Fill out this short form, one of our Experts will contact you soon.
Talk to an Expert Today
Call Now