本文描述了在金蝶系统中配置子单据体转换时可能遇到的错误问题,特别是在旧版本中。为解决这个问题,提供了使用插件的方法。插件代码示例展示了如何在单据转换过程中通过插件获取源单数据,并在下推过程中处理数据转换,包括从源单据体中获取数据并赋值到目标单据体的相应位置。通过重写`OnGetSourceData`和`AfterConvert`方法,插件能够实现对单据转换过程的精确控制。
一、问题描述:
如下图,配置子单据体转换时会报错(目前7.6、7.7版本已经修复了这个,老版本会存在),如果出现这个报错,可以通过插件的形式进行处理
二、解决方法:可通过单据转换插件进行处理,
2.1、插件代码如下:
using Kingdee.BOS.Contracts;
using Kingdee.BOS.Core.Metadata.EntityElement;
using Kingdee.BOS.Orm.DataEntity;
using System;
using System.Linq;
using Kingdee.BOS.Core.Metadata;
using Kingdee.BOS.Core.Metadata.ConvertElement.PlugIn;
using Kingdee.BOS.Core.Metadata.ConvertElement.PlugIn.Args;
using System.ComponentModel;
namespace Dave.ConvertDemo.ServicePlugIn
{
/// <summary>
/// 按顺序输出单据转换-下推过程的插件事件
/// </summary>
[Kingdee.BOS.Util.HotUpdate]
[Description("子单据体单据转换插件")]
public class SubEntity : AbstractConvertPlugIn
{
private DynamicObject sourceBill = null;
object fid;
//获取源单数据
public override void OnGetSourceData(GetSourceDataEventArgs e)
{
base.OnGetSourceData(e);
fid = e.SourceData[0]["FId"];
if (fid != null && !"".Equals(fid))
{
string sfilter = string.Format("FID = {0} ", fid.ToString());
OQLFilter filter = OQLFilter.CreateHeadEntityFilter(sfilter);
if (null == sourceBill)
{
IViewService viewService = ServiceHelper.GetService<IViewService>();
sourceBill = viewService.Load(this.Context, e.SourceBusinessInfo.GetForm().Id, null, filter).FirstOrDefault();
}
}
}
// 下推携带
public override void AfterConvert(Kingdee.BOS.Core.Metadata.ConvertElement.PlugIn.Args.AfterConvertEventArgs e)
{
base.AfterConvert(e);
var headEntity = e.Result.FindByEntityKey("FBillHead");
foreach (var extendedDataEntity in headEntity)
{
// 声明选中单据体集合数据
DynamicObjectCollection entryCollection = null;
// 目标的父单据体实体(标识)
Entity entity = e.TargetBusinessInfo.GetEntity("FEntity");
//目标父单据体的数据包(orm)
entryCollection = extendedDataEntity.DataEntity["Entity"] as DynamicObjectCollection;
// 源单父单据体数据包(orm)
DynamicObjectCollection sourceObjCollection = sourceBill["TreeEntity"] as DynamicObjectCollection;
//父单据体行数差值,计算此差值是针对:目标单上已录入几行父单据体之后再去选单。
int difCount = entryCollection.Count;
if (sourceBill != null)
{
difCount -= sourceObjCollection.Count;
}
//从源单上获取每一条父单据体的子单据体集合,并赋值到目标单上对应的父单据体中。
for (int i = 0; i < entryCollection.Count; i++)
{
// 销售订单明细====父单据体实体
var entityData = entryCollection[i];
// 对应的订单明细索引
int index = entryCollection.IndexOf(entityData);
// 目标子单据体的实体(标识)
Entity FSubEntity = e.TargetBusinessInfo.GetEntity("F_QYGN_SubEntity");
// 目标子单据体的数据包(orm)
DynamicObjectCollection subCollection = entityData["F_QYGN_SubEntity"] as DynamicObjectCollection;
String[] SourceFeild = { "F_QYGN_SubText", "F_QYGN_SubDecimal", "F_QYGN_SubBase" };
String[] GoalFeild = { "F_QYGN_SubText", "F_QYGN_SubDecimal", "F_QYGN_SubBase" };
// 调用公共方法
// 参数1:目标子单据体标识 参数2:目标父单据体的当前行的实体 参数3:源单父单据体的实体名
// 参数4:源单子单据体实体名 参数5:要转换的字段名 参数6:当前行号
DynamicObjectCollection newRows = getSourceSubEntity(FSubEntity, entityData, "TreeEntity", "F_QYGN_SubEntity",
SourceFeild, GoalFeild, index - difCount);
if (subCollection == null)
{
subCollection = new DynamicObjectCollection(FSubEntity.DynamicObjectType, entityData);
}
else
{
subCollection.Clear();
}
int x = 1;
foreach (DynamicObject newRow in newRows)
{
newRow["Seq"] = x;
subCollection.Add(newRow);
x++;
}
}
}
}
/// <summary>
/// 从源单中获取单据体当前行对应的子单据体的数据集合
/// </summary>
/// <param name="FSubEntity">子单据体标识</param>
/// <param name="entityData">父单据体的当前行的实体</param>
/// <param name="entityName">源单父单据体的实体名</param>
/// <param name="subName">源单子单据体实体名</param>
/// <param name="fieldNames">要转换的字段名(目标单需要与源单字段名完全一致。另外不要遗漏序号字段-标识为Seq)</param>
/// <param name="index">当前行号</param>
/// <returns></returns>
private DynamicObjectCollection getSourceSubEntity(Entity FSubEntity, DynamicObject entityData, string entityName, string subName, string[] source, string[] goal, int index)
{
//创建一个目标单据体(包括父子单据体)
DynamicObjectCollection newRows = new DynamicObjectCollection(FSubEntity.DynamicObjectType, entityData);
//源单数据
if (sourceBill != null)
{
//获取原单的父单据体数据包
DynamicObjectCollection sourceObjCollection = sourceBill[entityName] as DynamicObjectCollection;
if (sourceObjCollection != null)
{//获取源子单据体的数据包集合
// DynamicObject s = sourceObjCollection[index] as DynamicObject;
DynamicObjectCollection sourceSubCollection = (sourceObjCollection[index] as DynamicObject)[subName] as DynamicObjectCollection;
//循环元数据包
foreach (var sourceSubEntityData in sourceSubCollection)
{
//创建一个目标子单据体的数据包
DynamicObject newRow = new DynamicObject(FSubEntity.DynamicObjectType);
for (int i = 0; i < source.Length; i++)
{
newRow[goal[i]] = sourceSubEntityData[source[i]];
}
newRows.Add(newRow);
}
}
}
return newRows;
}
}
}
2.2、将插件注册到单据转换中:
2.3、启用单据转换规则:
2.4、实现效果:
如有帮助,请点个赞呗
发布于 金蝶云星空BOS开发交流圈 社群
推荐阅读