报表如何实现多表联查原创
金蝶云社区-陈来珍
陈来珍
0人赞赏了该文章 1072次浏览 未经作者许可,禁止转载编辑于2023年10月16日 11:22:25

关键词:报表、中间表、多表联查

一、需求

1、原始需求:在报表查询时,要求查询出采购入库单和生产入库单当日和当月各个仓库各个物料对应的入库数量,如下:

仓库物料本日采购入库数量本月采购入库数量本日生产入库数量本月生产入库数量
华南仓库摸具111333111222

表单信息如下:

image.png

image.png


二、思路与方案

1、痛点分析:后续可能有上千万条数据多表联查处理,始时查询的报表很慢,并且采购入库和生产入库的业务单每秒中都可能产生,所以综合考虑下:

(1)数据量大,查询慢

(2)实时性要求不了

那么可以通过创建中间表、用定时任务在某个时间间隔时处理好相关数据并插入中间表,然后报表可以直接取数。

2、开发方案

本案例只接受插入中间表的过程

image.png

三、实现过程

1、创建中间表

image.png


2、定时任务配置

配置过程参考:https://developer.kingdee.com/school/144893020511528192?productLineId=29

3、编写调度任务类

public class ImTaskCountScheduler extends AbstractTask {
//    public TaskImCountScheduler() {
//    }
//调度任务执行入口
    public void execute(RequestContext requestContext, Map<String, Object> map) throws KDException {
        //任务处理逻辑另起接口,方便其他地方直接调用
        ImTaskCountService taskCountService = new ImTaskCountServiceImpl();
        taskCountService.countTask();
    }
}

主业务计算逻辑(详细代码看文章后面的附件)

//实现中间表数据存储功能
@Override
public void countTask() {
    ImDateRangeEnum[] dateRangeEnums = ImDateRangeEnum.values();
    DataSet preDS=null;
    //计算各个表单的数据
    for (int index = 0; index < BILLNUMBER.length; index++) {
        //(1)查出某表单本日数据
        DataSet taskdData = this.query(dateRangeEnums[0], BILLNUMBER[index]);
        //(2)查出某表单本月数据
        DataSet taskmData = this.query(dateRangeEnums[3], BILLNUMBER[index]);
        if (taskdData == null || taskmData == null) {
            logger.info("待同步数据为空");
            return;
        }
        //今天数据分组求和
        taskdData = this.process(taskdData);
        //本月数据分组求和
        taskmData = this.process(taskmData);
        //(3)本日数据和本月数据合并,以月份数据为主表,因为本日存在的仓库、物料对应的入库数据,本月数据中一定有
        DataSet billDs = taskdData.rightJoin(taskmData).on(groupBy[0], groupBy[0]).on(groupBy[1], groupBy[1]).
                select(new String[]{ "qty" + " as " + TARGET_QTY[index][0]},
                        new String[]{groupBy[0], groupBy[1],"qty" + " as " + TARGET_QTY[index][1]}).finish();
        if (preDS == null) {
            preDS = billDs;
            preDS.copy().print(true);
        } else {//合并两个结果集

            preDS.copy().print(true);
            billDs.copy().print(true);
            //(4)采购入库单数据和生产入库入库单数据合并,相同的仓库和物料合并到同一条数据中
            preDS = myUnionDs(preDS, billDs, index);
        }
    }
        //是否需要删除旧的数据
             this.deleteAllData();
        if (preDS != null) {
            //分批往中间表插入数据
            this.save(preDS);
        }

}

四、效果图

点击手工执行调度计划

image.png

打开入库直接列表,可以看采购入库和生产入库本日和本月数据已插入中间表。

image.png

五、开发环境版本

V5.0.012

六、参考资料


共享任务中心的个人任务排名报表(报表)

开发平台

学习成长中心

SDK接口

开发必备100个小知识

开发案例库


赞 0