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

Acumatica Production Order Alloction 封装页多行报错及功能重写求助

生产订单Allocation分配功能复用问题解决方案

问题根因验证

你推测的LSProdMatlLine绑定事件未触发属于高频触发场景,除此之外还有两类常见原因也会导致新增第二行时报对象引用错误:

  • 标准Allocation弹窗的ProdMatlLine数据源默认绑定了行级initValue、modifiedField、validateWrite事件,自定义页面调用时如果没有将弹窗数据源和自定义页面的LSProdMatlLine数据源做事件透传,新增第二行时系统会尝试读取前一行的上下文缓存,找不到对应记录就抛出空引用
  • 标准功能默认依赖生产订单列表页的上下文状态变量,自定义页面没有初始化ProdTable相关的全局状态参数,新增多行时状态校验逻辑读取不到上下文就报错
  • 新增行时inventTrans关联逻辑没有触发,第二行尝试关联库存事务时找不到前一行的事务关联标识

Allocation功能标准使用规则

标准生产订单Allocation功能的默认调用逻辑约束:

  1. 必须在包含ProdTable完整数据源的页面上下文中调用,调用前需要先将当前选中的生产订单记录绑定到全局参数ProdTable_Status
  2. 分配弹窗的ProdMatlLine数据源必须和调用页面的物料行数据源做视图关联,事件要做透传绑定
  3. 每次新增分配行后会自动触发库存预留校验,必须保证预留维度参数在调用页面已经完成初始化

功能重写复用指导

第一步:添加事件透传绑定

在自定义页面调用Allocation弹窗的逻辑里,补充数据源事件绑定代码:

// 自定义页面调用Allocation弹窗前绑定行事件
Args args = new Args();
FormRun allocationDialog;
args.record(prodTable);
args.name(formStr(ProdProductionOrderAllocation));
allocationDialog = ClassFactory.formRunClass(args);
allocationDialog.init();
// 绑定ProdMatlLine的行事件到自定义页面的LSProdMatlLine数据源
allocationDialog.dataSource(formDataSourceStr(ProdProductionOrderAllocation, ProdMatlLine)).addDynalink(fieldNum(ProdMatlLine, ProdId), LSProdMatlLine, fieldNum(LSProdMatlLine, ProdId));
// 透传initValue事件
allocationDialog.dataSource(formDataSourceStr(ProdProductionOrderAllocation, ProdMatlLine)).initValueDelegate += eventhandler(this, methodStr(MyCustomProdPage, prodMatlLine_InitValue));
allocationDialog.run();
allocationDialog.wait();

第二步:新增行上下文缓存处理

扩展Allocation弹窗逻辑,新增上下文缓存避免第二行读取空值:

[ExtensionOf(formStr(ProdProductionOrderAllocation))]
public final class ProdProductionOrderAllocation_Extension
{
    // 新增全局缓存变量存储已添加的行上下文
    Map prodMatlLineCache = new Map(Types::Int64, Types::Record);
    
    public void init()
    {
        next init();
        // 初始化时读取自定义页面传入的LSProdMatlLine上下文存入缓存
        if(element.args().caller() is MyCustomProdPage)
        {
            MyCustomProdPage callerPage = element.args().caller();
            LSProdMatlLine line = callerPage.LSProdMatlLine;
            prodMatlLineCache.insert(line.RecId, line);
        }
    }

    public void prodMatlLine_InitValue(ProdMatlLine _prodMatlLine)
    {
        // 新增行时从缓存读取上下文赋值,避免空引用
        if(prodMatlLineCache.elements() > 0)
        {
            var enumerator = prodMatlLineCache.getEnumerator();
            if(enumerator.moveNext())
            {
                LSProdMatlLine cachedLine = enumerator.currentValue();
                _prodMatlLine.ProdId = cachedLine.ProdId;
                _prodMatlLine.InventDimId = cachedLine.InventDimId;
            }
        }
        next prodMatlLine_InitValue(_prodMatlLine);
    }
}

第三步:多行新增校验优化

禁用标准功能的单行强制校验逻辑,添加多行批量校验:

// 扩展ProdMatlLine数据源的validateWrite方法
[ExtensionOf(formDataSourceStr(ProdProductionOrderAllocation, ProdMatlLine))]
public final class ProdMatlLine_Extension
{
    public boolean validateWrite()
    {
        boolean ret;
        // 自定义页面调用时跳过单行上下文校验,新增所有行后统一校验
        if(element.args().caller() is MyCustomProdPage)
        {
            ret = true;
        }
        else
        {
            ret = next validateWrite();
        }
        return ret;
    }
}

// 扩展弹窗ok方法添加批量校验
[ExtensionOf(formStr(ProdProductionOrderAllocation))]
public final class ProdProductionOrderAllocation_Ok_Extension
{
    public void ok()
    {
        ProdMatlLine line;
        Str curAllocationId = element.allocationId();
        if(element.args().caller() is MyCustomProdPage)
        {
            while select forUpdate line where line.AllocationId == curAllocationId
            {
                if(!line.validateWrite())
                {
                    warning(strFmt("第%1行分配数据校验失败", line.LineNum));
                    return;
                }
            }
        }
        next ok();
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 18:39:02