计算字段

概述

计算字段利用预设公式自动生成数据结果,覆盖前台新建、编辑保存、API 写入及数据批量导入全场景。典型应用包括:根据产品报价和折扣计算出货价、根据订单金额原币乘以汇率生成本位币金额等。

[!NOTE]
计算字段的计算结果不可手动修改。若需要在自动生成后允许二次编辑,请使用默认值公式

基础规格

属性 说明
适用场景 订单利润 = 金额 - 成本、汇率换算、日期推算等
返回值类型 数值、金额、百分比、日期、日期时间、时间、文本、布尔值
可插入字段 单选、单行文本、多行文本、时间、网址、布尔值、手机、数字、百分数、邮箱、人员、计算字段、统计字段
关联对象支持 支持查找关联对象的计算字段和统计字段;查找关联对象的统计字段需统计普通字段
导入数据 计算字段对导入的数据生效
函数支持 预设对象的计算字段和默认值设置公式时,支持插入函数

基础设置

在字段管理中新建计算字段时,需完成以下基础配置:

配置项 说明
字段名称 按业务要求自定义,不可与本对象下已有字段同名
API Name 系统自动生成,也可点击 AI 按钮生成翻译后的 API Name
备注信息 字段描述,仅在管理后台展示,前台不显示
帮助信息 支持悬停问号展示或外露展示(仅新建编辑页)
千分位显示 启用后,11111.00 在前台显示为 11,111.00(打印结果不显示千分位)
掩码显示 启用后可添加角色白名单,非白名单角色在列表页、详情页、新建编辑页看到的字段值显示为 **

计算公式配置

点击 计算设置 可配置返回值类型、计算公式以及空值处理方式。

返回值类型

返回值类型影响空值参与计算的行为:

  • 日期时间、日期、时间、文本、布尔:当其他计算字段、统计字段或验证规则引用该字段时,"公式中字段为空值时"的配置不生效,空值直接参与计算。空值参与数学运算或逻辑判断会导致报错,最终结果为空值。此时需要使用判空函数。
  • 数值、金额、百分比:系统根据"公式中字段为空值时"的配置决定是否将空值转换为 0 再参与计算。

小数位数

设置小数位数后,计算结果自动四舍五入到指定位数后写入数据库。例如小数位数设为 2,计算结果为 6.167,数据库存储和前端显示均为 6.17

基础模式与高级模式

  • 基础模式:仅可插入本对象的字段和全局变量。
  • 高级模式:可引用查找关联对象和主对象的字段(查找关联多选类型字段不支持)。关联对象中可选字段范围与本对象相同。

[!WARNING]

  • 在公式中配置关联对象的统计字段和相关对象的计算字段均为异步计算,结果可能存在延迟。
  • 公式中引用全局变量(当前日期、当前时间、当前日期时间)、人员对象字段或使用 NOW()TODAY() 函数时,该计算字段不支持被筛选、被其他统计字段或计算字段引用,也不支持被验证规则引用。

公式配置注意事项

  • 日期相减:配置"日期 1 - 日期 2"时,日期相减结果以小时为单位。若需以天为单位,需在公式中自行转换。
  • & 符号:在公式中会被转换为 + 号,不建议直接使用。如需在文本中展示 &,请配置一个文本类型的全局变量(值为 &),然后在公式中引用该全局变量。
  • CASE 函数:每个判断分支的返回类型必须一致。例如 CASE($field$, "一线城市", 60.5, "二线城市", 49.0, 0) 会报错,因为最后的 0 不带小数,需改为 0.0

空值处理方式

此配置仅对返回数值类型的字段可配置,返回非数值类型时字段空值始终按空值参与计算。

选项 行为
默认为零 返回类型为数值、金额、百分比时,公式中字段的空值按 0 处理;其他类型仍按空值参与
默认为空 返回类型为数值、金额、百分比时,公式中字段的空值保持为空

保存时的历史数据计算

点击编辑字段页面的 保存 时,若数据量超过 10,000 条,系统弹出提示:

选项 说明
现有数据不计算 仅对保存后新建或编辑的记录生效,不计算历史数据
全部计算 重新计算该对象下全部现存数据(数据量大时计算字段值在一段时间内为空)
符合以下数据范围计算 按需配置条件,仅对满足条件的数据进行计算

数据量不超过 10,000 条时不弹出提示,系统正常保存。

查看计算任务进度

新建或编辑计算字段后,列表页显示 计算任务执行情况 按钮。点击可查看任务状态、总数据量、已完成数据量和预计结束时间。

计算任务进度查询

对象数据试算

