找回密码
 立即注册

QQ登录

只需一步,快速开始

Bella.Yuan Wyn认证
超级版主   /  发表于:2024-2-4 13:39  /   查看:1841  /  回复:0
本帖最后由 Bella.Yuan 于 2024-2-19 12:13 编辑

最近看大家都会问考勤报表的制作,那针对这类报表该如何设计呢,下面我们就来一起看看。

针对这个报表,我们以这个客户的这个帖子的数据为例来进行对应的设计和实现:
https://gcdn.grapecity.com.cn/showtopic-202452-1-1.html

步骤1:准备数据。首先需要准备的就是数据源,数据集,这里针对这2个功能不做过多的赘述了,大家如果对这2个功能还有疑问的,可以参考帮助文档的这一章节:数据连接数据准备

步骤2:根据需求判断组件的使用以及其他设置。数据准备好之后,那就进入到报表设计,我们先来看看对应的要实现的报表的样子,根据样子去判断该选择那个组件以及该如何设计报表。

image.png855856628.png
由上图可以看到,该报表有2个报表参数,所以我们就需要考虑对应的报表需要2个参数,看看参数是添加在数据集还是添加在报表上,这里大家根据自己的实际情况进行添加,如果想添加在数据集上且报表中根据输入的值进行数据过滤,那就需要使用“直连数据集”,这里需要注意一下;如果是在报表上直接添加参数,那就根据实际情况添加对应的类型的报表参数就可以。本文已直连数据集为例进行对应的内容讲解。
1)报表的数据准备中选择直连数据集,设置2个日期类型的参数,如下图示:
image.png929454040.png
2)将对应的参数设置给数据集(使用数据过滤器)或者使用自定义sql使用这2个参数,本例使用的是方法2。
方法1:数据过滤器
image.png695217284.png
方法2:自定义sql使用参数
image.png815492858.png
接下来看看对应的报表样子,这种类型的报表一看就需要使用列分组来实现,所以组件定位就是矩表组件,在报表设计中我们首选矩表组件。后面在根据对应的实际需求编写对应的表达式来实现对应的计算就可以。


步骤3:设计报表。通过步骤一和步骤二,我们的数据准备和对应的分析已经结束,接下来就是对应的报表详细设计阶段。
打开报表设计器,因为该报表没有什么特殊之处,所以我们首选“RDL报表”,针对rdl报表和页面报表的区别,大家可以参考这篇帖子进行对应的知识学习。
1)选择完报表类型后,进入报表设计器界面,首先先新加数据集,这里选择已创建好的数据集,参考下图:
image.png98764037.png
2)选择矩表组件,开始报表设计,当有数据集时,系统默认开启矩表向导,所以我们可以使用矩表向导做最初的矩表设计,这样在后面设计时就会很灵活:
image.png754071044.png
3)给矩表绑定数据,根据实际的报表样子绑定对应的数据字段,使用表达式设置某些特殊的值。
image.png799933471.png
这里有几个特殊点需要给大家说明一下:
a):矩表行分组不允许单元格的合并,所以打卡情况后的两列的行上我只写了一个,其余的行我是用单元格的线条隐藏多余线条,然后将对应的文本框内容置地显示。
image.png907519836.png
b):列分组的迟到早退,因为只需要看到迟到和早退,所以在列分组上我添加了过滤条件。
image.png51149291.png
c):实际出勤天数中使用了自定义函数,这里的需求如下,直接在报表中使用表达式过于复杂,这里推荐自定义函数功能:
image.png563098449.png
这里针对自定义函数不多说了,大家编写好对应的自定义函数后,放入系统后台的报表设置自定义函数中,这里记得上传代码后一定要点击编译,然后在点击保存按钮。保存后在报表中就可以使用Code.自定义函数名称来进行对应的使用。
image.png910450439.png

//迟到
  public int CalculateLateDuration(DateTime actualStartTime, DateTime normalStartTime,string leaveCategory)
    {
        if (!string.IsNullOrEmpty(leaveCategory))
        {
            return TimeSpan.Zero.Minutes; // 请假类别不为空,迟到为空
        }
        if (actualStartTime > normalStartTime && actualStartTime <= new DateTime(actualStartTime.Year, actualStartTime.Month, actualStartTime.Day, 12, 0, 0))
        {
            return (actualStartTime - normalStartTime).Minutes; // 8:00:00 < 实际上班时间 <= 12:00:00
        }
        else if (actualStartTime > new DateTime(actualStartTime.Year, actualStartTime.Month, actualStartTime.Day, 12, 0, 0) && actualStartTime < new DateTime(actualStartTime.Year, actualStartTime.Month, actualStartTime.Day, 13, 0, 0))
        {
            DateTime todayNoon = new DateTime(actualStartTime.Year, actualStartTime.Month, actualStartTime.Day, 12, 0, 0);
            return (todayNoon - normalStartTime).Minutes; // 12:00:00 < 实际上班时间 < 13:00:00
        }
        else if (actualStartTime >= new DateTime(actualStartTime.Year, actualStartTime.Month, actualStartTime.Day, 13, 0, 0) && actualStartTime < normalStartTime)
        {
           return (new TimeSpan(4, 0, 0) + (actualStartTime - new DateTime(actualStartTime.Year, actualStartTime.Month, actualStartTime.Day, 13, 0, 0))).Minutes; // 13:00:00 <= 实际上班时间 < 正常上班时间
        }

        return  TimeSpan.Zero.Minutes; // 其他情况迟到为空
    }

//早到
  public int CalculateEarlyDuration(DateTime actualEndTime , DateTime normalEndTime,string leaveCategory)
    {
       if (!string.IsNullOrEmpty(leaveCategory))
        {
            return TimeSpan.Zero.Minutes; // 请假类别不为空,迟到为空
        }
       if (actualEndTime > normalEndTime && actualEndTime <= new DateTime(actualEndTime.Year, actualEndTime.Month, actualEndTime.Day, 12, 0, 0))
        {
            DateTime todayNoon = new DateTime(actualEndTime.Year, actualEndTime.Month, actualEndTime.Day, 12, 0, 0);
            return (todayNoon - actualEndTime + new TimeSpan(4, 0, 0)).Minutes; // 8:00:00 < 实际下班时间 <= 12:00:00
        }
        else if (actualEndTime > new DateTime(actualEndTime.Year, actualEndTime.Month, actualEndTime.Day, 12, 0, 0) && actualEndTime < new DateTime(actualEndTime.Year, actualEndTime.Month, actualEndTime.Day, 13, 0, 0))
        {
            DateTime todayNoon = new DateTime(actualEndTime.Year, actualEndTime.Month, actualEndTime.Day, 13, 0, 0);
            return (normalEndTime - todayNoon).Minutes; // 12:00:00 < 实际下班时间 < 13:00:00
        }
        else if (actualEndTime >= new DateTime(actualEndTime.Year, actualEndTime.Month, actualEndTime.Day, 13, 0, 0) && actualEndTime < normalEndTime)
        {
            return (normalEndTime - actualEndTime).Minutes; // 13:00:00 <= 实际下班时间 < 正常下班时间
        }

        return  TimeSpan.Zero.Minutes; // 其他情况迟到为空
    }

最后该报表就完成了对应的设计,如果还有新的需求,可以继续在这个模版的基础上进行对应的修改和添加,记得一定要根据实际需求来实现,附件是对应的模版,大家也可以参考实现看看。
wyn-export-20240204142424.zip (13.81 KB, 下载次数: 397)

0 个回复

您需要登录后才可以回帖 登录 | 立即注册
返回顶部