如何从创建采购订单界面同步SOLine自定义字段至POLine的CuryUnitCost?
从销售订单行同步自定义成本到采购订单行的正确实现方式
你之前在RowSelected事件里的做法确实有不少隐患——这个事件会频繁触发,而且依赖OrderNbr生成后再更新,不仅效率低,还容易因为手动调用PressSave()造成循环触发的问题。咱们换个更合适的时机来处理这个同步逻辑。
核心思路
当从销售订单(SO)生成采购订单(PO)时,每个POLine都会关联对应的SOLineSplit记录(用来关联SO和PO的中间表),而POLine的PlanID字段会直接对应SOLineSplit.PlanID。我们可以利用这个关联关系,在POLine刚被插入缓存时就同步SOLine的自定义成本字段,不需要等PO的OrderNbr生成。
代码实现
替换你之前的RowSelected事件,改用POLine_RowInserted事件来处理:
protected virtual void POLine_RowInserted(PXCache cache, PXRowInsertedEventArgs e) { POLine poLine = e.Row as POLine; if (poLine == null) return; // 通过PlanID找到对应的SOLineSplit记录 SOLineSplit soSplit = PXSelect<SOLineSplit, Where<SOLineSplit.planID, Equal<Required<SOLineSplit.planID>>>> .Select(Base, poLine.PlanID); if (soSplit == null) return; // 根据SOLineSplit关联到对应的SOLine SOLine soLine = PXSelect<SOLine, Where<SOLine.orderType, Equal<Required<SOLine.orderType>>, And<SOLine.orderNbr, Equal<Required<SOLine.orderNbr>>, And<SOLine.lineNbr, Equal<Required<SOLine.lineNbr>>>>> .Select(Base, soSplit.OrderType, soSplit.OrderNbr, soSplit.LineNbr); if (soLine == null) return; // 获取SOLine的自定义字段扩展 SOLineExt soLineExt = PXCache<SOLine>.GetExtension<SOLineExt>(soLine); if (soLineExt.UsrUnitCost != null) { // 更新POLine的CuryUnitCost,无需手动调用Save,系统会自动处理缓存修改 cache.SetValueExt<POLine.curyUnitCost>(poLine, soLineExt.UsrUnitCost); } }
为什么这个方案更合理?
- 触发时机准确:
RowInserted事件只会在POLine被添加到缓存时触发一次,不会像RowSelected那样每次选中行都执行,效率更高。 - 无需等待OrderNbr生成:
PlanID在POLine创建时就已经被赋值,直接通过它关联到SOLineSplit和SOLine,不需要依赖PO的自动编号生成。 - 避免循环触发:不需要手动调用
PressSave(),修改会被存入缓存,等待系统正常保存流程提交,不会造成循环触发的问题。
额外提示
如果你的场景是批量从SO生成PO(比如用“Create Purchase Orders”处理),这个逻辑同样适用,因为批量生成时每个POLine都会触发RowInserted事件。
内容的提问来源于stack exchange,提问作者Prathyusha
相关产品推荐
相关产品推荐