如果试算出现错误提示,计算字段没有值,大概率是以下原因:

  1. 计算公式中有字段的值是空值,但是没有默认为零也没有判空。
  2. 类型转换错误,文本转数字、文本转日期等,基本都是因为格式不正确。
  3. 如果是默认值或验证规则试算结果与数据提交时的结果不一致,请检查公式中的字段是否有过变化,尤其是公式中涉及计算字段和统计字段的,要检查级联到的字段是否有过变化,因为计算字段和统计字段的变化在修改记录中不记录。

AI 公式助手

计算字段支持利用 AI 自动生成计算公式:

  1. 新建计算字段时,进入 计算设置

新建计算字段

  1. 输入"/"或点击 AI 公式助手,唤起 AI 公式助手。

唤起 AI 公式助手

  1. 输入公式描述后,AI 公式助手自动生成公式。

AI 生成公式

  1. 点击 复制应用,使用 AI 生成的计算公式。

应用公式

函数参考

逻辑函数

函数 说明 示例
IF(logical_test, val_true, val_false) 参数个数:3;第一个为布尔类型,第二、三个必须为同一类型。条件为 true 返回第二个参数,否则返回第三个。支持嵌套。注意:IF 在计算时并非只算命中的分支,而是所有分支都计算一遍,所以不管哪个分支有错误(0 作除数、空值/文本参与逻辑运算、类型转换不对)都会导致公式报错计算失败 34 = IF(true, 34, 52)
CASE(expr, val1, res1, ..., else) 参数个数:不定;result(n)else_result 必须为同一类型。根据 expression 与 value(n) 比较,一致则返回对应 result(n),都不一致返回 else_result。最多支持 50 个 value 判断,超过保存报错 33 = CASE(3, 2, 2.0, 3, 33.0, 1.3)
NULLVALUE(expr, substitute) 参数个数:2;第一个参数判断是否为空,若空则返回第二个参数,否则返回原值。返回值类型为第二个参数的类型 1 = NULLVALUE(Null, 1)

数值函数

函数 说明 示例
+, -, *, / 参数个数:2;参数类型:数值、百分比、金额。进行加减乘除运算 6 = (3+2)*6/5
-(日期相减) 参数个数:2;均为日期,以为单位 a = 1982-04-13, b = 1982-03-20 → 24 = a - b
-(日期时间相减) 参数个数:2;均为日期时间,以小时为单位 a = 1982-04-13 17:00, b = 1982-04-12 15:00 → 26 = a - b
-(时间相减) 参数个数:2;均为时间,以小时为单位 a = 17:00, b = 15:00 → 2 = a - b
VALUE(string) 参数个数:1;文本类型。将文本形式的数字转化为数字,支持负数和小数,转化不成功返回空 -1982.04 = VALUE('-1982.04')Null = VALUE('aaa')
MIN(n1, n2) 参数个数:2;均为数值类型。返回两个参数中最小的一个 4 = MIN(4, 13)
MAX(n1, n2) 参数个数:2;均为数值类型。返回两个参数中最大的一个 13 = MAX(4, 13)
MIN(n1, n2, ...) 参数个数:不定;数值类型。返回所有参数的最小值。只要有一个参数为空则返回空 80 = MIN(100, 80, 120)
MAX(n1, n2, ...) 参数个数:不定;数值类型。返回所有参数的最大值。只要有一个参数为空则返回空 120 = MAX(100, 80, 120)
MULTIPLE(n1, n2) 乘法 52 = MULTIPLE(4, 13)
MOD(n1, n2) 取余 3 = MOD(13, 4)
ADDS(n1, n2) 加法 17 = ADDS(13, 4)
SUBTRACTS(n1, n2) 减法 9 = SUBTRACTS(13, 4)
ROUND(number, digits) 四舍五入 1.5 = ROUND(1.45, 1)
ROUNDDOWN(number, digits) 参数个数:2;数值。将 number 向下舍入到 digits 指定的小数位数,如果是负数则趋向零 1.4 = ROUNDDOWN(1.47, 1)
ABS(number) 绝对值 1.5 = ABS(-1.5)
EXP(number) e 的 n 次幂 2.718... = EXP(1)
SQRT(number) 正平方根 4 = SQRT(16)
LN(number) 自然对数 3.219 = LN(25)
LOG(number) 以 10 为底的对数 2 = LOG(100)
SIN(number) 正弦(弧度) 0.5 = SIN(PI()/6)
COS(number) 余弦(弧度) 0.5 = COS(PI()/3)
TAN(number) 正切(弧度) 1 = TAN(PI()/4)
ASIN(number) 反正弦(-1 到 1 之间) π/2 = ASIN(1)
ACOS(number) 反余弦(-1 到 1 之间) π/3 = ACOS(0.5)
ATAN(number) 反正切 π/4 = ATAN(1)
ATAN2(y, x) y/x 的反正切 π/4 = ATAN2(1, 1)
PI() 返回 π 3.14159... = PI()
LEN(text) 字符串长度 6 = LEN('xiaoke')
FIND(search, text [, start]) 参数个数:不定;文本、数值。返回 text 中 search 字符串出现的起始位置。注意:①可选参数 start 表示开始查找的位置,字符位置从 1 开始计数,未找到返回 0;②start 为空或小于 1 时从第 1 个字符开始查找,start 大于 text 长度时返回 0;③search 或 text 为空时返回 0;④start 输入小数时截断取整数位 1 = FIND("dog", "dog days and dog nights")

