数据一般都具有天然的时间属性,在很多业务中,以自然月为周期进行数据统计、分析和展示非常普遍。例如,在人事系统中查看某个月的考勤信息、销售人员查看自己或者部门的日程安排等。这些情况下,将报表以日历形式进行展示,往往具有更加直观的展示效果。

下面,我们将通过一个常见的考勤报表的制作,说明如何制作这些日历形式的报表。先看一下报表应有的展示效果:

该报表以日历形式清晰、直观地展示了 3 月份的人员出勤情况。下面介绍下该报表的制作方法。

在润乾报表中,制作日历类报表主要的操作是通过 to 函数实现一个交叉报表扩展出对应的行列,然后在想办法找到该月第一天是周几,这样后边的日期就能依次获取,至于日历最终用于考勤还是其他业务,只需要将实际业务中的日期字段和日历中的日期对应即可,下面看下详细的操作步骤。

一、日历格式制作

实际应用中需要动态传入月份,从而实现动态日历的设置,因此先在报表中增加一个参数 rq,值表达式默认为 2018-03

在一个自然月中,日期最多会跨六周,因此只需在单元格 A2 输入 =to(0,5),B1 单元格输入 =to(1,7),并且将 B1 单元格的扩展方向设置成横向扩展,然后将 A 列隐藏。

这样报表展现时就会纵向扩展出 6 行,横向扩展出 7 列。

在 B2 单元格表达式中写入 =A2*7+B1, 此时报表预览结果如下:

大家知道,每个月的第一天有可能是一周中的任何一天,以 2018-03-01 为例,该日为周四,所以日历展示时,1 号要展示在周四处,也就是上图红框中的“5”的位置(国际日历中,第一列为周日),简单来看就是将上图中的日期 -4 即可,接下来看下这个 4 是怎么动态获取的。

润乾函数中有个时间日期函数 day,通过该函数可以获取某个日期在该月中是几号,使用时可以增加 w 参数,即 day@w,可以获取某个日期是一个星期中的第几天,先用 rq+”-01”字符串拼接成一个日期格式字符串,再用 date 函数对其进行日期格式转换 date(rq+“-01”),这样 day@w(date(rq+“-01”)) 就能够获取该月 1 号是一个星期中的第几天,因为是国际日历,如果是周日则返回 1,周一则返回 2,所以如果是周四的话,day@w(date(rq+“-01”)) 返回的值是 5,要取得想要的 4 则在该值的基础上减 1 即可。

还有一种可能,如果 1 号恰好是周日的话,之前纵向扩展时是 0 到 5 扩展出了 6 行,日历中通常 1 号为周日的话是放在日历的第二行,所以要进行 1 号是否是周日的判断,如果是则在第二行显示(值 -7),最终 B2 单元格表达式为:

=A2*7+B1-if(day@w(date(rq+“-01”))==1,7,day@w(date(rq+“-01”))-1)

也就是在原有生成连续日期的基础上减去当月第一天处于该周中第几天,预览结果如下:

可以看到 1 号目前显示在了周四的位置。

ps:day@w 函数返回日期所在该周的第几天,周日返回 1.

做为日历,第一行展示时要显示成中文,并且是从周日开始显示,在 B1 单元格显示值表达式写入:map(to(1,7),list(“星期日”,“星期一”,“星期二”,“星期三”,“星期四”,“星期五”,“星期六”))

另外,由于交叉区域扩展出来 6*7(42)个单元格,而一个月为 30 天左右,所以会有负数(上个月)以及大于当前月最大值的数。这些值在展示时是不需要的,可以通过表达式将不需要数据隐藏掉,在 B2 单元格显示值表达式中写入:if(value()<1||value()>days((date(rq+“-01”))),"",value())

A2 中扩展出 6 行数据,实际中该月可能会横跨四周到 5 周,所以同样要将不需要数据给隐藏掉,判断规则:

如果在第五行第一天的日期超过了该月天数,那么其他几天肯定也超过最大天数了,这行数据就需要隐藏,或者如果日期在扩展的第一行中,并且该行最后那天日期 <1 的话,那么该行也需要隐藏,所以在 B2 单元格隐藏行表达式中写入:if(A2>=4 and B1==1 and value()>days((date(rq+“-01”))),true,if(A2==0 and B1==7 and value()<1,true,false))

这样报表就展示成如下日历格式:

二、考勤数据如何结合日历报表

接下来看一下考勤数据如何放到日历中显示。

考勤数据通常会有两个字段,一个为考勤日期,另一个为出勤情况,如下述数据集:

数据集中有两列数据,rq 为考核日期,sfcq:是否出勤,1:出勤,0:缺勤

在上述制作好的报表基础上将 A2 和 A3 单元格合并,在 B3 单元格中输入表达式:=ds1.select(sfcq,day(rq)==B2)

B2 单元格为日历的天,day(rq) 含义取 rq 字段的日,这样将这个做为过滤条件就能从 ds1 数据集中取出该天的出勤情况。

展示时要展示成中文,在 B3 单元格显示值表达式中写入:if(value()==“1”,“出勤”,if(B1==1 or B1==7,"",“缺勤”)),当数据库中字段的值为 1 时代表出勤,并且当 B1 等于 1 或者 7 时,表示周末,不参与考勤评定,其余日期为空的同样算缺勤。

再调整边框样式,主要 B2、B3 单元格展示时,要将日期和出勤情况展示成一个单元格内,所以 B2 和 B3 单元格中间的边框设成不显示。

报表展现时,为了更加醒目的显示哪些日期没有出勤,可以设置成如果缺勤则字体变成橙色展示,在 B3 单元格的前景色表达式中写入:if(value()!=“1”,-32768,-16777216),通常情况下,周末的日期以红色展示,所以在 B2 单元格前景色表达式中写入:if(B1==1 or B1==7,-65536,-16777216)。

在之前 B2 单元格隐藏行表达式中动态控制哪些行隐藏,因为报表增加了 B3 单元格,所以要在 B3 中要做同样控制,在 B3 单元格隐藏行表达式中写入:

if(A2>=4 and B1==1 and B2>days((date(rq+“-01”))),true,if(A2==0 and B1==7 and B2<1,true,false))。

报表中可增加一行用于展示当前月份信息,在报表上方插入行,将 A1、B1 合并,单元格中写入表达式:=string(date(rq+“-01”),“yyyy 年 MM”)+“月份出勤统计”

剩余进行样式调整,根据实际需要设置报表前景色、背景色、边框样式等,这样考勤报表就制作完成了。

最终报表展现结果如下:

总结:本例中通过单元格扩展以及日期函数的使用,实现了报表的灵活定制,使之以日历形式展示,并且能够在日历中显示考勤等信息。实际应用中同样可显示其他信息,只需要将日期字段和日历中的日期做关联即可,并且该报表还可和其他报表或业务系统联动,比如日历中可显示技术部门每天处理的任务数,结合报表的超链接功能,点击任务数就能够跳转到任务列表中查看具体的任务信息,等等。

作者:gxy
链接:http://c.raqsoft.com.cn/article/1540824028843?r=IBelieve
来源:乾学院
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

