表达式
表达式是 Luck-Report 的计算核心,除最常见的表达式类型单元格外,条件属性、图片与二维码的数据来源、链接参数等处均可书写表达式。掌握表达式是制作复杂报表的前提。
基本语法
表达式支持的数据类型如下:
| 类型 | 说明 | 示例 |
|---|---|---|
| 数字 | 整数或小数 | 1、123、0.121331 |
| 字符串 | 单引号或双引号包裹 | "Luck-Report"、'教程' |
| 布尔值 | 只有 true 和 false | true |
| 空值 | null | null |
算术运算符:
| 运算符 | 说明 | 示例 |
|---|---|---|
| + | 数字求和;有一方是字符串时做连接 | 21 + 31 得 52;"值:" + 331 得 "值:331" |
| - | 求差 | 21 - 31 得 -10 |
| * | 求积 | 3 * 6 得 18 |
| / | 求商,除不尽保留 10 位小数 | 6 / 3 得 2 |
| % | 求余 | 5 % 3 得 2 |
比较运算符,多用于条件判断:
| 运算符 | 说明 | 示例 |
|---|---|---|
| == | 等于 | A1 == 100 |
| != | 不等于 | A1 != 100 |
| > | 大于 | A1 > 100 |
| >= | 大于等于 | A1 >= 100 |
| < | 小于 | A1 < 100 |
| <= | 小于等于 | A1 <= 100 |
| in | 值在集合中 | A1 in "1,2,3" |
| not in | 值不在集合中 | A1 not in "1,2,3" |
| like | 左值包含右值即为真 | A1 like '北京' |
多个条件用 and(&&)、or(||)连接。
变量定义与赋值
用 var 定义变量并在后续表达式中使用:
var 变量名 = 表达式规则要点:
var可省略,a = 100同样合法;- 行尾分号
;可省略; - 变量名以字母或中文开头,可含数字、下划线、中划线,支持中文;
- 单元格表达式中可写多条语句,自上而下依次执行,最终输出最后一条语句的值,而非按 return 结算;赋值语句不产生返回值,所以最后一条必须是普通表达式;
- 赋值表达式计算结果为
null时,不会覆盖变量的原有值。
表达式案例如下:
var a = 10
var b = a * 2
var c = a + b
c上面例子的输出为 30。变量赋值也可写在 if、case、三元表达式的块中(见下文)。
条件判断
三种形式:三元表达式、if、case。
三元表达式
结构为"条件 ? 真值 : 假值",条件部分可用 and/or 组合多个条件。

| 示例 | 说明 |
|---|---|
A1 > 1000 ? "正常值" : "低值" | A1 大于 1000 返回 "正常值",否则返回 "低值" |
A1 > 1000 and A1 < 20000 ? "正常值" : "修正值:" + (A1 + 100) | 条件不满足时返回拼接值,如 A1 为 2000 则返回 "修正值:2100" |
var a = A1 * 2A1 > 1000 ? "正常值:" + a : "低值" | 先定义变量,再在三元表达式中引用 |
if 判断
由一个 if 部分、若干可选的 else if 部分和一个可选的 else 部分构成,结构类似 Java/JavaScript。return 关键字与行尾分号均可省略。

| 示例 | 说明 |
|---|---|
if(A1 > 1000){return "正常值"} | 条件满足返回 "正常值",否则无输出 |
if(A1 > 1000){return "正常值"}else{"低值"} | else 块中的 return 同样可省略 |
if(A1 > 1000 and A1 < 20000){return "正常值:" + A1}else if(A1 > 20000 and A1 < 40000){return "超高值"}else{"低值"} | 组合条件与多重 else if 判断 |
if 块中可以先定义变量再返回:
if(A1 > 1000){
var s = ds1.sum(salary, month == 1)
"一月合计:" + s
}case 判断
case 用大括号包裹若干"条件 + 返回值",多组之间用逗号分隔,书写上比 if 更紧凑。return 关键字可省略。

