常见问题 - 使用错误的方式给基础资料字段赋值
金蝶云社区-JohnnyDing
JohnnyDing
3人赞赏了该文章 9756次浏览 未经作者许可,禁止转载编辑于2016年03月22日 09:13:15

在很多情况下,需要直接修改单据的数据包,给基础资料字段赋值;
如单据转换插件中,给基础资料字段赋值:此时没有单据Model.SetValue()方法可以调用,必须直接修改单据数据包。

但如果没有按照正确的方法给基础资料赋值,就可能会为后续代码埋下一个大隐患。

在阅读本帖之前,先看下这个帖子反馈的问题:

https://vip.kingdee.com/article/162033
有关生成单据保存报错

这个问题的原因,就是因为插件给物料字段赋值方法错误:给物料字段填写的数据包,并不是物料需要的数据包。

这会导致物料字段的引用属性引用数据包不匹配。

随后,单据的实体服务规则、保存校验器等,会按照引用属性到数据包取属性值。
如果引用属性与引用数据包不匹配,会取错数!

轻则报错中断,重则蒙混过关,但是数据全错!

原理已经知道了,下面看看典型的错误代码
//********************************************

// 给基础资料字段赋值,如下方式是错误的:
// 使用了 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),加载基础资料的数据包,然后填写到单据上。