历史版本2 :函数常见问题 返回文档
编辑时间: 内容长度:图片数:目录数: 修改原因:

目录:

1. 概述编辑

在 FineReport 产品中提供了多种函数以便于满足用户在日常使用中的需求,同时拥有 公式不合法报错 的功能,本文主要介绍函数在使用过程中常见的问题及解决方案。

2. 日期函数编辑

2.1 日期公式组合

2.1.1 往前推三个工作日

问题描述

往前推三个工作日,比如现在周五,得到周三,周六和周日也是得到周三,也就是不计算周末(无法跳过节假日)

解决方案

datedelta(today(), 0 - indexof('5552224', weekday(today())))

2.1.2 获取当年第一天

解决方案

format(CONCATENATE(CONCATENATE(year(now()),"01"),"01"),"yyyy-MM-dd")

2.1.3 获取上个月今天

解决方案

format(MONTHDELTA(now(),-1),"yyyy-MM-dd")

2.1.4 获取参数上一年的指定日期

解决方案

FORMAT(date(year($riqi)-1,month($riqi),25),"yyyy-MM-dd")

2.2 日历模板

问题描述

选择具体月份,显示对应日期和星期

解决方案

获取日期:RANGE(1, DAYSOFMONTH($月份 + "-01"))

获取日期对应的星期:SWITCH(WEEKDAY($月份 + "-" + FORMAT(A5, "00")), "1", "一", "2", "二", "3", "三", "4", "四", "5", "五", "6", "六", "0", "日")

2.3 给当前系统时间加8个小时

解决方案

format(year(today()) + "-" + month(today()) + "-" + day(today()) + " " + (HOUR(now(), "HH:mm:ss") + 8) + ":" + 
MINUTE(now(), "HH:mm:ss") + ":" + SECOND(now(), "HH:mm:ss"), "yyyy-MM-dd HH:mm:ss")

2.4 today()公式的显示问题

问题描述

填报预览模式下,单元格放一个日期控件,设置格式是yyyy-MM-dd,单元格写公式today(),预览格式是正常的,编辑之后格式又变成了时间类型的。

解决方案

单元格显示内容需要在样式」处单独设置。

2.5 TODATE()函数

2.5.1 TODATE()的起始日期

问题描述

todate(0)的返回结果是1970-01-01 08:00:00。如何更改?

解决方案

DATETONUMBER(date):返回自 1970 年 1 月 1 日 00:00:00 GMT 经过的毫秒数。时区问题,改成经纬度0的时区重启电脑。

2.5.2 TODATE()函数显示空白

问题描述

TODATE('2020/4/10', 'mm/dd/yy')单元格公式输入后预览最新的JAR显示为空白。10.0-2019.07.03版本以及之前JAR显示正常。

解决方案

最近版本改了逻辑:就是参数不匹配出错的时候返回空 ,之前参数不匹配是返回当前时间。函数的详细使用可参见:TODATE() 函数

2.6 week()函数

问题描述

week(today())计算在百度上4.13是第16周,使用内置的函数是15周,开始的比百度上面的晚一周。

解决方案

目前的规则师按照国际标准来的,所以目前做不了兼容。

2.7 日期控件默认值写today取到昨天

问题描述

远程设计时,日期控件写默认值today函数,不管类型选什么,都取到昨天;文本控件写today或者now都可以取到今天;linux服务器系统时间和硬件时间都是今天。

解决方案

模板请求的响应内容里搜下 date_milliseconds ,然后在前端执行浏览器 console 那边执行 new Date(上一步的值), 这个结果跟日期控件是一致的即可。

2.8 now()公式的时间不对

问题描述

本地环境是对的,远程环境不对。

原因分析

docker部署的工程,docker中镜像的系统时间存在问题。

解决方案

修改部署 FineReport 的镜像中的时间即可。

2.9 yyyy-MM格式的日期求月份差值

问题描述

start 是开始日期控件名,end 是结束日期控件名,两个日期控件格式都是 yyyy-MM。

解决方案

(year(format($end,"yyyy-MM-dd"))-year(format($start,"yyyy-MM-dd")))*12+(month(format($end,"yyyy-MM-dd"))-month(format($start,"yyyy-MM-dd")))

2.10 today+1-”08:00:00“无法识别

问题描述

使用模板参数,模板参数识别控件的值减去八个小时,today+1-”08:00:00“无法识别

解决方案

设置两个模板参数,定义公式不要写8:00:00

3. 数字编辑

3.1 数字公式组合

3.1.1 判断小数位数

解决方案

假如A1是小数所在单元格,LEN(A1)-FIND(".",A1,1)

3.1.2 取绝对值最大的数组里的数据

解决方案

max(split(replace(ds1.select(1),"-",""),","))

3.1.3 获取最小值但是不包括0

解决方案

INDEXOFARRAY(SORTARRAY(GREPARRAY(C2[!0], index!= 0)),1)

3.1.4 判断是不是小数

解决方案

$$$-trunc($$$)>0

3.2 最小值

问题描述

A1:D1的单元格手填的值为23、4、65、1,可以使用min(A1:D1)获取最小值1,如果某个单元格为空,这个方法返回的值是0

解决方案

min(GREPARRAY(array(a1),len(item)!=0),
GREPARRAY(array(b1),len(item)!=0),
GREPARRAY(array(c1),len(item)!=0),
GREPARRAY(array(d1),len(item)!=0)
)

3.3 find函数16位以上识别不准确

问题描述

使用ds1.find函数识别位数超过16位时,位数不准确

解决方案

所有计算类函数精度都只支持到16位

3.4 判断单元格内容是否是纯数字

解决方案

先提取字符串中的数字,然后和原字符串比较长度,长度一致返回true,代表纯数字,不一致false,代表非纯数字

len(JOINARRAY(GREPARRAY(split(A1, ""), regexp(item, "[0-9]")), "")) = len(A1)

3.5 去掉小数位后面的0

解决方案

比如数据88.98705670000,希望转换成88.9870567,使用:format("88.98705670000","#0.################")

4. 字符串编辑

4.1 去掉真实姓名参数中的(用户名)

解决方案

left($fine_display_name, find("(", $fine_display_name) - 1)

4.2 单元格公式拼接参数和字符串,参数为空时,固定值也无法显示

问题描述

参数本身格式是数组,单元格用公式获取参数,并且拼接其他固定字符串。如果参数为空,整个单元格都会显示空白。场景如下拉复选框返回值为数组格式时,单元格内固定值预览不显示

原因分析

字符串+数组 的运算采用的映射运算,比如"AA"+数组(1,2)=数组(AA1,AA2)。

内部逻辑是:先根据与之相加的数组的长度属性把"AA"转成数组(AA,AA)然后与数组(1,2)进行映射。

这个逻辑就会导致如果数组是空数组,那么第一步字符串转数组就除了问题,因为数组长度为0,塞不进去

解决方案

参数为数组时,单元格公式改为判断, if(len($参数)==0,"",$参数)。或者用数组公式处理,将参数转换为字符串。

4.3 公式对于0开头的字符串匹配

问题描述

IF('000'=='00F','相等','不相等')公式正常结果应该是不相等,实际结果确是相等

解决方案

0是比较特殊,可以使用IF(exact("000","00F"),"相等","不相等")公式,exact()函数替代。