0

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 switch statements, include a default: branch to handle new values gracefully.
  • Prefer enum literals like WHSWorkStatus::Open for comparisons. Reach for enum2Label() when showing users a value, and enum2Str() for logs/config that refer to the element name.
  • Be mindful that index2Name()/index2Label() traverse by index, which is metadata order; use index2Value() 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

Call Now800-453-5961