二开案例.动态表单插件.动态创建显示列
需求
显示某个产线下的所有序列号,并能够看出序列号加工到哪个作业,作业的列数不固定,需要动态显示
实现逻辑
OnSetBusinessInfo事件与OnSetLayoutInfo事件一起使用,通过捕获OnSetBusinessInfo事件,修改单据的逻辑元模型(BusinessInfo),动态添加字段,通过捕获OnSetLayoutInfo事件修改单据的布局元模型(LayoutInfo),设置动态添加字段的位置。
元数据
最终效果
示例代码
/// <summary> /// 当前业务信息 /// </summary> private BusinessInfo currBusinessInfo; /// <summary> /// 当前布局信息 /// </summary> private LayoutInfo currLayoutInfo; /// <summary> /// 工作中心Id /// </summary> private long workCenterId; /// <summary> /// 生产订单单据类型(启用工序跟踪、柔性生产) /// </summary> private List<string> lstMoBillTypeFiltered = new List<string>(); /// <summary> /// 工序信息,用于确定每个工序计划的工序及顺序 /// </summary> private DynamicObjectCollection optInfos; /// <summary> /// 最大工序数,用于确定有多少列 /// </summary> private int maxOptNumber; /// <summary> /// 序列号信息,用于展示最终数据 /// </summary> private DynamicObjectCollection snInfos; public override void AfterBindData(EventArgs e) { base.AfterBindData(e); FillData(); } /// <summary> /// 填充数据 /// </summary> private void FillData() { //序列号条件 string snCondition = Convert.ToString(this.Model.GetValue("FSnCondition")); IEnumerable<DynamicObject> snInfosByCondition; if (snCondition.IsNullOrEmptyOrWhiteSpace()) { snInfosByCondition = snInfos; } else { snInfosByCondition = snInfos.Where(o => Convert.ToString(o["FSNNumber"]).Contains(snCondition)); } List<IGrouping<object, DynamicObject>> snInfoGroupBySerialId = snInfosByCondition.GroupBy(o => o["FSerialId"]).ToList(); //清除数据 this.Model.DeleteEntryData("FEntity"); //行 for (int i = 0; i < snInfoGroupBySerialId.Count(); i++) { //添加一行 this.Model.CreateNewEntryRow("FEntity"); //当前行序列号信息 IGrouping<object, DynamicObject> curRowSnInfo = snInfoGroupBySerialId[i]; long optPlanId = Convert.ToInt64(curRowSnInfo.FirstOrDefault()["FOptPlanId"]); Dictionary<long, IGrouping<long, DynamicObject>> dicOptInfo = optInfos.GroupBy(o => Convert.ToInt64(o["FOptPlanId"])).ToDictionary(o => o.Key); //当前行工序信息 List<DynamicObject> curRowOptInfo = dicOptInfo[optPlanId].OrderBy(o => Convert.ToInt64(o["FOperNumber"])).ToList(); string snNumber = Convert.ToString(curRowSnInfo.FirstOrDefault()["FSNNumber"]); //序列号 this.View.Model.SetValue("FSnNumber", snNumber, i); //列 for (int j = 0; j < curRowOptInfo.Count; j++) { //当前列的序列号信息,存在返修序的时候满足条件的不止一个,取审核时间最近的一个(sql取数的时候已经排序) DynamicObject curColumnSnInfo = curRowSnInfo.Where(o => Convert.ToInt64(o["FOperNumber"]) == Convert.ToInt64(curRowOptInfo[j]["FOperNumber"]) && Convert.ToInt64(o["FProcessId"]) == Convert.ToInt64(curRowOptInfo[j]["FProcessId"])).FirstOrDefault(); if (curColumnSnInfo != null) { string key = "FProcess" + (j + 1).ToString(); string value = string.Format("{0}-{1}-{2}-1", curColumnSnInfo["FOperNumber"], curColumnSnInfo["FProcessName"], curColumnSnInfo["FQtyType"]); this.View.Model.SetValue(key, value, i); } } } //刷新 this.View.UpdateView("FEntity"); } /// <summary> /// 调整单据的逻辑元数据包,动态添加列 /// </summary> /// <param name="e"></param> public override void OnSetBusinessInfo(SetBusinessInfoArgs e) { workCenterId = Convert.ToInt64(this.View.OpenParameter.GetCustomParameter("WorkCenterId")); //生产订单单据类型 Dictionary<string, DynamicObject> dicMoBillType = SFCCommonServiceHelper.GetAllMoBillType(this.Context); foreach (var moBillType in dicMoBillType) { //工序跟踪 bool isProcessTrack = moBillType.Value.GetDynamicObjectItemValue<bool>("IsProcessTrack"); //柔性生产 bool isFlexibleProduce = moBillType.Value.GetDynamicObjectItemValue<bool>("FlexibleProduce"); //工序跟踪 and 柔性生产 if (isProcessTrack && isFlexibleProduce) { lstMoBillTypeFiltered.Add(moBillType.Key); } } optInfos = GetOptInfos(workCenterId, lstMoBillTypeFiltered.ToArray()); //optInfos.GroupBy(o => o["FOptPlanId"]).ToDictionary(o => o.Key, o => o.Count()).Max(o => o.Value); maxOptNumber = optInfos.GroupBy(o => o["FOptPlanId"]).Max(o => o.Count()); snInfos = GetSnInfos(workCenterId, lstMoBillTypeFiltered.ToArray()); // 创建当前单据元数据副本,避免直接修改原始元数据,并发时有问题 FormMetadata currmetadata = (FormMetadata)ObjectUtils.CreateCopy( this.View.OpenParameter.FormMetaData); currBusinessInfo = currmetadata.BusinessInfo; currLayoutInfo = currmetadata.GetLayoutInfo(); // 取单据体的元数据模型 string currEntityKey = "FEntity"; Entity currEntity = currBusinessInfo.GetEntity(currEntityKey); // 取原始的字段。动态添加的字段,是基于原始字段的一个分身 Field oriField = currBusinessInfo.GetField("FSnNumber"); FieldAppearance oriFieldApp = currLayoutInfo.GetFieldAppearance("FSnNumber"); AddNewFieldsToBusinessInfo(currEntityKey, currEntity, oriField); // 强制要求重新构建单据的ORM模型 currBusinessInfo.GetDynamicObjectType(true); // 输出动态调整后的单据逻辑元数据模型(BusinessInfo) e.BusinessInfo = currBusinessInfo; e.BillBusinessInfo = currBusinessInfo; } /// <summary> /// 调整单据的布局元数据,为动态添加列,产生外观布局对象 /// </summary> /// <param name="e"></param> public override void OnSetLayoutInfo(SetLayoutInfoArgs e) { // 取原始字段的外观布局对象,尺码需仿照原始字段外观 FieldAppearance oriFldApp = currLayoutInfo.GetFieldAppearance("FSnNumber"); // 取明细表格外观布局对象 EntityAppearance entryApp = currLayoutInfo.GetEntityAppearance(oriFldApp.EntityKey); // 设置字段的录入顺序 int tabIndex = oriFldApp.Tabindex; tabIndex = AddNewFieldsToLayoutInfo(oriFldApp, tabIndex); // 对表格中的字段,重新按照TabIndex进行排序 entryApp.Layoutinfo.Sort(); // 输出动态调整后的单据布局 e.LayoutInfo = currLayoutInfo; // 要求明细表格,重新构建各列,以便把新加入的字段,也加入到表格控件中 EntryGrid grid = this.View.GetControl<EntryGrid>("FEntity"); grid.SetCustomPropertyValue("AllowLayoutSetting", false); grid.CreateDyanmicList(currLayoutInfo.GetEntityAppearance("FEntity")); this.View.SendDynamicFormAction(this.View); } /// <summary> /// 增加新字段到业务信息 /// </summary> /// <param name="currEntityKey"></param> /// <param name="currEntity"></param> /// <param name="oriField"></param> private void AddNewFieldsToBusinessInfo(string currEntityKey, Entity currEntity, Field oriField) { for (int i = 0; i < maxOptNumber; i++) { // 基于原始字段,复制出新字段,并设置必须改动的属性 Field newField = (Field)ObjectUtils.CreateCopy(oriField); newField.DynamicProperty = null; newField.ChildrenFields.Clear(); newField.EntityKey = currEntityKey; newField.Entity = currEntity; if (newField.UpdateActions != null) { newField.UpdateActions.Clear(); } // 必改属性,涉及到数据的加载 string name = "FProcess" + (i + 1).ToString(); newField.Key = name; newField.FieldName = name; newField.PropertyName = name; string chineseNumber = NumToChinese((i + 1).ToString()); newField.Name = new LocaleValue(Kingdee.BOS.Resource.ResManager.LoadKDString("作业", "0151515153565030034703", Kingdee.BOS.Resource.SubSystemType.MFG) + chineseNumber); // 把新字段,添加到单据的逻辑元数据模型(BusinessInfo)中 currBusinessInfo.Add(newField); } } /// <summary> /// 增加新字段到布局信息 /// </summary> /// <param name="oriFldApp"></param> /// <param name="tabIndex"></param> /// <returns></returns> private int AddNewFieldsToLayoutInfo(FieldAppearance oriFldApp, int tabIndex) { for (int i = 0; i < maxOptNumber; i++) { // 基于原始字段的外观,产生出新字段的外观 FieldAppearance newFieldApp = (FieldAppearance)ObjectUtils.CreateCopy(oriFldApp); string name = "FProcess" + (i + 1).ToString(); string chineseNumber = NumToChinese((i + 1).ToString()); newFieldApp.Key = name; newFieldApp.Caption = new LocaleValue(Kingdee.BOS.Resource.ResManager.LoadKDString("作业", "0151515153565030034703", Kingdee.BOS.Resource.SubSystemType.MFG) + chineseNumber); newFieldApp.Field = currBusinessInfo.GetField(name); newFieldApp.Tabindex = ++tabIndex; // 把新字段的外观,加入到单据布局对象中 currLayoutInfo.Add(newFieldApp); } return tabIndex; }
二开案例.动态表单插件.动态创建显示列
需求显示某个产线下的所有序列号,并能够看出序列号加工到哪个作业,作业的列数不固定,需要动态显示实现逻辑OnSetBusinessInfo事件与OnSet...
点击下载文档
本文2024-09-23 03:26:34发表“云星空知识”栏目。
本文链接:https://wenku.my7c.com/article/kingdee-k3cloud-158889.html
您需要登录后才可以发表评论, 登录登录 或者 注册
最新文档
热门文章