73.3、单据转换插件,多选基础资料,代码
续 73.2
1、打开VS,新建一个类 ,具体可以参考 4.1 1-7步
2、项目名称KingdeeYC.Bos.Test.ConvertPlug
3、修改类名称为 MulBaseZLConvPlug
4、引用的dll
Kingdee.BOS.dll
Kingdee.BOS.Contracts.dll
Kingdee.BOS.Core.dll
Kingdee.BOS.DataEntity.dll
Kingdee.BOS.App.dll
5、使用
using System;
using System.Collections.Generic;
using System.ComponentModel;
using Kingdee.BOS.Core.Metadata;
using Kingdee.BOS.Core.Metadata.ConvertElement.PlugIn;
using Kingdee.BOS.Core.Metadata.ConvertElement.PlugIn.Args;
using Kingdee.BOS.Core.Metadata.EntityElement;
using Kingdee.BOS.Orm.DataEntity;
using Kingdee.BOS.Contracts;
using Kingdee.BOS.App;
using Kingdee.BOS.Core.Metadata.FieldElement;
using System.Linq;
6、继承的接口类 AbstractConvertPlugIn
7、复制固定写法的代码
using System; using System.Collections.Generic; using System.ComponentModel; using Kingdee.BOS.Core.Metadata; using Kingdee.BOS.Core.Metadata.ConvertElement.PlugIn; using Kingdee.BOS.Core.Metadata.ConvertElement.PlugIn.Args; using Kingdee.BOS.Core.Metadata.EntityElement; using Kingdee.BOS.Orm.DataEntity; using Kingdee.BOS.Contracts; using Kingdee.BOS.App; using Kingdee.BOS.Core.Metadata.FieldElement; using System.Linq; namespace KingdeeYC.Bos.Test.ConverPlug { [Description("多选基础资料插件")] public class MulBaseZLConvPlug : AbstractConvertPlugIn { public override void AfterConvert(AfterConvertEventArgs e) { // 找到目标单单据关联主实体 var targetForm = e.TargetBusinessInfo.GetForm(); if (targetForm.LinkSet == null || targetForm.LinkSet.LinkEntitys == null || targetForm.LinkSet.LinkEntitys.Count == 0) { // 目标单未设置关联主实体,无法获取目标单的源单信息,携带不了 return; } // 关联主实体 Entity entity = e.TargetBusinessInfo.GetEntity( targetForm.LinkSet.LinkEntitys[0].ParentEntityKey); // 关联Link子实体 Entity linkEntity = e.TargetBusinessInfo.GetEntity( targetForm.LinkSet.LinkEntitys[0].Key); // 收集全部源单内码 HashSet<long> srcBillIds = new HashSet<long>(); // Dictionary(目标单索引, HashSet(源单内码)) Dictionary<int, HashSet<long>> dctDataIndexToSrcBillId = new Dictionary<int, HashSet<long>>(); var entryRows = e.Result.FindByEntityKey(entity.Key); foreach (var entryRow in entryRows) { int dataIndex = entryRow.DataEntityIndex; if (dctDataIndexToSrcBillId.ContainsKey(dataIndex) == false) { dctDataIndexToSrcBillId.Add(dataIndex, new HashSet<long>()); } var linkRows = linkEntity.DynamicProperty.GetValue(entryRow.DataEntity) as DynamicObjectCollection; foreach (var linkRow in linkRows) { long srcBillId = Convert.ToInt64(linkRow["SBillId"]); if (srcBillIds.Contains(srcBillId) == false) { srcBillIds.Add(srcBillId); } // 记录每条目标单,其引用的源单集合 if (dctDataIndexToSrcBillId[dataIndex].Contains(srcBillId) == false) { dctDataIndexToSrcBillId[dataIndex].Add(srcBillId); } } } // 读取源单上的多选辅助资料信息 IViewService viewService = ServiceHelper.GetService<IViewService>(); // 仅加载源单内码、多选辅助资料内码 List<SelectorItemInfo> selectItems = new List<SelectorItemInfo>(); selectItems.Add(new SelectorItemInfo(e.SourceBusinessInfo.GetForm().PkFieldName)); selectItems.Add(new SelectorItemInfo("F_MulDepId")); string filter = string.Format("{0} IN ({1})", e.SourceBusinessInfo.GetForm().PkFieldName, string.Join(",", srcBillIds)); var srcObjs = viewService.Load(this.Context, e.SourceBusinessInfo, selectItems, OQLFilter.CreateHeadEntityFilter(filter)); // 收集源单上全部的辅助资料内码 MulBaseDataField sourceFld = e.SourceBusinessInfo.GetField("F_MulDepId") as MulBaseDataField; HashSet<string> assIds = new HashSet<string>(); // Dictionary(源单内码, HashSet(辅助资料内码)) Dictionary<long, HashSet<string>> dctSrcBillIdToAssIds = new Dictionary<long, HashSet<string>>(); foreach (var srcObj in srcObjs) { long srcBillId = Convert.ToInt64(srcObj[0]); var srcAssiRows = sourceFld.RefEntityDynamicProperty.GetValue(srcObj) as DynamicObjectCollection; foreach (var srcAssiRow in srcAssiRows) { string assId = Convert.ToString(sourceFld.RefIDDynamicProperty.GetValue(srcAssiRow)); if (assIds.Contains(assId) == false) { assIds.Add(assId); } if (dctSrcBillIdToAssIds.ContainsKey(srcBillId) == false) { dctSrcBillIdToAssIds.Add(srcBillId, new HashSet<string>()); } if (dctSrcBillIdToAssIds[srcBillId].Contains(assId) == false) { dctSrcBillIdToAssIds[srcBillId].Add(assId); } } } // 加载辅助资料详情 MulBaseDataField targetFld = e.TargetBusinessInfo.GetField("F_MulDepId") as MulBaseDataField; var assObjs = viewService.Load( this.Context, (from p in assIds select (object)p).ToArray(), targetFld.RefFormDynamicObjectType); // Dictionary(辅助资料内码, 辅助资料数据包) Dictionary<string, DynamicObject> dctAssObjs = new Dictionary<string, DynamicObject>(); foreach (var assObj in assObjs) { string assId = Convert.ToString(assObj[0]); dctAssObjs.Add(assId, assObj); } // 向目标单填写辅助资料 var headObjs = e.Result.FindByEntityKey(targetFld.EntityKey); foreach (var item in dctDataIndexToSrcBillId) { int dataIndex = item.Key; DynamicObject headObj = headObjs[dataIndex].DataEntity; var mulAssiRows = targetFld.RefEntityDynamicProperty.GetValue(headObj) as DynamicObjectCollection; foreach (var srcBillId in item.Value) { if (dctSrcBillIdToAssIds.ContainsKey(srcBillId) == false) continue; foreach (var assId in dctSrcBillIdToAssIds[srcBillId]) { if (dctAssObjs.ContainsKey(assId) == false) continue; DynamicObject newAssiRow = new DynamicObject(targetFld.RefEntityDynamicObjectType); mulAssiRows.Add(newAssiRow); targetFld.RefIDDynamicProperty.SetValue(newAssiRow, assId); targetFld.DynamicProperty.SetValue(newAssiRow, dctAssObjs[assId]); } } } } } }
8、注意:修改3处理地方,改成上一章节,采购订单和收料通知单,字段标识 F_MULDEPID
9、注册插件
9.1、打开单据转换,点扩展
9.2、打开插件策略,点注册
10、最终效果,采购订单下推收料通知单,带出多选部门
总目录链接
https://wenku.my7c.com/article/6499387201459123
KingdeeYC.Bos.Test.ConverPlug.zip
如果是在明细行呢
注释不够明了,通过调试,插件实现原理及关键变量内容如下,供参考:
//关键变量结构
//dctDataIndexToSrcBillId :目标单,源单内码,用于目标单追溯源单内码
//dctSrcBillIdToAssIds:源单内码,多选资料id,通过1的源单内码,追溯单据对应的资料id
//dctAssObjs:多选资料id,对应动态对象,通过2的id找动态对象,用于后面赋值
//目标单值来源->目标单->源单内码->源单多选资料id->id对应动态对象
//1、将目标单单据体序号,源单内码写入 dctDataIndexToSrcBillId
//2、将源单内码,多选基础资料或辅助资料的id写入dctSrcBillIdToAssIds,并将id写入辅助资料集合dctAssObjs中
//3、将dctAssObjs内数据变更为id,动态对象(用于后面通过id及动态对象赋值)
//3、获取目标单表头数据,headObjs,headObjs的序号与第一点对应。
//4、遍历dts,以单据体序号找headObjs,并定位需要写入的字段。
//5、dts中的源单内码,从第二点中找到对应的多选数据的id
寻找实体上F_VKJV_SPBM对应的属性描述符失败,实体不存在此属性![EntityType:BillHead Propeyties:Id VKJV_XMSJ_SQSQEntity ]
linkEntity有数据,但是下面这句取不到值,帮我分析下是什么情况,我的目标单据体默认是没有行数据的,会不会是这个原因。
var linkRows = linkEntity.DynamicProperty.GetValue(entryRow.DataEntity) as DynamicObjectCollection;
原单和目标单单据体没有关联关系,然后linkEntity就是空集合,这种情况怎么获取原单的主键集合
【emoji】
打卡
顶你!
73.3、单据转换插件,多选基础资料,代码
本文2024-09-16 17:24:23发表“云星空知识”栏目。
本文链接:https://wenku.my7c.com/article/kingdee-k3cloud-15504.html