计算公式 ~~v4.5

计算公式是 REBUILD 自动化的核心能力之一。它能实现复杂的数据加工处理,如拼接截取文字、计算日期、条件分支逻辑,甚至调用 AI、请求外部接口、执行 SQL 查询。在 字段更新数据校验 等功能中都会用到,编写方式一致,但请注意不同功能对公式返回值的要求不同。

计算公式要求你具备一定的编程基础,否则可能无法顺利进行

基础

计算公式底层使用 Aviator 脚本语言实现,因此你可以编写任何符合 Aviator 语法的代码来实现业务需求。在开始使用前我们强烈建议你首先阅读 Aviator 文档,了解基本写法,尤其是 函数库列表 章节,高阶使用还会涉及 if 条件for 循环 等。

基本写法

先看一个简单的例子,以下计算公式取字段订单日期 orderDate,并加 10(天)后返回。

{orderDate} + 10

再看一个稍微复杂点的例子,以下计算公式取出字段订单日期 orderDate,如果订单日期为空则使用当前日期,然后加 10(天)后返回。

## 在本例中,由于是多行公式,所以需要使用 `;` `return` 完整语法,如是单行脚本则可以忽略
let date = {orderDate};
if (ISNULL(date)) {
  date = CURRENTDATE();
}
return date + 10;

对于有一定编程基础的用户,相信对上述计算公式并不会感到陌生。我们用到了逻辑判断 if 条件,以及 ISNULL CURRENTDATE 函数(详见下文),接下来让我们继续学习。

字段变量

在计算公式中,可以使用字段变量获取字段值,字段变量通过 {} 包裹,在公式执行时系统会将其替换为实际的字段值。例如下面的公式用于计算订单的到期时间。

## 获取订单日期,并调用 DATEADD 函数加 1 年后返回
let date = {orderDate};
return DATEADD(date, 1, 'Y');

字段变量值说明