百分比运算符

函数 说明 示例
+, -, *, / 参数个数:2;参数类型:数值、百分比、金额。进行加减乘除运算,以百分比形式返回

日期提取函数

函数 说明 示例
YEAR(date) 参数个数:1;日期或日期时间类型。获取年份 1982 = YEAR(date)
MONTH(date) 参数个数:1;日期或日期时间类型。获取月份 4 = MONTH(date)
DAY(date) 参数个数:1;日期或日期时间类型。获取日期 13 = DAY(date)
HOUR(datetime) 参数个数:1;日期时间或时间类型。获取小时数 14 = HOUR(DATETIMEVALUE("2025-07-31 14:30:45"))
MINUTE(datetime) 参数个数:1;日期时间或时间类型。获取分钟数 30 = MINUTE(DATETIMEVALUE("2025-07-31 14:30:45"))
SECOND(datetime) 参数个数:1;日期时间或时间类型。获取秒数 45 = SECOND(DATETIMEVALUE("2025-07-31 14:30:45"))
MILLISECOND(datetime) 参数个数:1;日期时间或时间类型。获取毫秒数 0 = MILLISECOND(DATETIMEVALUE("2025-07-31 14:30:45"))
UNIXTIMESTAMP(datetime) 参数个数:1;日期时间、日期或时间类型。返回自 1970-01-01 以来的毫秒数,或时间在一天中的毫秒数 1753943445000 = UNIXTIMESTAMP(DATETIMEVALUE("2025-07-31 14:30:45"))
DAYOFYEAR(date) 参数个数:1;日期类型。返回指定日期在当年的具体天数(1-366) 1 = DAYOFYEAR(DATE(2025,1,1))
WEEKDAY(date) 参数个数:1;日期类型。返回指定日期是当周的第几天(1=周一,7=周日) 1 = WEEKDAY(DATE(2025,7,28))
ISOYEAR(date) 参数个数:1;日期类型。返回 ISO 8601 周历年份(一周第一天为周一) 2025 = ISOYEAR(DATE(2025,7,31))
ISOWEEK(date) 参数个数:1;日期类型。返回 ISO 8601 周编号(1-53),第一周从周一开始 21 = ISOWEEK(DATE(2024,5,20))

[!NOTE]
UNIXTIMESTAMPTIMENOWFROMUNIXTIME 等涉及时区的函数:灰度多时区的租户使用租户时区,否则使用东八区。

日期与日期时间函数

函数 说明 示例
DATE(year, month, day) 通过数值创建日期 1982-04-13 = DATE(1982, 4, 13)
DATEVALUE(string) 通过字符串创建日期 1982-04-13 = DATEVALUE('1982-04-13')
DATETIMEVALUE(string) 通过字符串创建日期时间 2001-08-24 15:45:25 = DATETIMEVALUE('2001-08-24 15:45:25')
DATETIMETODATE(datetime) 提取日期时间中的日期部分 1982-04-13 = DATETIMETODATE(...)
DATETIMETOTIME(datetime) 提取日期时间中的时间部分 17:02:40 = DATETIMETOTIME(...)
FROMUNIXTIME(ms) 毫秒数转日期时间 2025-07-31 14:30:45 = FROMUNIXTIME(1753943445000)
TODAY() 返回当前日期
NOW() 返回当前日期时间
TIMENOW() 返回当前时间 14:30:45 = TIMENOW()
YEARS(n) 设定"年"偏移量 TODAY() + YEARS(1)
MONTHS(n) 设定"月"偏移量 TODAY() + MONTHS(1)
DAYS(n) 设定"日"偏移量 TODAY() + DAYS(1)
HOURS(n) 设定"小时"偏移量 datetime + HOURS(4)
MINUTES(n) 设定"分钟"偏移量 datetime + MINUTES(30)

日期运算规则:

  • 日期 ± 偏移date + DAYS(4) 得到 4 天后的日期。
  • 日期时间 ± 偏移datetime - DAYS(1) 得到前一天的时间。
  • 时间 ± 偏移time - HOURS(1) 得到前一小时的时间(结果在 00:00~23:59 之间)。
  • 日期相减:两个日期相减结果以小时为单位。日期时间相减也以小时为单位。时间相减同样以小时为单位。

文本函数

