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

通过BLC代码处理Employee Timecard行插入后保存消失问题

Acumatica EP305000 新增行保存消失问题解决

我在Employee Timecard(EP305000)屏幕详情区域点击“+”按钮时,通过RowInserted事件更新新增网格行的特定字段。目前遇到的问题是:代码执行后UI能看到字段已更新,但点击保存按钮时,该行直接消失,系统仿佛没识别到这行已添加。

手动更新任意字段后,系统就能正常识别并保存该行。想请教两个问题:

  • 是否需要设置脏标记(dirty flag)才能让系统识别该行?
  • 如果纯通过BLC代码添加行,是不是必须做类似设置脏标记的操作,才能确保网格更新且行被系统识别?

原代码

protected void EPTimecardDetail_RowInserted(PXCache sender, PXRowInsertedEventArgs e)
{
    string day = null;
    DateTime? date = null;
    DateTime? startDate = null;
    DateTime? endDate = null;
    int? project = null;
    int? task = null;

    if (isCreateCorrectionFlag == false)
    {
        
        //获取最后一行数据...
        foreach (EPTimecardDetail tca in Base.Activities.Select())
        {
            if (tca.ProjectID == null) break;  //确保变量取到的是最后一行有效数据,而非刚插入的空行
            day = tca.Day;
            date = tca.Date;
            project = tca.ProjectID;
            task = tca.ProjectTaskID;

            var tcae = PXCache<PMTimeActivity>.GetExtension<PMTimeActivityExt>(tca);
            startDate = tcae.UsrStartDate;
            endDate = tcae.UsrEndDate;
        }

        var tcd = (EPTimecardDetail)e.Row;
        if (tcd == null) return;

        tcd.Date = date;
        tcd.Day = day;

        var tcde = PXCache<PMTimeActivity>.GetExtension<PMTimeActivityExt>(tcd);
        tcde.UsrStartDate = startDate;
        tcde.UsrEndDate = endDate;
        tcd.TimeSpent = CalcTimeWorked(tcde);

        tcd.ProjectID = project;
        tcd.ProjectTaskID = task;
        tcd.Summary = "=====";

    }
}

问题原因与解决方法

问题根源是直接修改实体字段后,没有通知PXCache字段已变更,导致缓存未标记为脏(dirty)。保存时系统认为该行没有修改,不会将其持久化到数据库。

有两种可靠的解决方式:

  1. 使用PXCache.SetValue系列方法赋值:
    这类方法会自动标记字段为脏状态,让系统识别到变更。比如把tcd.Date = date;改成sender.SetValue<EPTimecardDetail.date>(tcd, date);,自定义扩展字段用SetValueExtension处理。
  2. 手动标记缓存为脏:
    在所有字段修改完成后,调用sender.MarkDirty(tcd);或者sender.SetStatus(tcd, PXEntryStatus.Updated);,强制让系统识别该行有变更。

另外,原代码中遍历获取最后一行的逻辑可以优化,直接用LastOrDefault筛选有效行,效率更高且逻辑更清晰:

修改后的示例代码

protected void EPTimecardDetail_RowInserted(PXCache sender, PXRowInsertedEventArgs e)
{
    if (isCreateCorrectionFlag) return;

    // 获取最后一行带项目ID的有效数据
    var lastValidRow = Base.Activities.Select()
        .Where(tca => tca.ProjectID != null)
        .LastOrDefault();
    if (lastValidRow == null) return;

    var tcd = (EPTimecardDetail)e.Row;
    if (tcd == null) return;

    // 使用SetValue自动标记字段变更
    sender.SetValue<EPTimecardDetail.date>(tcd, lastValidRow.Date);
    sender.SetValue<EPTimecardDetail.day>(tcd, lastValidRow.Day);
    sender.SetValue<EPTimecardDetail.projectID>(tcd, lastValidRow.ProjectID);
    sender.SetValue<EPTimecardDetail.projectTaskID>(tcd, lastValidRow.ProjectTaskID);
    sender.SetValue<EPTimecardDetail.summary>(tcd, "=====");

    // 处理自定义扩展字段
    var lastRowExt = PXCache<PMTimeActivity>.GetExtension<PMTimeActivityExt>(lastValidRow);
    sender.SetValueExtension<PMTimeActivityExt.usrStartDate>(tcd, lastRowExt.UsrStartDate);
    sender.SetValueExtension<PMTimeActivityExt.usrEndDate>(tcd, lastRowExt.UsrEndDate);

    tcd.TimeSpent = CalcTimeWorked(sender.GetExtension<PMTimeActivityExt>(tcd));
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 18:20:29