为保持最大兼容性,系统对字段变量值进行了一些处理。在编写公式前请务必阅读以下说明:

  • 数字(小数、整数)、布尔字段会保持值类型,其他字段变量值均处理为字符串(包括日期等)
  • 若字段变量值为空,对于数字(小数、整数)字段将处理为数字 0,对于非数字字段将处理为空字符串 ''。因此对于字段值的空值判断应为 if {ziduan} == ''if {ziduan} == 0,而非 if {ziduan} == nil。我们推荐你使用 ISNULL 函数来判断空值,较为方便
  • 多选型字段(标签、多选)会处理为文本值(多值使用 , 分隔,如 AAA, BBB
  • 引用型字段(下拉列表、分类、引用、任意引用)会处理为 ID(20 位 Hash 字符串),如需获取文本值可使用 TEXT 函数进行转换
  • 多引用字段较为特殊
    • 如果目标字段也是多引用,则输出为 ID 字符串(, 分隔),
    • 否则输出为名称字段文本(, 分隔),如果你想保持为 ID 可以通过点连接主键字段如 {duoyinyong.AccountId}

引用字段点连接

对于引用字段可以使用 点连接 以便获取引用记录的数据。在计算公式中,多引用字段也支持点连接(用法与引用字段相同),需要注意的是,多引用字段返回的是一个数组,获取之后通常配合 for 循环 使用。

多引用字段点连接仅在 字段更新 触发器中可用

目标记录字段变量

在触发器的计算公式中,还可以使用 {^字段名} 引用目标记录的字段值。在字段名前加 ^ 前缀表示该变量取值于目标记录而非源记录,常用于需要基于目标记录已有值进行计算的场景。

目标记录字段变量仅在 字段更新 触发器中可用

可用函数

在函数语法中,$XXX 表示参数(可以是字段变量或是具体值),如果使用 [] 包裹则表示该参数为可选。同时注意函数名区分大小写、字段使用 {} 包裹、字符(串)使用引号包裹、数字无需包裹。

你可以将函数结果随意更新到一个文本字段,以便观察执行效果

文本与转换

TEXT

  • 作用:转换 ID(字段)值为文本。其中 ID 可以是 引用多引用任意引用(V4.1)、下拉列表分类 字段(值)
  • 语法:TEXT($ID, [$DEFAULT])
    • $ID 表示 ID,可以是 ID 字段,也可以是具体的 ID 值,例如 837-018c2f7fa58e03f8
    • $DEFAULT 当无法找到文本时使用的默认值(可选)
  • 示例:TEXT({id}) TEXT({id}, '没有值')

ID

  • 作用:转换文本(字段)值为 ID。其中文本可以是业务实体的 自动编号名称字段(值),如匹配到多个仅返回第一个
  • 语法:ID($TEXT, $ENTITY)
    • $TEXT 表示文本,可以是文本字段,也可以是具体的文本值,例如 锐昉科技
    • $ENTITY 实体内部标识,表示在哪个实体中查找
  • 示例:ID({no}, 'SalesOrder')

TOSTR ~~v4.2

  • 作用:转换任何对象为文本
  • 语法:TOSTR($OBJECT)
    • $OBJECT 任何对象
  • 示例:TOSTR(CURRENTDATE())

CHINESEYUAN

  • 作用:转换数字(字段)为人民币大写
  • 语法:CHINESEYUAN($NUMBER)
    • $NUMBER 数字,可以是数字字段,也可以是具体的数字值,例如 9800
  • 示例:CHINESEYUAN({jine}) CHINESEYUAN(123)

HANLPPINY ~~v3.9

  • 作用:转换中文为拼音(全拼或首字母)
  • 语法:HANLPPINY($STR, [$FIRST_CHAR])
    • $STR 中文字符,可以是字段或具体值,例如 锐昉科技
    • $FIRST_CHAR 指定为 true 表示返回首字母,否则返回全拼
  • 示例:HANLPPINY({kehuName}) HANLPPINY('锐昉科技')

空值处理

ISNULL

  • 作用:判断是否为空值(适用所有类型的字段)
  • 语法:ISNULL($VALUE)
    • $VALUE 要判断的值,可以是字段,也可以是具体的值
  • 示例:ISNULL({ziduan1}) ISNULL(0)

IFNULL ~~v4.4

  • 作用:给定值为空则返回默认值
  • 语法:IFNULL($VALUE, $DEFAULT)
    • $VALUE 要判断的值,可以是字段,也可以是具体的值
    • $DEFAULT 为空时返回的默认值
  • 示例:IFNULL({ziduan1}, '我是默认')

当前用户

CURRENTUSER

  • 作用:获取当前登录用户(ID)
  • 语法:CURRENTUSER()
  • 示例:CURRENTUSER()

CURRENTBIZUNIT

  • 作用:获取当前登录用户的所在部门(ID)
  • 语法:CURRENTBIZUNIT()
  • 示例:CURRENTBIZUNIT()

日期与时间

CURRENTDATE

  • 作用:获取当前日期(时间)
  • 语法:CURRENTDATE()
  • 示例:CURRENTDATE()

TODATE ~~v4.2

  • 作用:转换常用日期格式字符为日期对象
  • 语法:TODATE($STR)
    • $STR 常用日期格式,如 2020-01-012020/01/012020-01-01 00:00:00
  • 示例:TODATE('2025-10-20')

DATEADD

  • 作用:日期加,给定日期加上指定数量后返回新日期
  • 语法:DATEADD($DATE, $NUMBER, [$UNIT])
    • $DATE 日期,可以是日期字段,也可以是具体的日期值
    • $NUMBER 要加的数量,支持正负数
    • $UNIT 单位(可选,默认为 D)。I 表示分钟,H 表示小时,D 表示日,M 表示月,Y 表示年
  • 示例:DATEADD({riqi1}, 10) DATEADD({riqi1}, 1, 'Y') DATEADD({riqi1}, '2H')

DATESUB

  • 作用:日期减,给定日期减去指定数量后返回新日期
  • 语法:DATESUB($DATE, $NUMBER, [$UNIT])
    • $DATE 日期,可以是日期字段,也可以是具体的日期值
    • $NUMBER 要减的数量
    • $UNIT 单位(可选,默认为 D)。I 表示分钟,H 表示小时,D 表示日,M 表示月,Y 表示年
  • 示例:DATESUB({riqi1}, 10) DATESUB({riqi1}, 3, 'M')

DATEDIFF

  • 作用:计算两个日期之间的差值
  • 语法:DATEDIFF($DATE1, $DATE2, [$UNIT])
    • $DATE1 $DATE2 两个日期,可以是日期字段,也可以是具体的日期值
    • $UNIT 单位(可选,默认为 D)。S 表示秒,I 表示分钟,H 表示小时,D 表示日,M 表示月,Y 表示年
  • 示例:DATEDIFF({date1}, {date2}) DATEDIFF({date1}, {date2}, 'H') DATEDIFF({date1}, CURRENTDATE(), 'M')

DATEPICKAT

  • 作用:获取日期(时间)中的指定部分,得出新值(数字)
  • 语法:DATEPICKAT($DATE, [Y|Q|M|D|H|I|W])
    • $DATE 表示日期,可以是日期字段,也可以是具体的日期值,如 2021-01-01 2023-01-01 10:01:02
    • [Y|Q|M|D|H|I] 表示获取单位(可选,默认为 D)。Y 表示年,Q 表示季度,M 表示月,D 表示日,H 表示小时,I 表示分钟,W 表示周几(V3.6)
  • 示例:DATEPICKAT({riqi1}) DATEPICKAT({riqi1}, "Q")

CHINESEDATE ~~v4.5

  • 作用:将日期转换为中文日期格式或农历日期
  • 语法:CHINESEDATE($DATE, [$TRADITIONAL])
    • $DATE 日期,可以是日期字段,也可以是具体的日期值
    • $TRADITIONAL 是否返回农历日期(可选,默认 false
  • 示例:CHINESEDATE({riqi1}) CHINESEDATE({riqi1}, true)

OVERTIME ~~v4.5

  • 作用:计算两个时间点之间的加班时长(小时)
  • 语法:OVERTIME($STARTTIME, $ENDTIME, [$WORKSTART, $WORKEND])
    • $STARTTIME 开始时间
    • $ENDTIME 结束时间
    • $WORKSTART $WORKEND 上下班时间,默认 09:00 18:00(可选)
  • 示例:OVERTIME({kaishiTime}, {jieshuTime}) OVERTIME({kaishiTime}, {jieshuTime}, '08:30', '17:30')

工作日只计上下班时间之外的部分,周末和法定节假日只计上下班时间之内的部分(每天最多计一个班次),自动识别调休工作日

数据查询

SQLQUERY ~~v3.9

  • 作用:执行 SQL 查询,返回一个字段值
  • 语法:SQLQUERY($SQL, [$PARAM1, $PARAM2, $PARAM3, $PARAM4, $PARAM5])
    • $SQL SQL 语句。请注意此语句非原生 SQL,可参考 AJQL
    • $PARAM1 $PARAM2 $PARAM3 $PARAM4 $PARAM5 查询参数
    • 示例:SQLQUERY("select fieldName from EntityName where fieldName2 = 'value' and fieldName3 = ?", {fieldName4})
  • SQL 语句示例
    • fieldName from EntityName where fieldName2 = 'value' 其中 select 关键词不是必须的
    • fieldName1, fieldName2 from EntityName where fieldName2 = 'value' 注意 fieldName2 不会返回,因为仅支持查询一个字段,如需多个请使用 seqs 查询
    • fieldName1 from EntityName where fieldName2 = 'value' order by fieldName2 desc 通过 order by 指定排序规则
    • seq fieldName1 from EntityName where fieldName2 = 'value' 通过 seq 关键词可以查询多条记录的值,会返回一个一维数组/集合
    • seqs fieldName1, fieldName2 from EntityName where fieldName2 = 'value' 通过 seqs 关键词可以查询多条记录的多个值,会返回一个二维数组/集合

数组与集合

CONCATID ~~v3.9

  • 作用:连接多个 ID(字段)为 ID 数组。常用于将多个引用字段连接为一个 多引用 字段返回
  • 语法:CONCATID($ID1, $ID2, [$ID3, $ID4, $ID5])
    • $ID1 ID 字段,可以是引用/多引用字段,也可以是具体的 ID 值,例如 999-0000000000000001
    • $ID2 $ID3 $ID4 $ID5 同上
  • 示例:CONCATID({kehu1}, {kehu2})

CONCATARRAY ~~v3.9

  • 作用:连接多个(字段)为数组。虽然此函数接受任何参数,但更常用于将多个媒体类字段(如图片、附件)连接为一个 附件 字段返回,也可以将多个字段连接后进行更多逻辑处理。
  • 语法:CONCATARRAY($OBJ1, $OBJ2, [$OBJ3, $OBJ4, $OBJ5])
    • $OBJ1 任意字段或具体值
    • $OBJ2 $OBJ3 $OBJ4 $OBJ5 同上
  • 示例:CONCATARRAY({img1}, {file2})

关于数组/集合的使用方法,请参见 Aviator 数组和集合 以及 循环语句 帮助文档

文件处理

REPORT ~~v4.3

  • 作用:导出报表
  • 语法:REPORT($ID, $REPORTID, [$FORCEPDF, $UPLOADPATH])
    • $ID 记录 ID(同时支持 ID 数组)
    • $REPORTID 报表模板 ID
    • $FORCEPDF 是否输出为 PDF(可选)
    • $UPLOADPATH 是否上传并返回路径(否则返回文件对象),返回的路径可以放入 附件 字段(可选)
  • 示例:REPORT({AccountId}, '032-019c221026970002')
  • 示例:REPORT({AccountId}, '032-019c221026970002', true)

在某报表的 [预览] 按钮上右键点击"复制链接",链接后方的 ID 即为报表模板 ID,如 https://x.cn/admin/data/report-templates/preview?id=032-018e0cabba8b0001

ZIP ~~v4.3

  • 作用:打包压缩包
  • 语法:ZIP($FILENAME, $FILE1, [$FILE2, $FILE3, $FILE4, $FILE5])
    • $FILENAME 压缩包文件名称
    • $FILE1 $FILE2 $FILE3 $FILE4 $FILE5 要打包的文件,可以是媒体类字段(如图片、附件),或者是如通过 REPORT 导出的文件对象
  • 示例:ZIP('压缩包.zip', {WenJian1}, {WenJian2})

PDFMERGE ~~v4.3

  • 作用:将多个 PDF 文件合并为一个
  • 语法:PDFMERGE($FILENAME, $FILE1, [$FILE2, $FILE3, $FILE4, $FILE5])
    • $FILENAME PDF 文件名称
    • $FILE1 $FILE2 $FILE3 $FILE4 $FILE5 要合并的 PDF 文件,如果给定文件不是 PDF 则忽略
  • 示例:PDFMERGE('合并的.pdf', {Pdf1}, {Pdf2}, {Pdf3})

外部集成

LOCATIONDISTANCE

  • 作用:计算两个 位置(字段)的直线距离(米)
  • 语法:LOCATIONDISTANCE($LOC1, $LOC2)
    • $LOC1 表示起始坐标,可以是位置字段,也可以是具体的坐标值,例如 123.1234567,321.12345678
    • $LOC2 表示结束坐标,可以是位置字段,也可以是具体的坐标值,例如 123.1234567,321.12345678
  • 示例:LOCATIONDISTANCE({qiyundi}, {mudidi}) LOCATIONDISTANCE({qiyundi}, {mudidi}) / 1000

REQUEST

  • 作用:请求给定 URL 以获取结果
  • 语法:REQUEST($URL, [$DEFAULT])
    • $URL 有效的请求地址,系统将从该地址获取结果
    • $DEFAULT 当无法获取结果时使用的默认值(可选)
  • 示例:REQUEST('http://xx/api/x?id=' + {id}, '')

AI 助手

AIASK ~~v4.4

  • 作用:向 AI 提问,AI 返回结果
  • 语法:AIASK($USERCONTENT, [$FILE, $PROMPT])
    • $USERCONTENT 提问内容
    • $FILE 文件(可选)
    • $PROMPT 提示词(可选)
  • 示例:AIASK('帮我分析一下这个文件', {File1})

其他

StringUtils

系统内置了一个字符处理工具集 StringUtils 用于常用文字处理,例如将字母转换为全大写 StringUtils.upperCase($TEXT),关于此工具集所提供的方法请 参见文档

Aviator 内置函数

Aviator 内置一些常用的处理函数,包括:

上述部分函数仅商业版本可用,如若不可用会提示 Function not found: XXX 错误

示例

以下示例覆盖常见的业务场景,供你参考。更多示例可参考 REBUILD 高级计算公式实战

拼接两个字段值

{ziduan1} + "和" + {ziduan2}

获取两个日期之间的小时数

DATEDIFF({date1}, {date2}, "H")

计算订单天数

DATEDIFF({date}, CURRENTDATE())

条件赋值

当字段 level 值为 A 时返回 优质客户,否则返回 普通客户

if {level} == 'A' {
  return '优质客户';
} else {
  return '普通客户';
}

空值处理

当字段 amount 为空时使用 0,并乘以折扣率:

IFNULL({amount}, 0) * {discount}

阶梯税率计算

金额大于 10000 税率 15%,否则 10%:

if {jine} > 10000 {
  return {jine} * 0.15;
} else {
  return {jine} * 0.10;
}

人民币大写

将金额字段转换为大写,常用于合同、收据等:

CHINESEYUAN({jine})

循环拼接

查询订单明细中的产品 ID,循环取出产品名称并拼接:

let ids = SQLQUERY('seq ProductId from SalesOrderItem where SalesOrderId=?', {dingdan.SalesOrderId});
let s = '';
for id in ids {
  s = s + TEXT(id) + ' / ';
}
return s;

常见问题

公式调试技巧

对于复杂公式,有时我们希望可以进行调试,但目前并无直接调试方法。这里提供一个技巧,即使用 throw 关键词抛出一个异常(系统会弹窗提示 throw 的内容),然后借助异常达到调试的效果。

let shuzu = SQLQUERY('seq ProductId from SalesOrderItem where SalesOrderId=?', {dingdan.SalesOrderId});
## 抛出异常,页面会弹出错误提示
throw '这是个数组吗:' + shuzu;

## 循环拼接成字符串
let s = '';
for id in shuzu {
  s = s + TEXT(id) + ' / ';
}
return s;

同时,你可以设定触发器的“附加过滤条件”限定触发器针对指定的记录生效,从而达到通过特定记录(例如一条测试数据)调试的目的。

公式执行报错怎么办

公式执行报错通常有以下几种原因:

  • 函数名错误:提示 Function not found: XXX,说明函数名拼写有误或该函数不可用(部分函数仅商业版支持)
  • 类型不匹配:如对字符串执行数学运算,需先用 TOSTRTODATE 等函数进行类型转换
  • 字段不存在:检查 {} 中的字段标识是否正确,区分大小写
  • 语法错误:多行公式需使用 ; 分隔语句并使用 return 返回结果

如果错误信息不够明确,可使用 throw 抛出中间变量的值来辅助排查

多行公式和单行公式有什么区别

单行公式可以直接写表达式,无需 return,系统自动将结果作为返回值。多行公式(包含 iffor 等)则需要用 ; 分隔语句,并使用 return 明确指定返回值。

公式中可以使用 Aviator 原生函数吗

可以。计算公式底层基于 Aviator 脚本引擎,Aviator 内置的 函数库 均可在公式中使用,如字符串处理、数学计算、集合操作等。REBUILD 在此基础上扩展了 TEXTISNULLCURRENTDATE 等业务相关函数。

该文档内容对你是否有帮助?没有
你也可以通过 社区群组 向我们反馈问题
更新时间 2026-09-06
目录