函数 说明 示例
&+ 参数个数:2;均为文本类型。字符串组合。& 在公式中会被转换为 + 号,不建议直接使用 "张三" + "李四"张三李四
'' 参数个数:1;字符串。插入单行文本常量 '单行文本'
'''''' 参数个数:1;字符串。插入多行文本常量 '''多行文本'''
TEXT(value) 参数个数:1;不定类型。将一个值转换为使用标准显示格式的文本。value 为空时返回空字符串;百分数字段返回除以 100 的小数;日期、日期时间和时间字段返回格式化的文本 2025-08-01 = TEXT(DATE(2025,8,1))
LEFT(text, n) 参数个数:2;文本、数值。从文本字符串左边算起返回指定数量的字符。text 为空时返回空字符串;n 为空或小于 1 时返回空字符串 dog days = LEFT("dog days and dog nights", 8)
RIGHT(text, n) 参数个数:2;文本、数值。从文本字符串右边算起返回指定数量的字符。text 为空时返回空字符串;n 为空或小于 1 时返回空字符串 dog nights = RIGHT("dog days and dog nights", 10)
MID(text, start, n) 参数个数:3;文本、数值。给定起始位置和长度返回中间字符。start 从 1 开始计数;text 为空时返回空字符串;start 为空或大于 text 长度时返回空字符串;n 为空或小于 1 时返回空字符串 and = MID("dog days and dog nights", 10, 3)
UPPER(text) 参数个数:1;文本。将值中所有字母转换为大写 DOG = UPPER("doG")
LOWER(text) 参数个数:1;文本。将值中所有字母转换为小写 dog = LOWER("DOg")
REVERSE(text) 参数个数:1;文本。以相反顺序返回文本字符串 dog = REVERSE("god")
INITCAP(text) 参数个数:1;文本。将文本转换为小写形式,同时将每个单词的第一个字母变为大写。text 为空时返回空字符串 Dog Days And Dog Nights = INITCAP("DOG days and dog nights")
LPAD(text, len [, pad]) 参数个数:2-3;文本、数值。使用空格或可选填充字符串填充在值的左侧以使其长度达到指定长度。不传 padpad 为空时使用空格填充;text 为空时以空字符串参与运算;len 为空或小于 1 时返回 text xxxxxDog = LPAD("Dog", 8, "x")
RPAD(text, len [, pad]) 参数个数:2-3;文本、数值。使用空格或可选填充字符串填充在值的右侧以使其长度达到指定长度。不传 padpad 为空时使用空格填充;text 为空时以空字符串参与运算;len 为空或小于 1 时返回 text Dogxxxxx = RPAD("Dog", 8, "x")
SUBSTITUTE(text, old, new) 参数个数:3;文本。用 new 替换文本中的 old。全量替换,区分大小写。text 为空时返回空字符串;old 为空时返回 textnew 为空时使用空字符串替换 SUBSTITUTE("I love cats. Cats are cute.", "cats", "dogs")I love dogs. Cats are cute.
NUMBERSTRING(number) 参数个数:1;数值、金额。将数字转化成中文大写数字展示 壹拾玖万捌仟贰佰零肆点壹叁 = NUMBERSTRING(198204.13)
NUMBERSTRINGRMB(number) 参数个数:1;数值、金额。将数字转化成中文大写金额展示,最多支持到角、分 壹拾玖万捌仟贰佰零肆元壹角叁分 = NUMBERSTRINGRMB(198204.13)

布尔函数

函数 说明 示例
<, >, >=, <=, 参数个数:2;均为数值型、百分比、金额。数值类型进行比较,返回 true 或 false true = 1 < 2false = 2 < 1
AND(bool1, bool2, ...) 参数个数:多个;布尔型。逻辑与,若多个条件运算结果都为 true,则结果为 true true = AND(2>1, 5>3)
OR(bool1, bool2, ...) 参数个数:多个;布尔型。逻辑或,若其中一个条件运算结果为 true,则结果为 true true = OR(2>1, 5<3)
NOT(bool) 参数个数:1;布尔型。若条件为 true 则结果为 false,反之结果为 true false = NOT(2>1)
ISNULL(expr) 参数个数:1;不限类型。判断表达式结果是否为空,若空返回 true,反之 false false = ISNULL(5)
ISNUMBER(string) 参数个数:1;字符串。判断字符串是否可以转为数字 true = ISNUMBER('5')
STARTWITH(s1, s2) 参数个数:2;字符串。返回字符串是否以查询字符串开始 true = STARTWITH('abcdef', 'ab')
ENDWITH(s1, s2) 参数个数:2;字符串。返回字符串是否以查询字符串结束 true = ENDWITH('aecdab', 'ab')
EQUALS(s1, s2) 参数个数:2;字符串。返回字符串是否等于查询字符串(区分大小写) true = EQUALS('aecdab', 'aecdab')
CONTAINS(s1, s2) 参数个数:2;字符串。返回查询字符串在字符串中的匹配结果 false = CONTAINS('abcdef', 'kl')