| 示例 | 说明 |
|---|---|
case{A1 == 100 return "正常值",A1 > 100 and A1 < 1000 return '偏高'} | 两组条件分别返回不同值 |
case{A1 == 100 return "正常值",A1 > 100 and A1 < 1000 '偏高'} | 省略 return 的写法 |
case 没有默认分支:case 的每个分支都必须带条件,不支持 default/else。所有条件都不满足时单元格输出为空。如需默认值,改用带 else 的 if,或在 case 末尾加一个恒真条件兜底(如
1 == 1 return "默认值")。
单元格引用
单元格多数与数据绑定,运行时一个单元格往往展开为多个,因此引用规则以当前单元格为基准。引用方式就是直接写单元格名称。

在 D1 中输入 A1,由于 D1 是 A1 的子格且 A1 绑定的是分组数据,每个 D1 会取到其对应分组下 A1 的值:

若在 D1 中输入 B1,则取到的效果如下;输入 C1 时,则是取每个 D1 所在行的 C1 值:

如果目标单元格与当前单元格不在同一行或列,情况就不同了。下面的模板中,C2 的表达式引用 B1,两者不同行也不同列,但它们拥有共同的间接父格 A1(C2 的左父格是 B2,B2 的左父格是 A1),因此 C2 会取共同父格 A1 下所有 B1 的值:


多个值的输出:表达式取到多个值时,输出以 "," 分隔。
目标格取值原则:优先取与当前单元格同行或同列的目标格;不同行列时,取与当前单元格有共同父格的目标格(有共同上父格和共同左父格时取二者交集);没有共同父格时,取展开后的所有目标格。
仍以上面的模板为例,若 C2 中输入 C1,由于 C1 是 C2 的上父格,将直接取同列上父格的值:

再看一例,下面的模板中 B2 与 C1 既不同行列也无共同父格,因此 B2 会取到所有 C1 的值:


通过更改父格控制取值:调整当前单元格的上父格或左父格,可以改变它与目标格的父子关系,从而控制取值范围,这是报表计算模型中的常用手法。
单元格坐标
对于更复杂的引用场景,可用单元格坐标精确定位展开后的某个单元格。坐标同样基于当前单元格计算,格式如下:
单元格名称 [L左父格:序号,...;T上父格:序号,...]
L 部分约束左父格,T 部分约束上父格;序号为该父格展开后的位置,负值表示相对当前单元格向上位移,正值向下。只有左父格时直接写 L 部分;只有上父格时前面加分号 ";" 再写 T 部分。大括号中的条件可选,用于对坐标取到的多个单元格做进一步过滤,多条件间用 and/or 连接。
| 示例 | 说明 |
|---|---|
C1[A1:2,B1:1] | 先定位 A1 展开后的第 2 格,再定位其下 B1 展开后的第 1 格,取该 B1 对应的 C1 |
C2[A1:2,B1:2;C1:3] | 左父格定位到"第 2 个 A1 下的第 2 个 B1",上父格定位到 C1 展开后的第 3 格,取二者交集下的 C2 |
C2[A1:2,B2:2]{C2 > 1000} | 定位"第 2 个 A1 下第 2 个 B2"下的所有 C2,再过滤出值大于 1000 的 |
C2[A1:2,B2:2]{C2 > 1000 and C2 < 10000} | 同上,进一步限定值在 1000 到 10000 之间 |
具体示例,模板如下:

B2 中输入 C1[A1:2,B1:1],即取"第 2 个 A1 下第 1 个 B1"对应的 C1 值,运行效果:

在交叉表中,通过左父格与上父格的坐标约束可以定位到任意特定单元格。实际应用中,坐标常用于同比、环比类统计报表——用负数序号相对当前单元格位移,实现各种比值计算。
引用所有单元格:单元格名称后跟
[]表示引用展开后的全部值,如A1[]。还可加条件过滤,如A1[]{@ > 1000 and @ < 10000},其中@代表条件循环中当前遍历到的对象。
环比

D2 的表达式为 C2 - C2[A2:-1]:前一个 C2 与 D2 同行,直接取当前行的值;C2[A2:-1] 中的负序号表示取上一行 A2 对应的 C2,二者相减即环比:

第一行环比为 0,因为对首行 D2 来说上一行不存在,系统默认取了第一个 C2 的值。
同比

D2 的表达式为 C2 - C2[A2:-1]{B2==$B2}:先取当前行的 C2,再通过坐标 A2:-1 定位上一条 A2 记录下的 C2;由于其下 C2 仍有多个,加条件 B2==$B2 过滤——条件中的 B2 是当前单元格所在行的 B2 值,$B2 是坐标定位后目标 C2 对应的 B2 值,两者相等即月份相同,从而实现同比:

关于 $ 前缀:单元格名称前加
$表示取坐标定位后目标单元格所对应的单元格值,多用于条件比较,如C2[A2:-1]{B2==$B2}中的$B2。
第一个分组 2000 下同比值全为 0,因为该分组下不存在 A2:-1 坐标(无法上移),系统默认取了当前记录自身。若不想显示 0,可加 if 判断:位于第一组时输出空字符串,否则输出实际计算值。修改后的模板与表达式:



这里的 &A2 表示 A2 单元格展开后的序号。写成 if、三元或 case 均可。
关于 & 标记:
&单元格名称取目标单元格展开后的序号,要求当前单元格必须是目标单元格的子格或间接子格(如上例中 D2 是 A2 的间接子格)。此外,序号以共同父格为基准编排——有共同父格时,以该父格下目标格的数量编号,这一特性常用于明细型主从报表的从表编号。
逐层累加


当 &A2 为 1(首行)时取当前行 C2;否则取当前行 C2 加上一行的 D2 值,实现逐层累加(同样可换成三元或 case 判断):

数据集表达式
除了在设计器中双击数据集字段建立绑定,还可以直接在单元格表达式里书写数据集表达式:
数据集名称.聚合方式(字段名 [,条件] [,排序方式])聚合方式与属性面板中的聚合类型一致:select、group、customgroup、regroup、reselect、sum、avg、max、min、count。
字段名必须直接书写标识符,不能用引号包裹:
ds1.select(username)正确,ds1.select("username")会在解析阶段直接报错。字段名支持中文,如ds1.select(部门)。
select(罗列数据)
datasetName.select(propertyName,filter,order)filter 为过滤条件,多个条件用 and/or 连接;order 为排序方式,取 asc 或 desc。
| 示例 | 说明 |
|---|---|
ds1.select(username) | 取所有 username 值 |
ds1.select(username,age>18) | 取 age>18 的 username 值 |
ds1.select(username,age>18,desc) | 取 age>18 的 username 值并倒序 |
ds1.select(username,age>18 and age<60,asc) | 组合条件过滤后正序 |
group(分组罗列数据)
datasetName.group(propertyName,filter,order)参数含义与 select 相同,作用是对字段分组。字段值相同的行会合并为一组,常用于按分类、部门等维度汇总展示。
| 示例 | 说明 |
|---|---|
ds1.group(degree) | 对 degree 字段分组,学历相同的合并为一行 |
ds1.group(degree,age>18) | 对 age>18 的 degree 分组 |
ds1.group(degree,age>18,asc) | 分组后按 degree 正序 |
假设数据集中 degree 字段值为:初中、初中、初中、高中、高中,则 ds1.group(degree) 输出两行:初中、高中。
sum(累加)
datasetName.sum(propertyName,filter)目标字段必须是数字类型,否则报错。累加结果唯一,无需排序参数。
| 示例 | 说明 |
|---|---|
ds1.sum(salary) | salary 全量累加 |
ds1.sum(salary,age>30) | age>30 的 salary 累加 |
count(计数)
datasetName.count(filter)统计对象数量,无需字段名与排序。
| 示例 | 说明 |
|---|---|
ds1.count() | 统计对象总数 |
ds1.count(age>30) | 统计 age>30 的对象数 |
max / min(极值)
datasetName.max(propertyName,filter)
datasetName.min(propertyName,filter)结果唯一,无需排序参数。
| 示例 | 说明 |
|---|---|
ds1.max(salary) | salary 最大值 |
ds1.min(salary,age>30) | age>30 的 salary 最小值 |
avg(平均值)
datasetName.avg(propertyName,filter)除不尽时保留 8 位小数。
| 示例 | 说明 |
|---|---|
ds1.avg(salary) | salary 平均值 |
ds1.avg(salary,age>30) | age>30 的 salary 平均值 |
取当前单元格值
# 表示当前单元格自身的值。典型场景是配置链接时把当前值作为参数传递:

# 后接 . 和属性名可取当前单元格绑定对象的属性,如 #.id 取绑定对象的 id 值。当前单元格不是数据集类型时返回 null;绑定值有多个时只取第一个对象的属性值。