X++ Reflection: Tables and Fields

Reflection is used to dynamically retrieve metadata information from code artifacts dynamically at runtime. In older versions of Dynamics AX this was done using TreeNode framework which reflected the AOT structure. In Dynamics 365 Finance and Supply Chain Management you can use the MetadataSupport class.

Example: Table and its Fields

Create a temporary table that has a name field. The table will be dynamically populated with table names or field names. On the temporary table add 2 static methods to populate a table buffer with table names or field names.

public static TmpTableName populateTableName()
{
    TmpTableName _tmpTableName;
    var tables = Microsoft.Dynamics.Ax.Xpp.MetadataSupport::TableNames();
    while (tables.MoveNext())
    {
        _tmpTableName.clear();
        _tmpTableName.Name = tables.Current;
        _tmpTableName.insert();
    }
    return _tmpTableName;
}

public static TmpTableName populateFieldName(TableId _tableId)
{
     SysDictTable table = new SysDictTable(_tableId);
     Set fields = table.fields();
     SetEnumerator enum = fields.getEnumerator();
     TmpTableName _tmpTableName;

     while(enum.moveNext())
     {
         SysDictField field = enum.current();

         _tmpTableName.clear();
         _tmpTableName.Name = field.name();
         _tmpTableName.insert();
     }

     return _tmpTableName;
 }

Create a regular table that has 2 name fields, one for a table name and another for the field name. Overwrite the lookup method and provide the temporary table buffer as datasource.

public void lookupTableName(FormStringControl _control)
{
    SysTableLookup    lookup;
    QueryBuildDataSource qbds;
    Query q = new Query();
    qbds = q.addDataSource(tableNum(TmpTableName));
    qbds.addSortField(fieldNum(TmpTableName, Name), SortOrder::Ascending);
    lookup = SysTableLookup::newParameters(tableNum(TmpTableName),
          _control,
          true);
    lookup.addLookupField(fieldnum(TmpTableName, Name), true);
    lookup.parmQuery(q);
    lookup.parmTmpBuffer(TmpTableName::populateTableName());
    lookup.performFormLookup();
}

public void lookupFieldName(FormStringControl _control, TableId _tableId)
{
    SysTableLookup    lookup;
    QueryBuildDataSource qbds;
    Query q = new Query();
    qbds = q.addDataSource(tableNum(TmpTableName));
    qbds.addSortField(fieldNum(TmpTableName, Name), SortOrder::Ascending);
    lookup = SysTableLookup::newParameters(tableNum(TmpTableName),
          _control,
          true);
    lookup.addLookupField(fieldnum(TmpTableName, Name), true);
    lookup.parmQuery(q);
    lookup.parmTmpBuffer(TmpTableName::populateFieldName(_tableId));
    lookup.performFormLookup();                
}