
# 【应用场景】
套打时,在打印中,需要按所选子单据体合并套打,并按照子分录中的某个字段进行分组
# 【案例】
以检验单为例,使用主表体和决策标题进行数据演示介绍方案的实现
# 【方案详解】
## <1>通过配置模板,实现按照子分录数据分组
文章参考:[使用数据表格直接绑定子分录数据,从而进行分组设置](https://vip.kingdee.com/article/129668187389477888)
第一步,通过数据表格直接绑定子单据体字段,如下所示(数据源为决策表体)

第二步,配置分组管理,按照子单据体字段进行分组设置

第三步,通过右侧数据源直接通入单据体字段,将数据表格绑定单据体字段(注意,出现交互提示时点“是”)

第四步,保存模板,验证打印结果,能够实现按照不同分录的子单据体数据进行分组

## <2>通过插件,实现按选中子分录数据过滤
文章参考:[按选中子分录合并套打](https://vip.kingdee.com/article/57110672764935425)
需要注意的是,此方案判断的套打数据源标识为主表体而非决策表体
插件中处理三件事
第一,记录选中的子分录内码BarItemClick
第二,在套打查询干预事件中,针对单据体数据源追加子单据体分录内码
第三,进行查询后的数据过滤,按照选中子分录的内码过滤数据
参考代码
```csharp
public class MergeSubEntryListPlugInV2 : AbstractListPlugIn
{
Dictionary<string, SelectNode> billPKSelectNodeMap = new Dictionary<string, SelectNode>();
string targetSubEntry = string.Empty;//目标子单据体标识
string targetEntry = string.Empty;//目标单据体标识
bool mergeSubEntryList = false;
public override void BarItemClick(BarItemClickEventArgs e)
{
base.BarItemClick(e);
mergeSubEntryList = false;
targetSubEntry = string.Empty;
targetEntry = string.Empty;
if (e.BarItemKey.EqualsIgnoreCase("MergeSelectSubEntry"))//前提校验,需要过滤方案存在三个实体
{
List<FilterEntity> selectEntitnes = this.ListView.Model.FilterParameter.SelectedEntities;
var headEntity = selectEntitnes.FirstOrDefault(x => x.EntityType == BOSEnums.Enum_EntityType.Header);
var entryEntity = selectEntitnes.FirstOrDefault(x => x.EntityType == BOSEnums.Enum_EntityType.Entity);
if (headEntity == null || entryEntity == null)
{
this.View.ShowWarnningMessage("过滤方案中的选择实体没有勾选到子分录,无法进行合并套打所选子分录");
e.Cancel = true; return;
}
var subEntryEntity = selectEntitnes.FirstOrDefault(x => x.EntityType == BOSEnums.Enum_EntityType.SubEntity && x.ParentKey == entryEntity.Key);
if (subEntryEntity == null)
{
this.View.ShowWarnningMessage("过滤方案中的选择实体没有勾选到子分录,无法进行合并套打所选子分录");
e.Cancel = true; return;
}
mergeSubEntryList = true;
billPKSelectNodeMap.Clear();
targetEntry = entryEntity.Key;
targetSubEntry = subEntryEntity.Key;
foreach (var selectRow in this.ListView.SelectedRowsInfo)
{
if (!billPKSelectNodeMap.ContainsKey(selectRow.PrimaryKeyValue))
{ //构建单据头选择节点
var billNode = new SelectNode() { ChildNodes = new Dictionary<string, SelectNode>() };
billPKSelectNodeMap[selectRow.PrimaryKeyValue] = billNode;
}
var entryRowNode = billPKSelectNodeMap[selectRow.PrimaryKeyValue].ChildNodes.ContainsKey(selectRow.EntryPrimaryKeyValue) ?
billPKSelectNodeMap[selectRow.PrimaryKeyValue].ChildNodes[selectRow.EntryPrimaryKeyValue] : null;
if (entryRowNode == null)
{ //构建单据体分录选择节点
entryRowNode = new SelectNode() { ChildNodes = new Dictionary<string, SelectNode>() };
billPKSelectNodeMap[selectRow.PrimaryKeyValue].ChildNodes[selectRow.EntryPrimaryKeyValue] = entryRowNode;
}
var subEntryPkVal = selectRow.FieldValues[subEntryEntity.Key];
if (!entryRowNode.ChildNodes.ContainsKey(subEntryPkVal))
{ //构建子单据体分录选择节点
var subEntryRowNode = new SelectNode();
entryRowNode.ChildNodes[subEntryPkVal] = subEntryRowNode;
}
}
}
}
public override void OnPrepareNotePrintQueryParam(PrepareNotePrintQueryParamEventArgs e)
{
if (!mergeSubEntryList)
return;
//使用了合并套打所选子分录,需要在单据体的数据源中注册子单据体的内码字段
if (!e.DataSourceId.EqualsIgnoreCase(targetEntry))
return;
SubEntryEntity subEntryEntity = View.BillBusinessInfo.GetEntity(targetSubEntry) as SubEntryEntity;
if (subEntryEntity == null)
return;
strin