如何在X++中实现多字段OR关联的Dynalink替代逻辑?
问题描述
原本使用以下X++代码,通过addDynalink将FiscalDocument_BR数据源与GeneralJournalEntry的SubledgerVoucher字段进行单字段关联:
[DataSource] class FiscalDocument_BR { public void init() { super(); this.query().dataSourceTable(tableNum(FiscalDocument_BR)).clearDynalinks(); this.query().dataSourceTable(tableNum(FiscalDocument_BR)).addDynalink( fieldNum(FiscalDocument_BR, Voucher), GeneralJournalEntry, fieldNum(GeneralJournalEntry, SubledgerVoucher)); } }
但需要修改为如下SQL的关联逻辑:通过OR条件让GeneralJournalEntry.SubledgerVoucher匹配FiscalDocument_BR的Voucher、InventoryVoucher、CancelVoucherId、CancelInventoryVoucherId四个字段:
SELECT * FROM GeneralJournalEntry INNER JOIN FiscalDocument_BR ON GeneralJournalEntry.SUBLEDGERVOUCHER = FiscalDocument_BR.VOUCHER OR GeneralJournalEntry.SUBLEDGERVOUCHER = FiscalDocument_BR.InventoryVoucher OR GeneralJournalEntry.SUBLEDGERVOUCHER = FiscalDocument_BR.CancelVoucherId OR GeneralJournalEntry.SUBLEDGERVOUCHER = FiscalDocument_BR.CancelInventoryVoucherId WHERE SUBLEDGERVOUCHER IN ('E001-20001314', 'E001-10020552')
尝试多次调用addDynalink(无法实现OR逻辑)、使用range(未成功)都未能解决,请问如何修改X++代码实现该查询逻辑?
解决方案
AX的addDynalink默认是AND逻辑,无法直接构建OR关联条件,要实现你需要的OR多字段匹配,需要通过QueryBuildRange结合表达式语法手动构建关联条件,具体代码如下:
[DataSource] class FiscalDocument_BR { public void init() { QueryBuildDataSource qbdsFiscalDocument; QueryBuildRange qbrLinkCondition; str linkExpr; DictTable dictGJE; DictTable dictFiscalDoc; super(); // 获取FiscalDocument_BR的数据源并清除原有关联 qbdsFiscalDocument = this.query().dataSourceTable(tableNum(FiscalDocument_BR)); qbdsFiscalDocument.clearDynalinks(); // 获取表字典对象,生成字段全限定名避免歧义 dictGJE = new DictTable(tableNum(GeneralJournalEntry)); dictFiscalDoc = new DictTable(tableNum(FiscalDocument_BR)); // 构建OR关联表达式 linkExpr = strFmt('(%1.%2 = %3.%4) OR (%1.%2 = %3.%5) OR (%1.%2 = %3.%6) OR (%1.%2 = %3.%7)', dictGJE.name(), fieldStr(GeneralJournalEntry, SubledgerVoucher), dictFiscalDoc.name(), fieldStr(FiscalDocument_BR, Voucher), fieldStr(FiscalDocument_BR, InventoryVoucher), fieldStr(FiscalDocument_BR, CancelVoucherId), fieldStr(FiscalDocument_BR, CancelInventoryVoucherId)); // 利用RecId字段添加范围,将表达式作为关联条件 qbrLinkCondition = qbdsFiscalDocument.addRange(fieldNum(FiscalDocument_BR, RecId)); qbrLinkCondition.value(linkExpr); qbrLinkCondition.status(RangeStatus::Open); qbrLinkCondition.enabled(true); } }
关键说明
- 表达式构建:通过
strFmt拼接OR条件的完整表达式,使用表的全限定名(字典对象获取)避免字段歧义。 - RecId范围技巧:AX查询框架要求范围必须绑定到表中存在的字段,这里选择
RecId(任意字段均可),通过设置RangeStatus::Open让框架直接将表达式作为查询的一部分,而非自动处理范围逻辑。 - 清除原有关联:必须先调用
clearDynalinks()移除之前的单字段关联,避免逻辑冲突。
如果需要添加WHERE SUBLEDGERVOUCHER IN (...)的过滤条件,可在GeneralJournalEntry数据源上补充范围:
QueryBuildDataSource qbdsGJE = this.query().dataSourceTable(tableNum(GeneralJournalEntry)); QueryBuildRange qbrSubledgerVoucher = qbdsGJE.addRange(fieldNum(GeneralJournalEntry, SubledgerVoucher)); qbrSubledgerVoucher.value(strFmt('("%1", "%2")', 'E001-20001314', 'E001-10020552'));
内容的提问来源于stack exchange,提问作者Emanuel Hiroshi
相关产品推荐
相关产品推荐

