【套打】自实现合并套打所选子分录原创
金蝶云社区-_Tmp
_Tmp
18人赞赏了该文章 3887次浏览 未经作者许可,禁止转载编辑于2020年06月06日 14:17:25

系统针对子分录只有连续套打所选子分录操作;而合并操作只有合并单据和合并分录操作。


以工序计划为例,套打模板如下设置,数据表格绑定工序序列单据体,数据行嵌套文本控件绑定单据头字段,嵌套简单数据表格绑定工序列表子单据体。

image.png


合并套打所选分录效果如下(会打印所选分录下的所有子分录):

image.png


连续套打所选子分录效果如下(不同单据会换页):

image.png


image.png


那么如果我们想实现合并套打所选子分录(不同单据不换页,且只打印勾选的子分录数据)应该怎么实现呢。

可以利用合并套打所选分录操作,然后对子分录数据按照列表勾选行进行过滤。

<1>在业务对象的列表菜单增加菜单项,菜单的点击事件调用系统操作“合并预览所选分录”(这个是预览操作,打印操作则改为“合并套打所选分录”)。

image.png

<2>挂设列表插件,实现套打数据包修改

image.png

image.png

image.png

<3>效果验证

image.png

image.png


示例代码如下:

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();

        }

    }


这个代码当然也不是最佳实践,在列表选择行过多的时候查找选中行的性能就会下降,只是提供一个例子针对套打数据包进行数据过滤,最佳实践比如说维护一个字典快速判断对应数据是否选中行。

以下示例利用了过滤方案针对同一级实体只能勾选一个,所以不考虑一个单据体下多个子单据体的问题,只需要记录内码关系即可

image.png

image.png

image.png

赞 18