文章目录
概要
博主接触FineReport帆软报表有一段时间了,正好前几天做了一个任务日历的需求,就是把每天完成的任务量直观的展示在日历上,方便管理者更好的监控各业务的完成情况。做完之后就想着和大家分享一下心得体会,项目整体效果如下图所示:
整体架构流程
项目整体使用 FineReport v11.0 里的决策报表和普通报表进行设计,其中报表数据集的编写可能涉及到数据库 SQL 语句,还有在报表中使用的相关函数。
技术名词解释
如果是刚接触帆软报表的同学可以点击下方链接,查看官方文档说明:
项目中所用到的部分函数:
- FORMAT(object,format)
返回object的format格式。 object:需要被格式化对象,可以是String,数字,Object(常用的有Date,Time)。
format:格式化的样式。
示例: FORMAT(1234.5,"#,##0.00")=>1,234.50 FORMAT(1234.5,"#,##0")=>1,234FORMAT(1234.5,"¥#,##0.00")=>¥1,234.50 FORMAT(1.5,"0%")=>150%
FORMAT(1.5,"0.000%")=>150.000% FORMAT(6789,"##0.0E0")=>6.789E3
FORMAT(6789,"0.00E00")=>6.79E03
FORMAT(date(2007,1,1),"EEEEE,MMMMMdd,yyyy")=>星期一,一月01,2007
FORMAT(date(2007,1,13),"MM/dd/yyyy")=>01/13/2007
FORMAT(date(2007,1,13),"M-d-yy")=>1-13-07
FORMAT(time(16,23,56),"h:mm:ssa")=>4:23:56下午
- TODAY()
获取当前日期。
示例:如果系统日期是2005年9月10日则TODAY()等于2005-09-10。
- MONTHDELTA(date,delta)
返回指定日期date后delta个月的日期。
示例: MONTHDELTA("2008-08-08",4)等于2008-12-08。
- DATEINMONTH(date,number)
函数返回在某一个月当中第几天的日期。
示例:DATEINMONTH("2008-08-08",20)等于2008-08-20。
DATEINMONTH("2008-08-08",-1)等于2008-08-31。
- DAY(serial_number)
返回日期中的日。DAY是介于1和31之间的一个数。 Serial_number:含有所求的年的日期.
备注:FineReport将日期保存为系列数,一个系列数代表一个与之匹配的日期,以方便用户对日期进行数值式计算。在1900年日期系统中,FineReport电子表格将1900年1月1日保存为系列数2,将1900年1月2日保存为系列数3,将1900年1月3日保存为系列数4......依此类推。如在1900年日期系统,1998年1月1日存为系列数35796。
示例:DAY("2000/1/1")等于1。 DAY("2006/05/05")等于5。 DAY("1997/04/20")等于20。
DAY("2000-1-1","yyyy-MM-dd")等于1。 DAY("2006-05-05","yyyy-MM-dd")等于5。
DAY("1997-04-20","yyyy-MM-dd")等于20。 DAY(35796)等于1。
- IF(boolean,number1/string1,number2/string2)
判断函数,boolean为true时返回第二个参数,为false时返回第三个。 boolean:用于判断的布尔值,true或者false。
number1/string1:第一个参数,如果boolean为true,返回这个值。
number2/string2:第二个参数,如果boolean为false,返回这个值。
示例:IF(true,2,8)等于2
IF(false,"first","second")等于second IF(true,"first",7)等于first
- WEEKDAY(Serial_number)
获取日期并返回星期数。返回值为介于0到6之间的某一整数,分别代表星期中的某一天(从星期日到星期六)。
Serial_number:输入的日期备注:FineReport将日期保存为系列数,一个系列数代表一个与之匹配的日期,以方便用户对日期进行数值式计算。在1900年日期系统中,FineReport电子表格将1900年1月1日保存为系列数2,将1900年1月2日保存为系列数3,将1900年1月3日保存为系列数4......依此类推。如在1900年日期系统,1998年1月1日存为系列数35796。
举例: WEEKDAY("2005/9/10")等于6(星期六)。 WEEKDAY("2005/9/11")等于0(星期日)。WEEKDAY(35796)等于4(星期四)。
- LEN(args)
返回文本串中的字符数或者数组的长度。需要注意的是:参数args为文本串时,空格也计为字符。参数args为数组时,直接返回数组长度。
示例:LEN("Evermore software")等于17。 LEN(" ")等于1。LEN(['a','b'])等于2。
- EVAL(exp)
返回表达式exp计算后的结果。 exp:一个表达式形式字符串。
备注:只要EVAL中的参数exp最终可以转化成一表达式形式的字符串,比如"sum(2,4)","2+7"等等,那么它就可以被计算。
示例:EVAL("2+5")等于7。 EVAL("count(2,3)")等于2。 EVAL("sum"+"(2,3,5)")等于10。
EVAL(IF(true,"sum","count")+"(1,2,3,4)")等于10。
EVAL(IF(false,"sum","count")+"(1,2,3,4)")等于4。
技术细节
-
添加模板参数
(1)点击"+"添加三个模板参数 a,b,c,参数名字可以按照大家习惯取,默认值分别设置为公式:
FORMAT(TODAY(), "yyyy-MM")
,FORMAT(MONTHDELTA(TODAY(),1), "yyyy-MM")
,FORMAT(MONTHDELTA(TODAY(),-1), "yyyy-MM")
,点击确定。
-
打开设计器后,在顶部的导航栏点击"文件"->"新建决策报表(F)",如下图所示:
-
随后点击"新建空白模板",如下图所示:
-
然后在空白模板上方的功能区找到新建Tab块(空白块->Tab块,鼠标放上去按住左键拖到下方空白处),如下图所示:
-
双击新建好的Tab块页面,进入编辑设计,然后点击上面的"+"添加标题,如下图所示:
-
拖动"新建Tab块"的旁边功能按钮为每个Tab块添加"报表块",其它几个Tab块同样的操作,如下图所示:
-
双击"报表块",进入报表设计页面,页面设计参考图如下:
将不需要显示的行和列进行隐藏后,最后界面如下:
-
在页面合适位置合并几列单元格用来放年月,然后点击合并后的单元格插入公式:
$a
,如下图所示:
-
在年月的左边,我们要设置点击切换到上月的超级链接,如下图所示:
-
点击编辑进行"条件属性"设置,其中"背景"设置为图片:
-
"超级链接类型"设置为"动态参数":
参数 | 值 |
---|---|
a | $c |
c | FORMAT(MONTHDELTA($c+"-"+"01",-1), "yyyy-MM") |
b | FORMAT(MONTHDELTA($c+"-"+"01",1), "yyyy-MM") |
切换下月同理(参考step 9-step 12),只不过将右边单元格的超级链接参数和值改成下表:
参数 | 值 |
---|---|
a | $b |
b | FORMAT(MONTHDELTA($b+"-"+"01",1), "yyyy-MM") |
c | FORMAT(MONTHDELTA($b+"-"+"01",-1), "yyyy-MM") |
-
在星期的上面添加一行,其中B4单元格插入公式:
DAY(DATEINMONTH((E2 + "-01"), -1))
。
右边放上周几对应的数字,方便计算日期:
-
在C7单元格插入公式:
IF(WEEKDAY(E2 + "-01") = 1, 1, "")
,这里的主要目的是根据当前月的1日是不是周一,是的话就显示"1",不是则显示为空。
D7单元格插入公式:
IF(LEN(C7) <> 0, C7 + 1, IF(WEEKDAY(E2 + "-01") = 2, 1, ""))
,目的同上。E7单元格插入公式:
IF(LEN(D7) <> 0, D7 + 1, IF(WEEKDAY(E2 + "-01") = 3, 1, ""))
,目的同上。F7单元格插入公式:
IF(LEN(E7) <> 0, E7 + 1, IF(WEEKDAY(E2 + "-01") = 4, 1, ""))
,目的同上。G7单元格插入公式:
IF(LEN(F7) <> 0, F7 + 1, IF(WEEKDAY(E2 + "-01") = 5, 1, ""))
,目的同上。H7单元格插入公式:
IF(LEN(G7) <> 0, G7 + 1, IF(WEEKDAY(E2 + "-01") = 6, 1, ""))
,目的同上。I7单元格插入公式:
IF(LEN(H7) <> 0, H7 + 1, IF(WEEKDAY(E2 + "-01") = 0, 1, ""))
,目的同上。 -
下面C8单元格插入公式:
format(IF(LEN(C7) = 0, "", eval("E" + "2") + "-" + C7), "yyyy-MM-dd")
,目的是计算C7对应的日期,因为下面任务计划全部要根据这个日期进行数据查询。
D8单元格插入公式:
format(IF(LEN(D7) = 0, "", eval("E" + "2") + "-" + D7), "yyyy-MM-dd")
,目的同上。E8单元格插入公式:
format(IF(LEN(E7) = 0, "", eval("E" + "2") + "-" + E7), "yyyy-MM-dd")
,目的同上。F8单元格插入公式:
format(IF(LEN(F7) = 0, "", eval("E" + "2") + "-" + F7), "yyyy-MM-dd")
,目的同上。G8单元格插入公式:
format(IF(LEN(G7) = 0, "", eval("E" + "2") + "-" + G7), "yyyy-MM-dd")
,目的同上。H8单元格插入公式:
format(IF(LEN(H7) = 0, "", eval("E" + "2") + "-" + H7), "yyyy-MM-dd")
,目的同上。I8单元格插入公式:
format(IF(LEN(I7) = 0, "", eval("E" + "2") + "-" + I7), "yyyy-MM-dd")
,目的同上。 -
然后添加你想要监控的任务指标,通过查询数据集结果,设置单元格属性和过滤条件(这里C9、C10、C11的过滤日期根据上面C8的值进行对应),目的让该单元格只显示当前日期的任务。其它的同理。
-
下面C12单元格插入公式:
eval("I" + "7") + C4
,目的是根据根据上一行的周日日期加上对应的时间间隔来计算这个日期。后面同理。
-
关键点来了,C27格开始,我们就要判断日期是否结束了,插入公式:
IF((eval("I" + "22") + C4) > eval("B" + "4"), "", (eval("I" + "22") + C4))
,其中C4单元格插入公式为:DAY(DATEINMONTH((E2 + "-01"), -1))
。后面的同理。 -
最后,给每个日期单元格增加一个条件属性,添加一个背景属性,其作用是当前日期显示颜色背景,然后公式条件如下:
FORMAT(E2 + "-" + $$$, "yyyy-MM-dd") = format(TODAY(), "yyyy-MM-dd")
。其它单元格同理。
小结
至此,一个工作日历已经初具雏形了。
最后,如果本篇文章对正在阅读的您有所帮助或启发,请不要吝啬您的点赞收藏评论及分享,这样就有可能帮助到更多的人了。同时也欢迎留下您遇到的问题,让我们一起探讨学习,共同进步!