基础资料赋值
金蝶云社区-云端迈步
云端迈步
12人赞赏了该文章 6,568次浏览 未经作者许可,禁止转载编辑于2018年05月17日 20:39:56

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

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

先看看下面的报错情况:
在做发货通知单 下推到销售出库单 保存Save报错 ,报错如下图,我暂存单据手工保存,提交,审核 都没问题这个问题的原因,就是因为插件给物料字段赋值方法错误:给物料字段填写的数据包,并不是物料需要的数据包。


090.png



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

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

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

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

// 给基础资料字段赋值,如下方式是错误的:
// 使用了 stockMeta.BusinessInfo.GetDynamicObjectType() 加载基础资料引用数据包

IMetaDataService metaService = ServiceHelper.GetService<IMetaDataService>();
FormMetadata stockMeta = metaService.Load(this.Context, "BD_STOCK") as FormMetadata;


long stockId = Convert.ToInt64(reader["FStockId"]);

IViewService viewService = ServiceHelper.GetService<IViewService>();
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<IViewService>();
DynamicObject[] stockObjs = viewService.LoadFromCache(this.Context,
    new object[] { stockId },
    stockFld.RefFormDynamicObjectType);

stockFld.RefIDDynamicProperty.SetValue(newRowObj, stockId);
stockFld.DynamicProperty.SetValue(newRowObj, stockObjs[0]);

//*********************************************

总结:
给基础资料赋值的正确方法,是使用基础资料本身的引用模型(RefFormDynamicObjectType),加载基础资料的数据包,然后填写到单据上。

赞 12