计划运算向导的第一步,很多用户在选了计划方案之后,通常需要选择需求单据。之前收到过一些用户的反馈,在选择需求单据的同时,希望能携带更多在需求单据上的字段,来方便计划员在运算时更全面了解需求单据的信息。
但稍显可惜的是,计划运算选单因为系统标准逻辑较为复杂,并且交互界面来回切换,因此之前并不支持计划运算选单携带自定义字段。
不过,既然这是个合理的需求,就有理由支持。我们在最新补丁中已支持在适当二开的情况下,支持计划运算携带自定义字段。具体是6.X打2017-11-16的补丁PT117877,7.X打2017-11-30的补丁PT118904得到支持。
在此补丁基础上,以下讲述适当的二开都需要做些什么,本贴将拿计划运算选销售订单为示例。
设定计划运算选销售订单需要额外携带销售订单上要货日期,明细备注这两个信息。
首先,需在计划运算向导界面添加用于承接这两个信息的字段:
然后,需要写一个计划运算向导的表单插件并注册到标准插件后面,以下是经过验证OK的插件示例:
插件代码如下,请留意注释部分以帮助理解:
using Kingdee.BOS.Core.DynamicForm.PlugIn.WizardForm;
using Kingdee.BOS.Core.Metadata;
using Kingdee.BOS.Core.Metadata.EntityElement;
using Kingdee.BOS.Core.SqlBuilder;
using Kingdee.BOS.Orm.DataEntity;
using Kingdee.BOS.ServiceHelper;
using Kingdee.BOS.Util;
using Kingdee.K3.Core.MFG.EntityHelper;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
namespace Kingdee.K3.MFG.PLN.Business.PlugIn.DynamicForm.WizardForm
{
[Description("计划运算向导测试插件")]
public class MrpCalWizardTest : AbstractWizardFormPlugIn
{
public override void AfterDoOperation(BOS.Core.DynamicForm.PlugIn.Args.AfterDoOperationEventArgs e)
{
base.AfterDoOperation(e);
//操作代码固定是AfterSelectBill,
//using Kingdee.BOS.Util;之后可字符串具备EqualsIgnoreCase扩展方法,表示字符串不区分大小写比较
if (e.Operation.Operation.EqualsIgnoreCase("AfterSelectBill"))
{
GetSOProperty();
}
}
///
/// 获取销售订单相关属性
///
private void GetSOProperty()
{
//获取系统标准逻辑选取的销售订单信息
Entity entity = this.View.BusinessInfo.GetEntity("FEntity");
DynamicObjectCollection entrys = this.View.Model.GetEntityDataObject(entity);
//using Kingdee.K3.Core.MFG.EntityHelper;之后,DynamicObject类型的对象将具备GetDynamicValue
List
.Select(s => s.GetDynamicValue
if (soEIds.IsEmpty()) return;
//因为本插件是单据表单插件,按规范不能直接执行SQL,所以用QueryServiceHelper捞取数据,也可以用BusinessDataServiceHelper.Load(...)获取
DynamicObjectCollection soInfos = QueryServiceHelper.GetDynamicObjectCollection(this.Context, new QueryBuilderParemeter()
{
FormId = "SAL_SaleOrder", //销售订单标识
SelectItems = SelectorItemInfo.CreateItems(
"FId", //订单内码
"FSaleOrderEntry_FEntryID As FEntryID", //订单分录内码
"FDeliveryDate", //要货日期
"FEntryNote" //表体备注
),
FilterClauseWihtKey = string.Format(" FSaleOrderEntry_FEntryID IN({0}) ", string.Join(",", soEIds)) //过滤条件
});
//对于获取的销售订单数据构建成字典,以提升后续在循环中查找数据的效率
//这也是性能优化最常用并且效果最好的方式之一:循环外统一获取数据,然后构建成字典,再在循环中查找字典取数使用
Dictionary
soInfos.GroupBy(g => g.GetDynamicValue
IGrouping
//用数据模型对表体赋值,循环表体数据,进行自定义字段赋值
for (int i = 0; i < entrys.Count; i++)
{
string formId = entrys[i].GetDynamicValue
[/i] if (!formId.EqualsIgnoreCase("SAL_SaleOrder")) continue;
long relationEntryId = entrys.GetDynamicValue
if (!soInfoGroups.TryGetValue(relationEntryId, out soInfoGroup)) continue;
DynamicObject soInfo = soInfoGroup.First();
this.View.Model.SetValue("FDeliveryDate", soInfo.GetDynamicValue
this.View.Model.SetValue("FEntryNote", soInfo.GetDynamicValue
}
//如果表体数量量极大(几百上千行或以上),且自定义字段不涉及实体服务规则和值更新事件,请用以下方式对自定义字段赋值,本例暂注释
//this.View.Model.BeginIniti();
//foreach (DynamicObject entry in entrys)
//{
// string formId = entry.GetDynamicValue
// if (!formId.EqualsIgnoreCase("SAL_SaleOrder")) continue;
// long relationEntryId = entry.GetDynamicValue
// if (!soInfoGroups.TryGetValue(relationEntryId, out soInfoGroup)) continue;
// DynamicObject soInfo = soInfoGroup.First();
// entry["DeliveryDate"] = soInfo.GetDynamicValue
// entry["Note"] = soInfo.GetDynamicValue
//}
//this.View.Model.EndIniti();
//DBServiceHelper.LoadReferenceObject(this.Context, entrys.ToArray(), entity.DynamicObjectType, false);
//this.View.UpdateView("FSaleOrderEntry");
}
}
}
实现效果形如:
推荐阅读