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

Dynamics AX中筛选指定天数内无全公司交易的供应商问题

问题分析

你的核心需求是:筛选出指定日期后,在所有26家公司中都没有采购订单、发票或付款记录的唯一供应商——也就是说,只要某个供应商在任意一家公司有符合条件的交易,就必须排除。

原代码的问题出在:你试图用vendTable.AccountNum+''来消除dataareaid的关联,但X++的crossCompany查询在生成NOT EXISTS子句时,会自动添加T2.DATAAREAID = T1.DATAAREAID的关联条件。这就导致子查询只检查当前供应商所在公司的交易,而不是所有公司的交易,完全违背了你的需求逻辑。


解决方案思路

我们需要调整查询逻辑,确保子查询跨所有公司检查交易记录,并且不与主表的dataareaid关联。这里提供两种可行的实现方式:

方式一:先收集所有有交易的供应商,再反向筛选

这种方式更直观,性能也更可控:先把所有在指定日期后有交易(采购/发票/付款)的供应商账号收集起来,再从唯一供应商列表中排除这些账号。

X++ 代码示例

Set vendWithTransactions = new Set(Types::String);
cutoffDate = // 你的指定日期;
cutoffDateTrans = // 你的交易日期阈值;

// 1. 收集所有有采购订单的供应商账号
while select crossCompany distinct OrderAccount from purchTable
    where purchTable.createdDateTime > cutoffDate
{
    vendWithTransactions.add(purchTable.OrderAccount);
}

// 2. 收集所有有付款记录的供应商账号
while select crossCompany distinct AccountNum from vendTrans
    where vendTrans.TransDate > cutoffDateTrans
{
    vendWithTransactions.add(vendTrans.AccountNum);
}

// 3. 收集所有有发票记录的供应商账号
while select crossCompany distinct InvoiceAccount from vendInvoiceJour
    where vendInvoiceJour.InvoiceDate > cutoffDateTrans
{
    vendWithTransactions.add(vendInvoiceJour.InvoiceAccount);
}

// 4. 筛选符合条件的唯一供应商
while select crossCompany AccountNum, InvoiceAccount, NBDCMMSAllowInvoices, VendGroup, Party
    from vendTable
    group by AccountNum, InvoiceAccount, Party, VendGroup, NBDCMMSAllowInvoices
    where vendTable.Blocked != CustVendorBlocked::All
        && !vendWithTransactions.in(vendTable.AccountNum)
{
    // 处理结果,比如输出或存入临时表
    info(strFmt('符合条件的供应商:%1', vendTable.AccountNum));
}

优势

  • 逻辑清晰,容易调试
  • 可以单独优化每个收集交易的子查询(比如添加合适的索引)
  • 避免复杂的嵌套NOT EXISTS,减少SQL执行计划的不确定性

方式二:修正原查询,让NOT EXISTS子查询跨所有公司

如果想直接用单条查询实现,需要确保每个NOT EXISTS子查询都使用crossCompany,并且不关联主表的dataareaid。X++中可以通过显式指定子查询的crossCompany来实现:

X++ 代码示例

cutoffDate = // 你的指定日期;
cutoffDateTrans = // 你的交易日期阈值;

while select crossCompany AccountNum, InvoiceAccount, NBDCMMSAllowInvoices, VendGroup, Party
    from vendTable
    group by AccountNum, InvoiceAccount, Party, VendGroup, NBDCMMSAllowInvoices
    where vendTable.Blocked != CustVendorBlocked::All
    // 检查该供应商在所有公司都没有采购订单
    not exists (select firstOnly 1 from purchTable crossCompany
        where purchTable.OrderAccount == vendTable.AccountNum
            && purchTable.createdDateTime > cutoffDate)
    // 检查该供应商在所有公司都没有付款记录
    not exists (select firstOnly 1 from vendTrans crossCompany
        where vendTrans.AccountNum == vendTable.AccountNum
            && vendTrans.TransDate > cutoffDateTrans)
    // 检查该供应商在所有公司都没有发票记录
    not exists (select firstOnly 1 from vendInvoiceJour crossCompany
        where vendInvoiceJour.InvoiceAccount == vendTable.AccountNum
            && vendInvoiceJour.InvoiceDate > cutoffDateTrans)
{
    // 处理结果
    info(strFmt('符合条件的供应商:%1', vendTable.AccountNum));
}

生成的SQL说明

修正后的SQL中,每个NOT EXISTS子查询都会跨所有公司查询,并且不会关联主表的dataareaid,逻辑变为:对于当前供应商账号,不存在任何公司的采购订单/付款/发票记录,完全符合你的需求。


性能优化建议

针对你的数据量(35万条VendTable,1.3万唯一供应商),建议:

  • 确保以下字段有合适的索引:
    • PurchTable.OrderAccount + PurchTable.createdDateTime
    • VendTrans.AccountNum + VendTrans.TransDate
    • VendInvoiceJour.InvoiceAccount + VendInvoiceJour.InvoiceDate
    • VendTable.AccountNum + VendTable.Blocked
  • 如果使用方式一,可以考虑用临时表替代Set,当有大量交易供应商时,临时表的查询性能更稳定
  • 测试时可以先限制日期范围,验证逻辑正确后再全量执行

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:11:20