套打.二开案例.自实现合并套打所选子分录
【现状】
系统针对子分录只有连续套打所选子分录操作;而合并操作只有合并单据和合并分录操作。
【演示数据】
以工序计划为例,套打模板如下设置,数据表格绑定工序序列单据体,数据行嵌套文本控件绑定单据头字段,嵌套简单数据表格绑定工序列表子单据体。
合并套打所选分录效果如下(会打印所选分录下的所有子分录):
连续套打所选子分录效果如下(不同单据会换页):
那么如果我们想实现合并套打所选子分录(不同单据不换页,且只打印勾选的子分录数据)应该怎么实现呢。
可以利用合并套打所选分录操作,然后对子分录数据按照列表勾选行进行过滤。
【解决方案】
<1>在业务对象的列表菜单增加菜单项,菜单的点击事件调用系统操作“合并预览所选分录”(这个是预览操作,打印操作则改为“合并套打所选分录”)。
<2>挂设列表插件,实现套打数据包修改
<3>效果验证
示例代码如下:
public class MergeSubEntryListPlugIn : AbstractListPlugIn
{
string targetSubEntry = string.Empty;
bool mergeSubEntryList = false;
public override void BarItemClick(BarItemClickEventArgs e)
{
base.BarItemClick(e);
mergeSubEntryList = false;
targetSubEntry = 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);
var subEntryEntity = selectEntitnes.FirstOrDefault(x => x.EntityType == BOSEnums.Enum_EntityType.SubEntity);
if (headEntity == null || entryEntity == null || subEntryEntity == null)
{
this.View.ShowWarnningMessage("过滤方案中的选择实体没有勾选到子分录,无法进行合并套打所选子分录");
e.Cancel = true;
return;
}
//标记为合并子分录操作,记录目标子分录标识
mergeSubEntryList = true;
targetSubEntry = subEntryEntity.Key;
}
}
public override void OnPrepareNotePrintData(PreparePrintDataEventArgs e)
{
base.OnPrepareNotePrintData(e);
if (!mergeSubEntryList || e.DataObjects == null || e.DataObjects.Length == 0)
return;
var curEntity = this.View.BillBusinessInfo.GetEntity(e.DataSourceId) as SubEntryEntity;
//不是目标子单据体则不干预数据
if (curEntity == null || !curEntity.Key.EqualsIgnoreCase(targetSubEntry))
return;
HeadEntity headEntity = this.View.BillBusinessInfo.Entrys.FirstOrDefault(x => x is HeadEntity) as HeadEntity;
if (headEntity == null || curEntity.ParentEntity == null)
return;
List<DynamicObject> selectRowNoteData = new List<DynamicObject>();
foreach (var notePrintDataRow in e.DataObjects)
{
string billPk = null, entryPk = null, subEntryPk = null;
//获取当前套打数据行的单据内码,分录内码,子分录内码
if (notePrintDataRow.DynamicObjectType.Properties.ContainsKey(headEntity.EntryPkFieldName))
{
billPk = ObjectUtils.Object2String(notePrintDataRow[headEntity.EntryPkFieldName]);
}
if (notePrintDataRow.DynamicObjectType.Properties.ContainsKey(curEntity.ParentEntity.EntryPkFieldName))
{
entryPk = ObjectUtils.Object2String(notePrintDataRow[curEntity.ParentEntity.EntryPkFieldName]);
}
if (notePrintDataRow.DynamicObjectType.Properties.ContainsKey(curEntity.EntryPkFieldName))
{
subEntryPk = ObjectUtils.Object2String(notePrintDataRow[curEntity.EntryPkFieldName]);
}
if (billPk.IsNullOrEmpty() || entryPk.IsNullOrEmpty() || subEntryPk.IsNullOrEmpty())
continue;
//判断当前行子分录行是否为列表选中行,是选中行则加入到自定义的数据集合中
var currSelectRow = this.ListView.SelectedRowsInfo.FirstOrDefault(x => x.PrimaryKeyValue == billPk &&
x.EntryEntityKey == curEntity.ParentEntity.Key && x.EntryPrimaryKeyValue == entryPk &&
x.FieldValues.ContainsKey(curEntity.Key) && x.FieldValues[curEntity.Key] == subEntryPk);
if (currSelectRow == null)
continue;
selectRowNoteData.Add(notePrintDataRow);
}
//使用自定义数据集合覆盖系统的数据包,本质就是过滤掉非选中行数据
e.DataObjects = selectRowNoteData.ToArray();
}
}
这个代码当然也不是最佳实践,在列表选择行过多的时候查找选中行的性能就会下降,只是提供一个例子针对套打数据包进行数据过滤,最佳实践比如说维护一个字典快速判断对应数据是否选中行。
以下示例利用了过滤方案针对同一级实体只能勾选一个,所以不考虑一个单据体下多个子单据体的问题,只需要记录内码关系即可
套打.二开案例.自实现合并套打所选子分录
本文2024-09-23 04:12:43发表“云星空知识”栏目。
本文链接:https://wenku.my7c.com/article/kingdee-k3cloud-163845.html