You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

D365 FO中查找字段选值后显示关联名称且不存至数据库的方案

实现D365 FO查找控件显示关联名称但存储ID的方案

核心思路

通过自定义查找逻辑+控件显示文本重写,让单个查找控件在选中ID后自动显示关联表的名称,同时数据库仅存储原始ID,无需额外添加显示字段。该方案可通过通用化处理适配多关联表场景。

方案一:重写查找控件的Lookup与DisplayText方法(代码实现)

1. 重写查找控件的Lookup方法

在表单中reportToPosition控件的Lookup事件中,构建包含ID和名称的查找窗口,让用户直观选择:

public void lookup()
{
    SysTableLookup      sysTableLookup;
    Query               query;
    QueryBuildDataSource qbds;

    // 初始化查找对象,绑定主表字段
    sysTableLookup = SysTableLookup::newParameters(tableNum(MainTable), this);
    // 设置返回值为ID字段,同时显示名称字段
    sysTableLookup.addLookupField(fieldNum(RoleTable, RoleCode), true);
    sysTableLookup.addLookupField(fieldNum(RoleTable, Title));

    // 构建关联表查询
    query = new Query();
    qbds = query.addDataSource(tableNum(RoleTable));
    // 可按需添加过滤条件,比如只显示有效角色
    // qbds.addRange(fieldNum(RoleTable, Active)).value(queryValue(true));

    sysTableLookup.parmQuery(query);
    sysTableLookup.performFormLookup();
}

2. 重写控件的DisplayText方法

让控件显示时自动从关联表拉取名称,而非原始ID:

public str displayText()
{
    RoleTable       roleTable;
    MainTable       mainTable;
    str             displayName = '';

    mainTable = this.dataSource().cursor();
    if (mainTable.reportToPosition != '')
    {
        select firstonly Title from roleTable
            where roleTable.RoleCode == mainTable.reportToPosition;
        displayName = roleTable.Title ?: mainTable.reportToPosition;
    }
    else
    {
        displayName = super();
    }

    return displayName;
}

3. 通用化适配多表场景

如果需要适配多个不同关联表,可封装通用工具类复用逻辑:

class CommonLookupHelper
{
    // 通用查找构建方法
    public static void performLookup(FormStringControl _control, TableId _relatedTableId, FieldId _relatedKeyField, FieldId _displayField)
    {
        SysTableLookup      sysTableLookup;
        Query               query;
        QueryBuildDataSource qbds;

        sysTableLookup = SysTableLookup::newParameters(_control.dataSource().table(), _control);
        sysTableLookup.addLookupField(_relatedKeyField, true);
        sysTableLookup.addLookupField(_displayField);

        query = new Query();
        qbds = query.addDataSource(_relatedTableId);

        sysTableLookup.parmQuery(query);
        sysTableLookup.performFormLookup();
    }

    // 通用显示文本获取方法
    public static str getDisplayText(Common _mainRecord, FieldId _mainKeyField, TableId _relatedTableId, FieldId _relatedKeyField, FieldId _displayField)
    {
        Common relatedRecord;
        str mainKeyValue = _mainRecord.(_mainKeyField);
        str displayText = '';

        if (mainKeyValue != '')
        {
            relatedRecord = tableBuffer(_relatedTableId);
            select firstonly (_displayField) from relatedRecord
                where relatedRecord.(_relatedKeyField) == mainKeyValue;
            displayText = relatedRecord.(_displayField) ?: mainKeyValue;
        }

        return displayText;
    }
}

调用示例:

// Lookup方法中
public void lookup()
{
    CommonLookupHelper::performLookup(this, tableNum(RoleTable), fieldNum(RoleTable, RoleCode), fieldNum(RoleTable, Title));
}

// DisplayText方法中
public str displayText()
{
    MainTable mainTable = this.dataSource().cursor();
    return CommonLookupHelper::getDisplayText(mainTable, fieldNum(MainTable, reportToPosition), tableNum(RoleTable), fieldNum(RoleTable, RoleCode), fieldNum(RoleTable, Title));
}

方案二:无代码配置(表单设计器实现)

适用于关联关系简单的场景:

  1. 打开表单设计器,选中reportToPosition控件;
  2. 在属性窗口找到ReplaceField,设置为关联表的显示字段(如RoleTable.Title);
  3. 确保控件的DataSource和DataField绑定主表的reportToPosition字段;
  4. 测试验证:选中ID后控件自动显示关联名称,数据库仍存储原始ID。

注意:复杂过滤或多表关联场景建议用方案一。

验证要点

  • 选中查找值后,控件显示关联名称而非ID;
  • 保存记录后,数据库reportToPosition字段存储原始ID;
  • 编辑已有记录时,控件自动加载对应关联名称;
  • 空值或无匹配关联记录时,控件显示原始ID或空值。

内容的提问来源于stack exchange,提问作者user4833581

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 09:41:16