[!WARNING]
ANDOR 函数在执行时会编译其中的每一个表达式。即使前面的条件已确定结果,后续表达式中的错误(如空值参与运算)仍会导致整个公式报错。需要将可能为空的字段用 ISNULL() 提前判空,并通过嵌套 IF 隔离分支。

筛选与排序

筛选

计算字段支持在数据列表页中作为筛选条件,筛选比较符根据返回值类型匹配。

[!WARNING]
公式中引用全局变量(当前日期、当前时间、当前日期时间)、人员对象字段或使用 NOW()TODAY() 函数时,该计算字段不支持筛选,也不支持被统计字段、计算字段或验证规则引用。

排序

所有返回类型的计算字段在列表页均支持排序,包括数值、金额、百分比、日期时间、日期、时间、文本、布尔类型。仅支持可筛选的计算字段。

计算字段与统计字段互算

场景举例

在发货单产品下计算单个产品的成本,希望在发货单中能够统计总成本,进行利润分析。

逻辑分析

统计字段支持了主对象或相关对象上的统计和计算需求。

计算字段与统计字段互算逻辑

具体业务举例(计算字段和统计字段的应用场景):

利润分析配置示例

层级模型

系统对计算字段和统计字段的跨对象引用链路有层级限制:

层级 说明
上层 主对象或查找关联对象字段
本层 本对象字段
下层 从对象或相关对象字段
上一级对象 主对象或查找关联对象

[!NOTE]
"相关对象"是指查找关联中本对象的对象。例如 [销售订单] 查找关联 [客户],则 [销售订单] 为 [客户] 的相关对象。建议从发起校验的节点开始查看层级。

层级限制规则

  • 若本对象的计算字段被上层统计字段引用,则该计算字段不能引用上层统计字段、默认值、计算字段、普通字段,也不能引用下层统计字段。可以引用本对象的默认值和计算字段。
  • 若本对象的默认值被上层统计字段引用且该统计字段又被更上层引用,则本对象默认值可引用本对象默认值和计算字段,不能引用本对象统计字段。可引用上一级的计算字段和默认值,不能引用上一级统计字段。
  • 本对象的默认值有相同的校验逻辑。

层级限制图解

图例 4-1 详细说明:

  • 如从【报价单】的计算字段触发校验,向上层下层进行引用。当此“计算字段”已引用本对象中的一个“统计字段”,则此“统计字段”不能引用【报价单明细】的计算字段/统计字段,只能引用【报价单明细】中的默认值。

由计算字段或默认值发起校验的层级限制

由计算字段或默认值发起校验

  • 可参考上方层级限制规则中的解释与示例。
  • 在新建编辑页面编辑了默认值公式中的字段,就会触发这个默认值的计算。

配置页面错误提示

配置不满足规则时,系统提示:

"系统暂不支持多级计算/统计互算,您已配置【对象名.字段名→对象名.字段名→对象名.字段名】(→代表引用)"

例如 [发货单] 中已配置"门店信用"字段计算相关对象 [门店] 的信用值,若再添加"优惠额度"字段引用本对象的"门店信用",保存时会报错。

多级计算互算报错

报错详情

默认值与计算字段的区别

使用场景对比

维度 默认值 计算字段
定位 自动填充初始值,可手动修改 自动生成结果,不可手动修改
典型场景 根据成本加利润率设置默认售价,实际售价可调整 交易时根据原币×汇率生成本位币金额,不可修改
历史数据 新建/编辑默认值公式后历史数据不重算 新建/编辑计算公式后历史数据会重算(有延迟)
字段变化响应 仅在新建/编辑页修改公式中字段时才重算 公式中字段值变化后,计算字段始终跟随变化
其他操作影响 UI 函数、按钮执行动作等不会触发重算 无论何种方式修改公式中字段,计算字段都会重算

[!TIP]
如果计算结果必须随公式中字段变化而更新,或希望新建字段后重算历史数据,请使用计算字段。

默认值常见计算问题

  • 公式内容错误:

    1. 参与计算的字段值为空或值错误。可以把数据上的值带入公式进行计算:
    • 出现 0 为除数的情况,导致计算公式报错。
    • 出现空值参与逻辑运算(加减乘除比大小),导致计算公式报错。
    • 注意公式中的“公式中字段为空值时”按什么参与运算。
    • 类型转换错误,文本转数字、文本转日期等,基本都是因为格式不正确。
    • 公式中如果使用创建时间,在新建页面是无法计算的,因为数据只有在保存后创建时间字段才会有值,所以默认值不会算出来。
    1. 公式逻辑不正确:
    • 可以再检查一下公式是按哪个分支进行计算的,注意单选/多选是用的 value 还是 label,如果用的是 label 还要确认是否由于多语言影响导致判断不对。
    • 单选/多选默认值参考“单选/多选默认值不生效”章节。

