一、计算字段使用场景
用户在使用纷享销客CRM产品过程中,会涉及各种数学运算,如根据产品官方报价和折扣计算出货价等。
使用计算型字段,可以方便的满足上述功能。
二、操作指南
2.1 计算字段配置
纷享销客提供的计算型字段,可以根据不同的预期结果值,采用不同的运算符和函数进行计算,结合满足要求的参数(其他字段或常量),计算相应的结果。
- 计算型字段的插入字段可支持插入单选、单行文本、多行文本、时间、网址、布尔值、手机、数字、百分数、邮箱、人员、计算字段、统计字段 ,作为变量进行计算。
- 计算字段支持查找关联对象的计算字段。(查找关联对象的统计字段需统计普通字段)
- 计算字段支持引用查找关联对象的统计字段。
- 默认值公式支持查找关联对象的计算字段。
- 预设对象的计算字段和默认值设置公式时,支持插入函数。
- 计算字段对导入的数据生效。
2.1.1 基础设置
- 字段名称:可自行按照业务要求定义,不可以和本对象下的已存在对象同名
- api name:系统自动生成,可根据需要点击ai按钮生成名称翻译后的API Name
- 备注信息:此处添加对字段的描述,配置后只在管理后台展示,在前台不显示
- 帮助信息:
帮助信息填写关于这个字段的信息,信息填写完成后会在前台新建编辑页和详情页展示
配置悬停问号展示:在详情页和新建编辑页,鼠标悬停问号展示字段帮助信息
配置外露展示(仅支持新建编辑页):在详情页鼠标悬停问号展示字段帮助信息,在新建编辑页外露展示字段帮助信息 - 是否显示千分位:若选择是,订单利润11111.00将在前端(列表页,详情页,新建编辑页)显示11,111.00。打印结果不显示千分位。
- 是否掩码显示:若设置“是”,可添加角色,配置好了之后,除了这些角色的其他人员在列表页,详情页,数据新建完成后再次进入的新建编辑页看到的字段值均为掩码(**)
2.1.2 计算设置
点击“计算设置”可配置计算字段的返回值类型、计算公式以及空值处理方式
2.1.2.1 返回值类型设置及设置可能触发的配置
- 当利润(计算字段)的返回值类型为日期时间,日期,时间,文本,布尔时,当其他计算字段,统计字段,验证规则引用利润(计算字段)时,“公式中字段为空值时”默认为零选项的设置不生效,直接以空值参与计算。空值参与数学运算或者逻辑判断的话,程序会报错,最终计算结果就是空值,这时就需要用到判空函数了。
- 当利润(计算字段)的返回值类型为数值、金额、百分比类型的字段,当其他计算字段,统计字段,验证规则引用利润(计算字段)时,会判断“公式中字段为空值时”这个选项,如果是“默认为零”,会将空值转换成0再参与计算,这时候是不需要对这些字段判空的。
2.1.2.2 小数位数
小数位数如果设置为2,利润(计算字段)算出来是6.167,在数据库会四舍五入存为6.17,前端显示也为6.17
2.1.2.3 计算公式配置的注意事项
- 基础模式只可插入本对象下的字段和全局变量,若想引用查找关联对象和主对象下的字段需启用高级模式。
- 在公式中配置关联对象的统计字段和相关对象的计算字段均为异步计算,计算结果可能会存在延迟!
- 计算公式中引用全局变量(当前日期、当前时间、当前日期时间)、人员对象下的字段和使用NOW() 、TODAY()函数时,将不支持被筛选和被其他统计字段、计算字段以及验证规则引用。
- 对于日期相减,如配置“日期1 - 日期2”,这个计算结果是小时,如果想要显示天,则需要公式中自己转换
-&符号在公式中会被转换成+号,不建议使用,如果想在文本里展示“&”符号,不能直接在公式中拼接,可以配置个全局变量(文本类型,配置成&符号),然后在公式中使用全局变量 - 使用case函数时,如果配置CASE($field_cCe5K__c$,"一线城市"60.5,“二线城市”,49.0,0)就错了,因为case每个判断的返回的类型要一样,比如这个公式里最后返回的是0,不带小数,则会报错,改成0.0即可
2.1.2.4 公式中字段为空值时
1.选择公式中字段为空值时默认为0
当计算字段的返回值类型为数值、金额、百分比类型的字段时,公式中的字段的空值处理为0
2.选择公式中字段为空值时默认为空
当计算字段的返回值类型为数值、金额、百分比类型的字段时,公式中的字段的空值处理为空
2.1.2.5 对象数据试算
如果试算出现错误提示,计算字段没有值,大概率是以下几点原因造成的:
1、计算公式中有字段的值是空值,但是没有默认为零也没有判空。
2、类型转换错误,文本转数字、文本转日期等,基本都是因为格式不正确。
2.1.3 注意事项
点击编辑字段页面的保存时,若数据大于1w条,会弹出提示弹窗。
- 若选择“现有数据不计算”:不会计算新建完计算字段之前的创建的历史数据
- 若选择“全部计算(数据量大,可能计算时间会略长)“:会重新计算该对象下现存的全部数据,但是会出现计算延时的问题(即计算字段的值在一段时间内为空)
- 若选择”符合以下数据范围计算“:可按需配置条件,系统只对满足条件的数据进行计算
- 若数据小于等于1w条,不会弹出提示弹窗,系统会正常保存计算字段
2.1.4 查看计算任务进度
新建或编辑计算字段后,因为计算历史数据需要花费的时间较长,因此提供了一个查看任务进度的入口,当任务执行中和等待中时可以查看统计字段的统计任务执行情况。此时列表会显示【计算任务执行情况】按钮,点击按钮弹出弹窗显示任务状态,展示任务的总数据量,已经完成的数据量和预计任务结束的时间。
2.1.5 计算公式配置案例
- 用一个日期减去另一个日期算出他们之前相隔的天数,用计算字段怎么写?
场景:客户下有两个日期字段,开始拜访日期和结束拜访日期,用户想要算出开始拜访日期和结束拜访日期的间隔时间。
操作说明:点击计算字段的计算设置在插入字段处选择“结束拜访日期”,在插入运算符处选择“-”,在插入字段处选择“开始拜访日期”。
操作逻辑:在插入字段处选择日期,在插入运算符处选择“-”拼接。
2.1.5 计算公式的可插入的函数解析
返回值类型 | 运算符/函数 | 参数 | 功能 | 备注及实例 |
---|---|---|---|---|
通用 | () | 标注运算符优先级 | ||
输入参数有关 | IF(logical_test, value_if_true, value_if_false) | 参数个数:3,参数类型:第一个为布尔类型,第二个和第三个必须为同一种类型 | 判断条件是否为true,如果为true,则返回return_true_value,否则返回return_false_value其中,return_true_value和return_false_value必须为同一类型,返回值类型也为该类型,且IF函数支持嵌套使用 | 例如:34 = IF(true, 34, 52) |
输入参数有关 | CASE(expression, value1, result1, value2, result2,...,else_result) | 参数个数:不定,参数类型:result(n)和else_result必须为同一种类型 | 根据满足不同的条件,返回满足条件的值。其中expression的值与value(n)进行比较,value(n)与expression的值一致,则返回对应的result(n),如果都不一致,则返回else_result;其中,result(n)和else_result必须为同一种类型,返回值类型也为该类型 | 例如:33 = CASE(3, 2, 2, 3, 33, 1.3) |
输入参数有关 | NULLVALUE(expression, substitute_expression) | 参数个数:2,参数类型:第一个为布尔类型,第二个参数可以为各种类型 | 判断条件是否为空,如果是,则返回return_value,如果否,返回空;其中,返回值类型也为第二个参数的类型 | 例如: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:00,b的值为1982-04-12 15:00:00,26 = a - b |
数值 | - | 参数个数:2,参数类型:均为时间,以小时为单位 | 运算时间的差值,以小时为单位 | 例如:a的值为17:00:00,b的值为15:00:00,2 = a - b |
数值 | VALUE(string) | 参数个数:1,参数类型:文本类型 | 将文本形式的数字转化成数字,支持负数和小数,如果转化不成功,返回空 | 例如:-1982.0413 = VALUE('-1982.0413'),Null = VALUE('aaa') |
数值 | MIN(number1,number2) | 参数个数:2,参数类型:均为数值类型 | 返回两个参数中最小的一个 | 例如:4 = MIN(4,13) |
数值 | MAX(number1,number2) | 参数个数:2,参数类型:均为数值类型 | 返回两个参数中最大的一个 | 例如:13 = MAX(4,13) |
数值 | MULTIPLE(number1,number2) | 参数个数:2,参数类型:均为数值类型 | 返回数字1乘以数字2的结果 | 例如:52 = MULTIPLE(4,13) |
数值 | MOD(number1,number2) | 参数个数:2,参数类型:均为数值类型 | 返回数字1被数字2除后的整数部分 | 例如:3 = MOD(13,4) |
数值 | ADDS(number1,number2) | 参数个数:2,参数类型:均为数值类型 | 返回数字1加上数字2的结果 | 例如:17 = ADDS(13,4) |
数值 | SUBTRACTS(number1,number2) | 参数个数:2,参数类型:均为数值类型 | 返回数字1减去数字2的结果 | 例如:9 = SUBTRACTS(13,4) |
数值 | YEAR(date) | 参数个数:1,参数类型:日期,或日期时间类型 | 用于获取参数中的年的数值 | 例如:a = 1982-04-13,1982 = YEAR(a) |
数值 | MONTH(date) | 参数个数:1,参数类型:日期,或日期时间类型 | 用于获取参数中的月的数值 | 例如:a = 1982-04-13,4 = MONTH(a) |
数值 | DAY(date) | 参数个数:1,参数类型:日期,或日期时间类型 | 用于获取参数中的日的数值 | 例如:a = 1982-04-13,13 = DAY(a)= |
数值 | LEN(text) | 参数个数:1,参数类型:文本型 | 返回字符串的长度 | 例如:6=LEN('xiaoke') |
百分比 | +,-,*,/ | 参数个数:2,参数类型:数值,百分比,金额 | 进行数值的加减乘除运算,以百分比形式返回 | |
日期时间类型的中间值 | YEARS(number) | 参数个数:1,参数类型:数值型 | 设定一个数值,作为一个“年”的数值应用在指定日期/日期时间的运算中 | 例如:2019-09-09=TODAY()+YEARS(1),其中,TODAY()假设为 2018-09-09 |
日期时间类型的中间值 | MONTHS(number) | 参数个数:1,参数类型:数值型 | 设定一个数值,作为一个“月”的数值应用在指定日期/日期时间的运算中 | 例如:2019-09-09=TODAY()+MONTHS(1),其中,TODAY()假设为 2019-08-09 |
日期时间类型的中间值 | DAYS(number) | 参数个数:1,参数类型:数值型 | 设定一个数值,作为一个“日”的数值应用在指定日期/日期时间的运算中 | 例如:2019-09-09=TODAY()+DAYS(1),其中,TODAY()假设为 2019-09-08 |
日期时间类型的中间值 | HOURS(number) | 参数个数:1,参数类型:数值型 | 设定一个数值,作为一个“小时”的数值应用在指定日期时间的运算中 | 例如:HOURS(4) |
日期时间类型的中间值 | MINUTES(number) | 参数个数:1,参数类型:数值型 | 设定一个数值,作为一个“分钟”的数值应用在指定日期时间的运算中 | 例如:MINUTES(4) |
日期 | +,- | 参数个数:2,参数类型:第一个为日期类型,第二个为由YEARS、MONTHS、DAYS计算出的时间 | 进行日期运算,得出新的日期值 | 例如:Creatdate+DAYS(4),得到创建时间+4天后的日期 |
日期 | DATE(year,month,day) | 参数个数:3,参数类型:数值 | 通过数值,创建一个日期类型值 | 例如:1982-4-13=DATE(1982,4,13) |
日期 | DATEVALUE(string) | 参数个数:1,参数类型:字符串 | 通过字符串,创建一个日期类型值 | 例如:1982-4-13=DATEVALUE('1982-04-13') |
日期 | TODAY() | 无参数 | 返回当前的日期 | |
日期 | DATETIMETODATE(datetime) | 参数个数:1,参数类型:日期时间类型公式 | 返回日期时间字段中的日期 | 例如:1982-4-13=DATEVALUE('1982-04-13 17:00:00') |
日期时间 | +,- | 参数个数:2,参数类型:第一个为日期时间类型,第二个为由YEARS、MONTHS、DAYS,HOURS,MINUTES计算出的时间 | 进行日期时间运算,得出新的日期时间值 | 例如:DeadlineTime-DAYS(1),得到截止时间前一天的时间 |
日期时间 | DATETIMEVALUE(string) | 参数个数:1,参数类型:字符串 | 通过字符串,创建一个日期时间类型值 | 例如:2001-08-24 15:45:25 = DATETIMEVALUE('2001-08-24 15:45:25') |
日期时间 | NOW() | 无参数 | 返回当前的日期时间 | |
时间 | +,- | 参数个数:2,参数类型:第一个为日期时间类型,第二个为由HOURS,MINUTES计算出的时间 | 进行时间运算,得出新的日期时间值 | 例如:submitDailyReport-HOURS(1),得到提交工作日报的前一小时的时间。注意:时间类型的值如果经过计算后的结果只在00:00到23:59之间 |
日期时间 | DATETIMETOTIME(datetime) | 参数个数:1,参数类型:日期时间类型公式 | 返回日期时间字段中的时间 | 例如:17:02:40=DATEVALUE('1982-04-13 17:02:40') |
文本 | & | 参数个数:2,参数类型:均为文本类型 | 字符串组合 | 例如:“张三”&“李四” 的值为 张三李四 |
文本 | '' | 参数个数:1,参数类型:字符串 | 插入单行文本常量 | 例如:'单行文本' |
文本 | '''''' | 参数个数:1,参数类型:字符串 | 插入多行文本常量 | 例如:'''多行文本''' |
文本 | NUMBERSTRING(number) | 参数个数:1,参数类型:数值,金额 | 将数字转化成中文大写数字展示 | 例如:壹拾玖万捌仟贰佰零肆点壹叁 =NUMBERSTRING(198204.13) |
文本 | NUMBERSTRINGRMB(number) | 参数个数:1,参数类型:数值,金额 | 将数字转化成中文大写金额展示,最多支持到叫角,分 | 例如:壹拾玖万捌仟贰佰零肆元壹角叁分 =NUMBERSTRINGRMB(198204.13) |
布尔 | <,>, >=,<=,≠ | 参数个数:2,参数类型:均为数值型,百分比,金额 | 数值类型进行比较,返回true或false | 例如:true = 1 < 2;false = 2 < 1 |
布尔 | AND(boolean1,boolean2,boolean3,...) | 参数个数:多个,参数类型:布尔型 | 逻辑与,若多个条件运算结果都为true,则结果为true | 例如:true = AND( 2>1 ,5>3) |
布尔 | OR(boolean1,boolean2,...) | 参数个数:多个,参数类型:布尔型 | 逻辑或,若其中一个条件运算结果都为true,则结果为true | 例如:true = OR( 2>1 ,5<3) |
布尔 | NOT(boolean) | 参数个数:1,参数类型:布尔型 | 若条件为true,则结果为false,反之,结果为true | 例如:false = NOT(2>1) |
布尔 | ISNULL(expression) | 参数个数:1,参数类型:不限 | 判断表达式结果是否为空,如果为空,返回true,反之为false | 例如:false = ISNULL(5) |
布尔 | ISNUMBER(string) | 参数个数:1,参数类型:字符串 | 判断expression字符串是否可以转为数字 | 例如:true = ISNUMBER('5') |
布尔 | STARTWITH(string1, string2) | 参数个数:2,参数类型:字符串 | 返回字符串是否以查询字符串开始的结果 | 例如:true = STARTWITH( 'abcdef' , 'ab' ) |
布尔 | ENDWITH(string1, string2) | 参数个数:2,参数类型:字符串 | 返回字符串是否以查询字符串结束的结果 | 例如:true = ENDWITH( 'aecdab' , 'ab' ) |
布尔 | EQUALS(string1, string2) | 参数个数:2,参数类型:字符串 | 返回字符串是否等于查询字符串的结果(跟大小写相关) | 例如:true = EQUALS( 'aecdab' , 'aecdab' ) |
布尔 | CONTAINS(string1, string2) | 参数个数:2,参数类型:字符串 | 返回查询字符串在字符串中的匹配结果(true,false) | 例如:false = CONTAINS( 'abcdef' , 'kl' ) |
2.2 筛选计算字段
计算字段支持在数据列表页中被筛选,且计算字段的筛选比较符是根据计算字段的返回值类型来匹配的。
2.3 计算字段与统计字段互算
2.3.1 场景举例
在发货单产品下计算单个产品的成本,希望在发货单中能够统计总成本,进行利润分析。
2.3.2 逻辑分析
统计字段支持了主对象或相关对象上的统计和计算需求。
-
具体业务上的使用举例(计算字段和统计字段的应用场景)
也许上面的图很多人还是看着两眼蒙圈,那下面给大家拿其中一个点举个具体例子:
开头提过用户希望能够通过系统的统计能力支持利润分析,具体配置如下:
2.3.3 计算/统计互算的层级限制
鉴于性能考虑,对计算和统计支持的链路层级有所限制,具体可参考下面图解:
-
层级分析:
-
上层:主对象或者查找关联对象字段
-
本层:本对象的字段
-
下层:从对象或相关对象字段
-
上一级对象:主对象或者查找关联对象
-
-
注意:
-
“相关对象”是指查找关联中本对象的对象,比如:[销售订单]查找关联[客户],则:[销售订单]为[客户]的相关对象
-
建议从发起校验的节点开始查看层级,方便理解。
-
-
对上图进行详细说明:
- 若本对象的计算字段被主对象或查找关联对象的统计字段引用,则该计算字段不能引用主对象和查找关联对象的统计字段,默认值,计算字段,普通字段。不能引用从对象和相关对象的统计字段。可以引用本对象的默认值和计算字段。本对象的默认值有相同的校验逻辑。
- 若本对象的默认值被主对象或查找关联对象的统计字段引用,且该统计字段被上一级对象的统计字段引用。则本对象的默认值可以引用本对象的默认值和和计算字段,不能引用本对象统计字段。本对象的默认值可以引用上一级对象的计算字段和默认,不能引用上一级对象的统计字段。本对象的计算字段有相同的校验逻辑。
- 如上图:发起校验的节点如果从【报价单】的计算字段触发,向上层下层进行引用。当此“计算字段”已引用本对象中的一个“统计字段”,则此“统计字段”是不能引用【报价单明细】的计算字段/统计字段的,只能引用【报价单明细】中的默认值。
2.3.4 由【计算字段或默认值】发起校验的层级限制
- 可参考1中“由【统计字段】发起校验时的层级限制”中的解释与示例。
- 在新建编辑页面编辑了默认值公式中的字段,就会触发这个默认值的计算。
2.3.5 配置页面提示信息
当配置了不满足规则的场景时,会提示用户错误的配置链路。这里给大家详细解说下提示信息,帮助大家理解。
-
提示信息:“系统暂不支持多级计算/统计互算,您已配置【对象名.字段名->对象名.字段名->对象名.字段名】(->代表引用)”
-
示例说明:
- 当【发货单】中已配置“门店信用”字段计算相关对象【门店】下的信用值时,如果再在【发货单】中添加“优惠额度”字段去引用本对象的“门店信用”时,字段保存时会出现如下报错。说明这个链路是不支持配置的。
2.4 计算字段排序
- 任何返回类型的计算字段在列表页均支持排序,包括数值、金额、百分比、日期时间、日期、时间、文本、布尔类型
2.5 计算字段使用案例
案例一:IF公式如何使用
【场景】
field1是数字字段,当字段field1的值大于100的时候,返回是,否则返回否。
【错误示例】
IF($field1$>100,"是","否")
当 field1字段的值为空的时候,这个公式的计算结果是空,因为空无法和100比较。
【正确示例】
1)IF(ISNULL($field1$),"否",IF($field1$>100,"是","否"))
IF函数会按顺序执行条件表达式,ISNULL函数满足条件时,直接返回否,否则继续判断field1是否大于100。
2) IF(IF(ISNULL($field1$),false,$field1$>100),"是","否")
把field1是否为空和field1是否大于100的判断逻辑放到一个IF函数里,field1不为空时才判断是否大于100。
3)IF(AND(NOT(ISNULL($field1$)),$field1$>100),"是","否")
使用AND函数同时对field1进行判空和判断是否大于100,这种用法需要注意的是判空必须放在AND函数的最前面。
案例二:日期类型字段如何计算
【场景】
当前日期和创建日期相差几天。
【错误示例】
TODAY()-$create_time$
函数TODAY()得到当前日期,是“日期”类型数据,$create_time$是“日期时间”类型数据,是不能直接相减的。
【正确示例】
TODAY()-DATETIMETODATE($create_time$)+1
使用函数TODAY()得到当前日期,DATETIMETODATE函数将日期时间转换为日期,使用两个日期相减得到日期差额。
案例三:日期时间类型函数如何使用
【场景】
新建一个计算字段,用于计算数据的创建日期。
【错误示例】
DATEVALUE(YEAR($create_time$)+"-"+MONTH($create_time$)+"-"+DAY($create_time$))
将创建时间拆解成年、月、日,再拼装成日期,这个思路没有问题,但是如果月和日小于10的时候,会由于格式不正确而转换失败,最终计算结果返回空值,这是因为公式中支持的日期的格式是"yyyy-MM-dd",月和日小于10的时候,前面需要补0,比如“2023-07-06”。
【正确示例】
1)DATETIMETODATE($create_time$)
标准函数DATETIMETODATE已经封装好了日期时间转日期的逻辑,直接使用即可。
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$)))
判断月和日如果小于10的话,在前面补0,虽然公式很复杂,但是逻辑是正确的。
三、默认值(计算公式)和计算字段区别
3.1 使用场景
-
默认值: 为某些字段设置计算公式作为默认值,当未手动填写时将自动填充计算后的值,当字段值根据计算公式生成后也可以二次修改。如在产品定价时,可以根据成本加上预期利润率的公式来设置产品的默认售价。但是此售价仅作为参考,真实的售价还是可以根据现状再次修改为其他值的。
-
计算字段:设置计算公式根据其他字段默认生成值,使用场景和默认值使用计算公式的差异在于,计算字段用于计算后不可修改的场景中。如在发生交易时,可以根据订单金额的原币乘以汇率的公式来生成订单金额的本位币。在发生交易时的金额是很严谨的且不可修改的!
3.2 计算逻辑有什么不同?
3.2.1 新建/编辑字段时是否触发历史数据计算?
默认值:新建/编辑默认值公式后历史数据不会重新计算。
计算公式:新建/编辑计算字段的计算公式后历史数据会重新计算,但是会有一定延迟需要等待一会生效。
3.2.2 修改公式中字段后重新计算
默认值:仅在新建页/编辑页/列表页,修改公式中字段时,才会调用计算公式计算。其他操作都不会在计算(如使用UI函数、按钮执行动作等)。也就是说:默认值不一定是公式中字段计算的结果。
计算字段:不仅在新建/编辑页动态变化,在新建完成后,计算公式中的字段值变了,计算字段的值也会改变
- 总结:如果使用场景是计算结果一定要保持随公式中字段变化或希望新建字段后重算历史数据,那么请使用计算字段。
3.3 数据默认值为空或错误是什么原因?
3.3.1 公式内容错误
1.参与计算的字段值为空,或者值错误
2.公式逻辑不正确
3.3.2 默认值字段本身限制
1.默认值字段对历史数据不生效: 默认值字段只有在新建/编辑页面中参与计算的字段发生变化时才会计算;非新建/编辑页中参与计算的字段变更不计算,比如关联数据、按钮修改、导入数据、函数新建变更等,如: a.使用了统计字段,统计字段在保存数据后发生了变化 b.使用了查找关联字段的值,并在当前对象保存数据后,lookup的字段值发生了变化
2.从对象使用负责人字段作为默认值,新建页面无法计算
3.使用负责人主属部门做默认值,新建页面无法计算,编辑页如果不修改参与公式的字段也不会重新算。
3.3.3 UI事件/函数相关限制
1.2024年5月1日之前配置的UI事件函数添加/编辑从对象的数据参与了默认值公式,默认值字段不自动计算(需要配置doCalculate(true)),2024年5月1日之后配置的UI事件函数添加/编辑从对象的数据参与了默认值公式,默认值字段自动计算。
2.函数编辑过默认值字段:新建保存按钮和编辑保存按钮配置了修改默认值字段的后动作,会导致在新建完成后的默认值与新建编辑页时看到的默认值不一致。
3.3.4 权限相关限制
1.详情页复制数据时:如当前用户对该字段权限为只读或不可见是不复制的。
2.如果是有权限的默认值字段,仅复制原值,不重新计算。
3.如果字段显示且有编辑权限,那么可自行修改,不能保证和计算公式一致。
4.数据映射时:默认值字段原值映射不重新计算,如布局只读/布局隐藏/权限只读/权限不可见都可以映射回填。
3.5 单选/多选默认值在新建编辑页不回填的原因
3.5.1 选项默认值不生效原因
公式里用到的单选/多选字段的value值与当前字段的不一致导致。
3.5.2 选项默认值匹配规则
默认值公式的值必须等于配置默认值公式的选项的value值
- 实例化说明
选项2的默认值=选项1的label+value
选项1:被默认值公式使用选项(选项值对应 选项值apiname(label 对应 value)a对应1,b对应2,c对应3 )
选项2:配置默认值公式的选项
若前台在选项1中选择了a,如果在选项2中的value中没有找到a1,前台的选项2的默认值就不回填
3.5.3 选项默认值设置具体实例
四、计算字段常见问题及排查方法
4.1 计算延迟导致的计算字段值为空
4.1.1 场景举例
用户疑问:为什么在后台更新【报价单明细】中“报价折扣”这个计算字段后,并且试算成功有值,但是前端界面查看时,有的数据中“报价折扣”字段未显示值,给人感觉是计算字段不计算,这个是什么原因。
4.1.2 排查方法
- 通过查看审计日志或者和管理员确认该计算字段是否是新建或者是重新编辑过的,此时计算字段会重新计算历史数据,但是当数据量较大时延迟会比较久,就会导致查看数据时可能还没计算完历史数据的情况,建议耐心等待几小时或者一天时间在查看。
- 可以查看修改记录,看是否有批量导入或者使用按钮等批量修改数据的情况,当有批量导入或者使用按钮等批量修改数据的情况,这种增量计算也会有延迟。如果该对象没有配置修改记录,建议联系管理员在CRM日志中排查是否是这类原因引起的计算延迟。
4.2 被函数覆盖导致的计算字段值错了
4.2.1 可能原因:
计算字段在计算服务算出来是正确的,但是可能会被工作流、UI函数等后续函数并发更新给覆盖掉
4.2.2 排查方法:
建议查看修改记录排查一下(建议联系实施排查),如果新建/编辑数据后有配置工作流、后动作函数、UI函数等,需要修改下函数修改方案:
Fx.object.batchUpdate(<String apiName>,<Map objects>)
Fx.object.batchUpdate(<String apiName>,<Map objects>,<List fields>)
即使用增量的批量更新,fields参数表示需要更新的字段列表,如果不指定字段更新则是增量更新,可能会覆盖其他字段。
建议如使用了函数,可将函数中把被统计的字段或者计算字段的数值源更新为和前端设置的小数位(四舍五入)后的数值;
4.3 导入数据的小数位数导致的计算字段值错了
4.3.1 场景举例
利润=(单价-成本)*数量。利润字段设置的小数位是 2 位,而通过函数更新或者数据导入等方式得到的成本=4.50,收入=4.594 ,数量=4。计算出来是利润=0.376,但数据库先四舍五入在存储,存储后数据库里利润=0.38,计算完后【收入】存到数据库四舍五入=4.95,前端显示 收入=4.95,利润=0.38。这时会产生疑问如果使用4.95计算出来的利润应该是0.376。
4.3.2 排查方法
查看是否使用了导入(查看导入导出记录)或函数批量更新数据(找实施),比如:前端设置的小数位是2位,函数更新或者数据导入等方式进入的数据小数位不是2位,则会引起该问题;数据库中数值实际要大于前端展示的数值;
4.4 计算字段值显示有误
4.4.1 问题原因
- 计算字段配置有误导致显示结果和预期有区别。
4.4.2 排查方向
- 检查计算字段的公式内容是否正确。
4.5 数据在列表页或详情页管理员看到的计算字段值和普通员工看到的不一样
4.5.1 问题原因
这种情况可能是普通员工从复制进入新建编辑页面;管理员有参与计算的字段的编辑权限,此时参与计算的字段是管理员手动写入值的,此时计算字段参与计算; 如普通员工没有参与计算的字段的编辑权限,复制数据时参与计算的字段是UI事件回填的,则计算字段不参与计算,依旧显示复制时的值。
4.5.2 排查方法:
- 请确定普通员工是否有计算字段的编辑权限;
- 参与计算的字段是否为UI事件回填的。
4.6 怎么识别计算字段变化了
4.6.1 通过审计日志查看计算字段描述变更
4.6.1.1 场景举例:
用户期望查看谁在什么时间,新建了计算字段,删除了计算字段,改变了计算字段的千分位显示,改变了计算字段的计算公式。
4.6.1.2 操作说明:
先进入审计日志。审计日志入口:管理后台-企业日志-审计日志
在审计日志界面的操作模块选择【自定义对象管理】。在这个界面使用ctrl+F,并输入对象名称查找,可查看计算字段何时被谁新建,编辑,删除。
4.7 在BI报表中维度如何使用计算字段
4.7.1 请先确定BI报表可以使用计算字段进行数据计算和分析
当计算公式中引用全局变量(当前日期、当前时间、当前日期时间)、人员对象下的字段和使用NOW() 、TODAY()函数时,将不支持该计算字段在系统任何地方被筛选(该计算字段不支持作为BI报表的维度),不支持该计算字段被统计字段、计算字段引用。
4.7.2 如何在BI报表使用计算字段
在【维度】处点击【设置】,选择计算字段即可将计算字段做为报表维度。
4.8 计算字段是否可以直接统计到其他字段中的内容
- 操作说明:计算字段无法直接统计到其他字段的内容,可以在计算公式的插入字段里面选择统计字段,根据统计结果配置计算公式,如果对涉及到主从关系和查找关联关系的统计字段引用产生疑问可以查看【计算/统计互算的层级限制】
4.9 计算字段如何统计文字的个数
4.9.1 计算字段如何统计到其他字段内容中文字的个数
- 操作说明:可以在计算公式中插入函数”LEN“。将LEN(string)中的string换成需要统计字段内容的字段apiname。
注意:如果想要统计到前台看到的单选字段内容中文字的个数,需要选择含label的apiname。
4.10 什么情况下计算字段不能被引用
4.10.1 关于不落地的计算字段的引用问题
当计算公式中引用全局变量(当前日期、当前时间、当前日期时间)、人员对象下的字段和使用NOW() 、TODAY()函数时,该计算字段的计算结果不会被存入数据库即计算字段不落地。将不支持该计算字段在系统任何地方被筛选(该计算字段不支持作为BI报表的维度),不支持该计算字段被统计字段、计算字段引用。
4.10.2 落地的计算字段为什么不能被计算字段,统计字段,默认值计算公式引用
当计算公式中没有引用全局变量(当前日期、当前时间、当前日期时间)、人员对象下的字段和使用NOW() 、TODAY()函数时,该计算字段的计算结果会被存入数据库即计算字段落地。此时若计算字段不能被计算字段,统计字段,默认值计算公式引用,说明该计算字段涉及计算/统计互算的层级限制。
4.11 关于计算字段的时效性
4.11.1 计算字段是实时更新的吗
不落地的计算字段是在查询数据的时候实时计算的,落地的计算字段是在后台程序队列中异步计算的,不是实时更新,因此存在一定的延迟,延迟的时间和队列中排队的任务数有关,购买了独立数据库的租户会分配独立的计算队列。
4.11.2 对于多条数据计算字段的时效性
1.计算字段是新建或者是重新编辑过的,此时计算字段会重新计算历史数据,但是当数据量较大时延迟会比较久
2.批量导入或者使用按钮等批量修改数据的情况,这种增量计算也会有延迟
4.11.3 对于单条数据计算字段的时效性
当计算字段引用的字段开始编辑时,计算字段开始计算。
4.12 关于计算字段的时区
4.12.1 计算字段中的日期时间是取的北京时间还是系统的当地时间
对于灰度了多时区的租户,计算公式中的日期时间是取的租户时区的时间,没有灰度多时区的租户取的是服务器的默认时区的时间(一般是东八区)。