本文讨论了在单据处理中直接修改数据包为基础资料字段赋值的重要性及正确方法。错误赋值可能引发后续代码问题,如保存报错或数据错误。文中通过对比错误和正确代码,指出应使用基础资料字段的引用模型(RefFormDynamicObjectType)来加载并赋值数据包,以确保字段与数据包正确匹配。
在很多情况下,需要直接修改单据的数据包,给基础资料字段赋值;
如单据转换插件中,给基础资料字段赋值:此时没有单据Model.SetValue()方法可以调用,必须直接修改单据数据包。
但如果没有按照正确的方法给基础资料赋值,就可能会为后续代码埋下一个大隐患。
在阅读本帖之前,先看下这个帖子反馈的问题:
https://vip.kingdee.com/article/36437
有关生成单据保存报错
这个问题的原因,就是因为插件给物料字段赋值方法错误:给物料字段填写的数据包,并不是物料需要的数据包。
这会导致物料字段的引用属性与引用数据包不匹配。
随后,单据的实体服务规则、保存校验器等,会按照引用属性到数据包取属性值。
如果引用属性与引用数据包不匹配,会取错数!
轻则报错中断,重则蒙混过关,但是数据全错!
原理已经知道了,下面看看典型的错误代码:
//********************************************
// 给基础资料字段赋值,如下方式是错误的:
// 使用了 stockMeta.BusinessInfo.GetDynamicObjectType() 加载基础资料引用数据包
IMetaDataService metaService = ServiceHelper.GetService
FormMetadata stockMeta = metaService.Load(this.Context, "BD_STOCK") as FormMetadata;
long stockId = Convert.ToInt64(reader["FStockId"]);
IViewService viewService = ServiceHelper.GetService
DynamicObject[] stockObjs = viewService.LoadFromCache(this.Context,
new object[] { stockId },
stockMeta.BusinessInfo.GetDynamicObjectType());
stockFld.RefIDDynamicProperty.SetValue(newRowObj, stockId);
stockFld.DynamicProperty.SetValue(newRowObj, stockObjs[0]);
//***********************************************
如下是正确代码,请注意与错误代码之间的差别:
//*********************************************
// 给基础字段赋值,如下方式是正确的:
// 必须使用 stockFld.RefFormDynamicObjectType 加载基础资料引用数据包
BaseDataField stockFld = e.TargetBusinessInfo.GetField("FStockId") as BaseDataField;
long stockId = Convert.ToInt64(reader["FStockId"]);
IViewService viewService = ServiceHelper.GetService
DynamicObject[] stockObjs = viewService.LoadFromCache(this.Context,
new object[] { stockId },
stockFld.RefFormDynamicObjectType);
stockFld.RefIDDynamicProperty.SetValue(newRowObj, stockId);
stockFld.DynamicProperty.SetValue(newRowObj, stockObjs[0]);
//*********************************************
总结:
给基础资料赋值的正确方法,是使用基础资料本身的引用模型(RefFormDynamicObjectType),加载基础资料的数据包,然后填写到单据上。
推荐阅读