默认值字段自身限制

  • 默认值字段对历史数据不生效:仅在新建/编辑页面中参与计算的字段发生变化时才会计算;非新建/编辑页中参与计算的字段变更不计算,比如关联数据、按钮修改、导入数据、函数新建变更等。如:使用了统计字段,统计字段在保存数据后发生了变化;使用了查找关联字段的值,并在当前对象保存数据后 lookup 的字段值发生了变化。
  • 从对象使用负责人字段作为默认值,新建页面无法计算。
  • 使用负责人主属部门做默认值,新建页面无法计算,编辑页如果不修改参与公式的字段也不会重新算。

UI 事件/函数相关

  • 2024 年 5 月 1 日之前配置的 UI 事件函数添加/编辑从对象数据参与默认值公式时,默认值不自动计算(需配置 doCalculate(true))。
  • 之后配置的 UI 事件函数自动计算。
  • 保存按钮后动作函数修改了默认值字段,可能导致提交后默认值与页面预览不一致。

权限相关

  • 详情页复制数据时:如当前用户对该字段权限为只读或不可见是不复制的。
  • 如果是有权限的默认值字段,仅复制原值,不重新计算。
  • 如果字段显示且有编辑权限,那么可自行修改,不能保证和计算公式一致。
  • 数据映射时:默认值字段原值映射不重算,如布局只读/布局隐藏/权限只读/权限不可见都可以映射回填。
  • 如何查看数据是通过什么方式创建的:需要查看修改记录中的新建记录,点击记录中的主属性,在新建修改记录快照上方会显示数据来源。

单选/多选默认值不生效

公式计算结果必须等于目标选项的 value(API Name),而非 label。

匹配规则:选项 2 的默认值 = 选项 1 的 label + value。即被默认值公式使用的选项(选项 1)的值对应选项值 API Name(label 对应 value,如 a 对应 1,b 对应 2,c 对应 3),配置默认值公式的选项(选项 2)的默认值会去匹配选项 1 的 label + value。若前台在选项 1 中选择了 a,在选项 2 的 value 中没有找到 a1,则前台选项 2 的默认值不回填。

选项默认值配置示例

专业术语说明

选项值映射

主从新建编辑页复制从数据时被复制的从默认值被重算

如果默认值字段直接或间接使用了关联对象的统计字段且统计的是当前操作对象的字段,那么涉及到的数据都会被重新计算。且关联对象的统计结果会带上当前这条数据。

公式配置案例

以下案例适用于计算字段、验证规则和默认值公式。

空值参与计算的处理

【场景】 field1 是数字字段,当值大于 100 时返回“是”,否则返回“否”。

错误示例

IF($field1$>100,"是","否")

field1 为空时,空值无法与 100 比较,计算结果为空。

正确示例

// 方法 1:ISNULL 优先返回
IF(ISNULL($field1$),"否",IF($field1$>100,"是","否"))

IF 函数会按顺序执行条件表达式,ISNULL 函数满足条件时直接返回“否”,否则继续判断 field1 是否大于 100。

// 方法 2:嵌套 IF 隔离判空
IF(IF(ISNULL($field1$),false,$field1$>100),"是","否")

把 field1 是否为空和是否大于 100 的判断逻辑放到一个 IF 函数里,field1 不为空时才判断是否大于 100。

// 方法 3:AND 中判空放最前
IF(AND(NOT(ISNULL($field1$)),$field1$>100),"是","否")

使用 AND 函数同时对 field1 进行判空和判断是否大于 100,注意判空必须放在 AND 函数的最前面。

[!NOTE]
日期、单选等字段不受“公式中字段为空值时”选项控制,没有值时始终以空值参与计算。

公式中判断字段是否为空

页面看到字段为空,但条件却没生效。实际页面看到字段为空,值可能是 null 也可能是 "",所以用单一方式判断不能保证生效。要使用 ISNULL() 函数来判断字段是否为空值。

特殊的 & 符号

& 符号在公式中会被转换为 + 号,不建议使用。拼接到文本里无法显示,在验证规则中也无法正常拦截此字符。

如果想在文本里展示 & 符号,不能直接在公式中拼接,可以配置一个全局变量(文本类型,配置成 & 符号),然后在公式中使用全局变量。

文本拼接

【场景】 销售订单下的某个计算字段,想显示成“客户名称—订单编号”。

正确示例字段1 + "-" + 字段2

错误示例:使用 &- 等其他操作符拼接


【场景】 拼一个日期时间字段,日期内容来自一个日期字段,时间是当前时间。

正确示例

DATETIMEVALUE(''+$field_rBj2I__c$+' '+$currentTime__g$)

