通过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)。保存时系统认为该行没有修改,不会将其持久化到数据库。
有两种可靠的解决方式:
- 使用
PXCache.SetValue系列方法赋值:
这类方法会自动标记字段为脏状态,让系统识别到变更。比如把tcd.Date = date;改成sender.SetValue<EPTimecardDetail.date>(tcd, date);,自定义扩展字段用SetValueExtension处理。 - 手动标记缓存为脏:
在所有字段修改完成后,调用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
相关产品推荐
相关产品推荐