日历类报表可以这样实现相关推荐

  1. Python Qt GUI设计:QCalendar日历类和QDateTimeEdit时间类(基础篇—20)

    目录 1.QCalendar日历类 2.QDateTimeEdit时间类 1.QCalendar日历类 QCalendar是一个日历控件,它提供了一个基于月份的视图,允许用户通过鼠标或键盘选择日期,默 ...

  2. ActiveReports 报表应用教程 (2)---清单类报表

    在大多报表系统中都有清单类报表的身影,比如:客户清单.商品信息清单.设备清单.物品采购清单.记账凭证.货品发货清单.员工清单等等.清单类报表看视乎比较简单,但是,由清单类报表演变而来的报表类型却十分丰 ...

  3. Java的知识点22——时间处理相关类、Date时间类(java.util.Date)、DateFormat类和SimpleDateFormat类、Calendar日历类

    时间处理相关类 用long类型的变量来表示时间,获得现在时刻的"时刻数值":long now = System.currentTimeMillis(); Date时间类(java. ...

  4. 【Java Calendar日历类】可视化日历程序(控制台输出)

    Calendar日历类 Calendar 类是一个抽象类,为我们提供了关于日期计算的相关功能,比如:年.月.日.时.分.秒的展示和计算. GregorianCalendar 是 Calendar 的一 ...

  5. Calendar是日历类

    Calendar是日历类,在Date后出现,替换掉了许多Date的方法.该类将所有可能用到的时间信息封装为静态成员变量,方便获取. Calendar为抽象类,由于语言敏感性,Calendar类在创建对 ...

  6. 模板库 | 销售管理类报表,邀您提反馈

    "葡萄城报表模板库是一款免费的报表制作.学习和参考工具,包含了超过 200 张高质量报表模板,涵盖了 16 大行业和 50 多种报表类型,为 30 余万报表开发者提供价值参考." ...

  7. Calender日历类

    使用方法: @Testpublic void test() { // 调用其静态方法得到一个对象Calendar calendar = Calendar.getInstance();System.ou ...

  8. java日历类add方法_Java日历computeTime()方法及示例

    java日历类add方法 日历类computeTime()方法 (Calendar Class computeTime() method) computeTime() method is availa ...

  9. java日历类add方法_Java日历computeFields()方法及示例

    java日历类add方法 日历类的computeFields()方法 (Calendar Class computeFields() method) computeFields() method is ...

最新文章

  1. 【Hibernate步步为营】--双向关联一对一映射具体解释(一)
  2. ubuntu server安装php mysql_Ubuntu Server 下Apache+MySQL+PHP安装
  3. fcc认证_介绍fCC 100:我们对2019年杰出贡献者的年度总结
  4. Ruby笔记三(类、对象、属性)
  5. 使用UML工具分析类图与类的关系-bouml(java和C++)
  6. RtlZeroMemory
  7. 【测试理论】三、测试流程管理
  8. 实例分割: 一文读懂 E2EC (CVPR 2022)
  9. 创蓝253国际短信调用接口说明
  10. win10使用markdownpad2报错 An error occurred with the HTML rendering component. This issue may be fixed b
  11. mysql 高级查询总结_MySQL高级查询总结
  12. android4.2 拦截power键,Android 屏蔽Power键 Home键
  13. css实现人走路效果,如何使用纯CSS实现一个人独自行走的动画效果(附源码)
  14. wml 与服务器交互
  15. 算法设计与分析第七章分支限界算法(完结篇)
  16. 电子变压器的设计工艺重不重要?
  17. 编程:假设有n个人进行排名,允许并列排名,名次并列人的不同顺序算一种,总共有多少种排名?
  18. laravel5.2 银联支付
  19. 使用EJS脚本实现花生壳动态域名更新服务(一)
  20. netty 通道配置接口定义

热门文章

  1. 100个冷笑话,越往后越冷(郁闷时专用……)
  2. PIP生存记 | 10%强制淘汰率? Amazon好进,不好混。
  3. 太平洋电脑网论坛关闭了
  4. 编译报错:error: ro.build.fingerprint cannot exceed 91 bytes
  5. eBPF 如何简化服务网格
  6. 什么是Use Case?
  7. 国产化适配之人大金仓数据库(三)项目适配
  8. [转载]使用JDBC创建数据库对象
  9. 奉劝大家不要再用刷流量软件刷新浪博客等级了
  10. 极限钓鱼!FBI开发加密通讯设备并通过线人流入黑市,800多名罪犯被监控并抓捕...