日期字段参与计算时的类型处理

对于返回类型是日期时间、日期、时间的计算字段,比较容易出问题的是类型转换的场景,比如日期时间转日期、日期时间修改时间等。

【场景】 新建计算字段,计算数据的创建日期。

错误示例

DATEVALUE(YEAR($create_time$)+"-"+MONTH($create_time$)+"-"+DAY($create_time$))

月和日小于 10 时缺少前导零(如 2023-7-6),日期格式不正确,DATEVALUE 转换失败返回空值。

正确示例

// 方法 1:直接使用标准函数
DATETIMETODATE($create_time$)

// 方法 2:手动补零(逻辑正确但复杂)
DATEVALUE(YEAR($create_time$)+"-"+IF(MONTH($create_time$)<10,"0"+MONTH($create_time$),MONTH($create_time$))+"-"+IF(DAY($create_time$)<10,"0"+DAY($create_time$),DAY($create_time$)))

【场景】 给日期时间增加 30 分钟。

错误示例$field_datetime__c$+HOURS(0.5)HOURS() 只能识别整数。

正确示例$field_datetime__c$+MINUTES(30)


【场景】 当前日期与创建日期相差几天。

错误示例TODAY()-$create_time$TODAY() 返回日期类型,$create_time$ 是日期时间类型,不能直接相减。

正确示例TODAY()-DATETIMETODATE($create_time$)+1

使用函数 TODAY() 得到当前日期,DATETIMETODATE 函数将日期时间转换为日期,使用两个日期相减得到日期差额。

[!NOTE]

  • 日期字段是否为空,如果为空需要进行判空处理。
  • 配置“日期 1 - 日期 2”,这个计算结果是小时,如果想要显示天,则需要在公式中自己转换。日期时间差不足 1 小时且未配置小数位数就会显示 0。

AND 函数中的空值陷阱

【场景】 判断字段值是否不超过 180 并关联对象字段非空。

错误示例

IF(AND($field_n22pu__c$!=null,$field_n22pu__c$!="",$field_n22pu__c$<=180,$account_id__r.field_cO63Q__c$!=null,$account_id__r.field_cO63Q__c$!=""),"获客","自拓")

field_n22pu__c 字段为空时,这个公式计算会报错,无法计算出预期结果“自拓”。

错误原因:虽然公式前面对 field_n22pu__c 字段进行了判空处理,但是 AND 的处理逻辑是把里面的分支都走一遍,所以在 field_n22pu__c 为空时,还是会走到 field_n22pu__c<=180 的判断,出现 null/""<=180 的情况,计算异常。

正确示例

IF(AND(IF(OR($field_n22pu__c$==null,$field_n22pu__c$==""),false,$field_n22pu__c$<=180),$account_id__r.field_cO63Q__c$!=null,$account_id__r.field_cO63Q__c$!=""),"获客","自拓")
IF(OR(ISNULL($field_5t3I8__c$),ISNULL($name1__c$)),"自拓",IF($field_5t3I8__c$<=180,"获客","自拓"))

文本拼接

拼接文本使用 + 号,不使用 &-。详见上方“文本拼接”案例。

公式中使用了日期、单选等字段的空值处理

【需求】 field1 是单选字段,field2 是日期字段,当 field1 包含“新冠”且 field2 的年份大于等于 2023 时返回 1,否则返回 0.5。

错误示例 1

IF(AND(CONTAINS($field1$,"新冠"),YEAR($field2$)>=2023),1,0.5)

当 field2 为空时,YEAR 函数不支持空值,公式报错,计算结果为空。(CONTAINS 函数兼容了空值,所以 field1 为空时不会报错。)

错误示例 2

IF(AND(NOT(ISNULL($field2$)),CONTAINS($field1$,"新冠"),YEAR($field2$)>=2023),1,0.5)

看上去对 field2 做了判空,但 AND 函数会编译每一个表达式,YEAR 函数还是会报错。

错误示例 3

IF(OR(ISNULL($field2$),NOT(CONTAINS($field1$,"新冠")),YEAR($field2$)<2023),0.5,1)

反向判断,但 OR 函数同样会编译每一个表达式,YEAR 函数还是会报错。

正确示例 1

IF(ISNULL($field2$),0.5,IF(AND(CONTAINS($field1$,"新冠"),YEAR($field2$)>=2023),1,0.5))

将 field2 的判空单独抽出来,多嵌套一层 IF 函数。

正确示例 2

IF(ISNULL($field2$),0.5,IF(OR(NOT(CONTAINS($field1$,"新冠")),YEAR($field2$)<2023),0.5,1))

反向判断,同样将 field2 的判空单独抽出来。

常见问题与排查

计算字段值为空(计算延迟)

