SOOrder多行更新异常:第二行SOLine的OrderQty未变更问题
问题分析与解决方案
问题原因
你遇到的第二行SOLine数量未更新的问题,核心原因有两个:
- SOLine对象未在图缓存中:原代码通过
soOrderEntryMaint.Select<SOLine>().First()直接查询数据库,获取的对象不在SOOrderEntry图的缓存内。调用Transactions.Update(soLine)时,Acumatica无法识别该记录的原始状态,导致更新操作未被正确提交。 - 跨订单的缓存干扰:循环复用同一个SOOrderEntry实例并调用
Clear(),处理不同订单的Split时,上下文状态混乱,导致后续记录加载和更新逻辑失效。
修正后的代码
protected void _(Events.RowPersisted<INLotSerialStatus> e) { var remaining = /* 补充你的remaining初始值 */; var lotSerial = /* 补充你的lotSerial值 */; var siteID = /* 补充你的siteID值 */; // 用PXSelect替代直接查询,确保获取最新的Split记录 var existingSHSoLineLineSplits = PXSelect<SOLineSplit, Where<SOLineSplit.orderType, Equal<Required<SOLineSplit.orderType>>, And<SOLineSplit.lotSerialNbr, Equal<Required<SOLineSplit.lotSerialNbr>>, And<SOLineSplit.siteID, Equal<Required<SOLineSplit.siteID>>>>>, OrderBy<Asc<SOLineSplit.qty>>> .Select(Base, SSIConstants.OrderTypes.SH, lotSerial, siteID) .ToList(); foreach (SOLineSplit soLineSplit in existingSHSoLineLineSplits) { if (remaining <= 0) break; // 为每个订单创建独立的SOOrderEntry实例,彻底避免缓存干扰 using (var soOrderEntryMaint = PXGraph.CreateInstance<SOOrderEntry>()) { // 加载目标订单 var soOrder = soOrderEntryMaint.Document.Search<SOOrder.orderNbr>(soLineSplit.OrderNbr, soLineSplit.OrderType); if (soOrder == null) continue; soOrderEntryMaint.Document.Current = soOrder; // 加载对应的订单行(从视图缓存获取,确保可被更新) var soLine = soOrderEntryMaint.Transactions.SelectSingleLine<SOLine.lineNbr>(soLineSplit.LineNbr); if (soLine == null) continue; soOrderEntryMaint.Transactions.Current = soLine; // 加载对应的Split记录(从视图缓存获取) var splitToUpdate = soOrderEntryMaint.splits.SelectSingleLine<SOLineSplit.splitLineNbr>(soLineSplit.SplitLineNbr); if (splitToUpdate == null) continue; soOrderEntryMaint.splits.Current = splitToUpdate; // 简化扣减数量计算 decimal qtyToDecrement = Math.Min(remaining, splitToUpdate.Qty ?? 0); // 更新Split数量 splitToUpdate.Qty = splitToUpdate.Qty - qtyToDecrement; soOrderEntryMaint.splits.Update(splitToUpdate); // 更新订单行数量,确保不小于0 soLine.Qty = soLine.Qty - qtyToDecrement; soLine.Qty = soLine.Qty < 0 ? 0 : soLine.Qty; soOrderEntryMaint.Transactions.Update(soLine); // 保存当前订单的更改 soOrderEntryMaint.Actions.PressSave(); // 更新剩余待扣减数量 remaining -= qtyToDecrement; } } }
关键修改点
- 独立实例处理每个订单:用
using块为每个订单创建新的SOOrderEntry实例,彻底避免不同订单之间的缓存状态干扰。 - 从视图缓存获取记录:通过
Document.Search、Transactions.SelectSingleLine、splits.SelectSingleLine方法获取记录,确保对象存在于图的缓存中,Update操作能正确识别并提交变更。 - 简化数量计算逻辑:用
Math.Min直接确定扣减数量,减少分支判断的出错概率。 - 移除Clear操作:由于每个循环都使用全新的图实例,无需手动清空缓存。
内容的提问来源于stack exchange,提问作者mbargar13
相关产品推荐
相关产品推荐