排查步骤

  1. 查看审计日志或向管理员确认计算字段是否新建或重新编辑过。此时历史数据正在重算,数据量大时延迟较久,建议等待数小时或一天。
  2. 查看修改记录,确认是否有批量导入或按钮批量修改数据。增量计算也会有延迟。若对象未配置修改记录,建议联系管理员在 CRM 日志中排查。

计算字段值错误(被函数覆盖)

计算服务计算结果正确,但可能被工作流、UI 函数等后续并发更新覆盖。

排查步骤:查看修改记录,检查是否有后动作函数或 UI 函数修改了该字段。函数应使用增量更新:

Fx.object.batchUpdate(<api-name>, <objects>, <fields>)

不指定 fields 参数时为全量更新,可能覆盖其他字段。

计算字段值错误(导入数据小数位)

前端设置小数位为 2 位,但通过导入或函数写入的数据小数位不是 2 位。数据库存储的实际精度高于前端显示精度,导致用户看到的数值与计算结果不一致。

排查步骤:查看导入导出记录或函数批量更新记录,核实数据实际精度。

计算字段值显示有误

检查计算字段的公式内容是否正确。

管理员与普通员工看到的值不同

可能原因:普通员工从复制进入新建编辑页面,管理员有参与计算字段的编辑权限(手动写入值参与计算),普通员工没有编辑权限(UI 事件回填值不参与重算)。

排查步骤:确认普通员工是否有计算字段编辑权限,以及参与计算的字段是否为 UI 事件回填。

识别计算字段变更

前往 管理后台 > 企业日志 > 审计日志,操作模块选择 自定义对象管理,使用 Ctrl+F 搜索对象名称,可查看计算字段的新建、编辑、删除记录。

新建编辑页有值,提交后无值或值不一致

排查方向

  • 计算字段直接/间接使用了统计字段。
  • 统计字段统计了当前提交的对象。
  • 统计字段有过滤条件,数据提交后过滤条件中字段变化导致统计结果变化。

相似问题:统计字段提交后值不一致。

默认值与计算字段公式相同但提交后值不同

排查方向

  • 原因 1:同上述问题,提交后计算字段重算而默认值不重算。
  • 原因 2:新建前验证函数中修改了字段值。
  • 原因 3:如果新建页就不一样,考虑是否有 UI 事件函数修改或数据来自复制/映射。

计算字段返回文本长度被截断

计算字段返回文本不限制长度,但如果是显示字段中配置的公式,默认长度为 128。

单选字段默认值不显示

排查:

  1. 检查计算结果在选项 value(API Name)中是否存在。不存在则新建页面无法显示,提交后显示“选项已删除”。
  2. 检查计算结果是否符合依赖关系。与业务类型依赖关系在新建页面不可见,需检查后台依赖关系配置。

单选字段依赖关系

在 BI 报表中使用计算字段

当计算公式中引用全局变量、人员对象字段或使用 NOW()TODAY() 函数时,该计算字段不支持作为 BI 报表维度。

其他计算字段可在报表 维度 处点击 设置,选择计算字段即可。

BI 报表中使用计算字段

计算字段能否直接统计其他字段内容

计算字段无法直接统计其他字段内容。可在计算公式中插入统计字段作为变量,根据统计结果配置计算公式。涉及主从关系和查找关联关系的引用请参见上文“计算/统计互算层级限制”。

统计文字个数

使用 LEN 函数统计字段内容中文字个数。统计单选字段需选择含 label 的 API Name。

LEN 函数统计文字个数

计算字段不能被引用的情况

  • 不落地:公式中引用全局变量、人员对象字段或使用 NOW()TODAY() 函数时,计算结果不存入数据库。不支持筛选、不支持作为 BI 维度、不支持被统计字段和计算字段引用。
  • 落地但受层级限制:公式中未引用上述内容时结果存入数据库。若仍不能被引用,说明涉及计算/统计互算的层级限制。

计算字段是否为实时更新

  • 不落地的计算字段是在查询数据时实时计算的。
  • 落地的计算字段是在后台程序队列中异步计算的,不是实时更新,因此存在一定的延迟,延迟时间与队列中排队的任务数有关。购买了独立数据库的租户会分配独立的计算队列。

多条数据与单条数据的时效性

  1. 计算字段是新建或重新编辑过的,此时会重算历史数据,数据量大时延迟较久。
  2. 批量导入或使用按钮等批量修改数据时,增量计算也会有延迟。
  3. 对于单条数据,当计算字段引用的字段开始编辑时,计算字段即开始计算。

计算字段的时区

灰度多时区的租户使用租户时区,未灰度多时区的租户使用服务器默认时区(一般为东八区)。

返回数据位数限制

  • 文本类型:建议不超过 5,000 位。
  • 数值、金额类型:建议不超过 50 位(含小数),小数位最多返回 9 位。

相关主题

2026-08-12
0 0