1. 自定义对象
  2. 通过公式计算字段值

什么是公式?

公式实例

Total_Pay = 
IF(Total_Hours__c <= 40, Total_Hours__c * Hourly_Rate__c, 
40 * Hourly_Rate__c + 
(Total_Hours__c - 40) * Overtime_Rate__c)

公式中的元素

公式可以包含对字段值、运算符、函数、文字表示值或其他公式的引用。使用任意或所有这些元素构建公式。

文字表示值

您输入的未经计算或更改的文本字符串或数字。

例如,如果您有一个总是要乘以金额的 2% 的值,公式将会包含该金额的 2% 的文字表示值:

ROUND((amount*0.02), 2)

此示例包含公式每个可能的部分:

  • 一个称为 ROUND 的函数,用于返回一个数值舍入为指定小数位数的数值。
  • 名为“金额”的字段引用。
  • 一个运算符 *,告诉公式生成器用文字表示值 0.02 乘以金额字段的值。
  • 一个文字表示数值 0.02。对所有百分数使用小数值。要在您的公式中包括实际文本,应将其括在引号内。
  • 此公式中的最后一个数字 2 是确定要返回的小数位数的 ROUND 函数所需的输入。

函数

函数即系统定义的公式,可能需要您的输入值,并返回一个或几个值。例如,TODAY() 不需要输入值,但会返回当前日期。TEXT(value) 函数需要您输入百分比、数字或货币并返回文本。

运算符

一个符号,指定要执行的计算类型或其执行顺序。例如,“+”号指定两个值应相加。左括号和右括号指定想要先计算的表达式。

字段引用

使用合并字段引用另一个自定义字段或标准字段的值。

合并字段的语法对于标准字段是 field_name,对于自定义字段是 field_name__c。相关对象上合并字段的语法是 reference_to_field_name.field_name,必要时可在您的公式中插入合并字段,并且理论上支持无限层次的扩展引用,比如三层引用写法为reference_to1_field_name.reference_to2_field_name.field_name

支持引用当前登录用户相关字段,写法是以$user开头来表示当前登录用户的引用,并用点符号来连接后续要扩展引用的属性,比如$user.name表示引用当前用户的名称,$user.organization.name表示引用当前用户所属组织的名称。

要引用关联字段指向的记录id只要用点符号来连接_id即可,比如reference_to_field_name._id$user._id

除了可以用 $user 开头的表达式来引用当前登录用户信息,还可以用 $userSession 开头的表达式来引用当前登录用户的 UserSession,详情请参阅 如何创建公式字段 - $userSession

跨对象引用

公式在服务端执行,因此可以在公式中引用当前记录相关表中的数据。

例如以下语法可以引用付款记录对应的合同记录对应的客户名称。

  payment.contract.account.name

公式中的运算符和函数

在构建公式时可以使用很多运算符和函数,请参考:公式中的运算符和函数

在哪些地方可以使用公式?

华炎魔方的许多地方都可以使用公式。开始使用公式之前,请了解其用法的差别。

  • 批准过程: 定义记录必须满足才能进入批准过程的条件。
  • 批准步骤: 定义记录必须满足才能进入批准步骤的条件。
  • 字段默认值: 在用户创建记录时向自定义字段应用一个值。使用公式可以定义默认值。用户可以更改默认值。默认值可以由使用您指定的值、合并字段或表达式的公式确定。
  • 公式字段: 使用您指定的值、合并字段或表达式。自动计算自定义字段的值。用户不能更改公式字段的值。
  • 验证规则: 防止用户在标准/自定义字段中输入无效值。验证规则可以基于公式,并在用户输入无效值时,向用户显示出错消息。
  • 字段更新: 自动将字段值更改为您指定的值。公式中可以包括其他值、合并字段或表达式。可以将字段更新设置为因工作流规则或批准过程而发生。
  • 工作流规则: 定义记录触发工作流规则时必须满足的条件。
用法何时执行?只读?可以指定空处理?
批准过程记录提交待批准不适用
批准步骤记录提交待批准不适用
字段默认值创建记录时
公式字段记录被保存后
验证规则记录被保存前不适用
字段更新工作流或批准过程中不适用
工作流规则保存记录时不适用

公式返回的数据类型

公式的数据类型决定预期从公式返回的数据的类型。

  • 文本: 返回字符串。除公式输出外,若还要显示文本,请将该文本放入引号中。对文本、多行文本、网址、邮件地址和自动编号等字段使用文本数据类型。
  • 布尔: 返回 true(真) 或false(假)。该字段在记录详细信息页面和报表中显示为复选框。使用 true 作为选中值,使用 false 作为未选中值。
  • 金额:  只能输入数值内容,默认2位小数,也可以指定小数位数。
  • 日期: 返回代表日历中某一天的日期。当前日期可通过在公式中调用内部函数 TODAY() 获得。
  • 日期时间: 返回表示时间中某一时刻的数据。日期时间字段包括日期,还包括由小时、分钟和秒组成的一天中的时刻。您可以使用 NOW() 函数在公式中插入当前日期和时间。
  • 数字: 返回正负整数或小数(最多 18 位)。华炎魔方对公式字段使用四舍五入平分规则。例如,12.345 变为 12.35 和 -12.345 变为 -12.35。
  • 百分比: 返回后跟百分号的百分比格式数字(最多 18 位)。百分比数据存储为小数,值为除以 100 后得到的小数,即 90% 等于 0.90。
  • 时间(暂不支持): 返回表示时间中某一时刻的数据,没有日期。时间字段包含小时、分钟、秒和毫秒的时间。您可以使用 TIMENOW() 函数在公式中插入当前日期。

如何创建公式字段

  • 按照与创建自定义字段相同的方式开始构建一个公式字段,字段类型选择公式。
  • 选择公式的数据类型。根据计算的输出值为您的公式选择适当的数据类型。
  • 选择数值、金额或百分比数据类型的小数位数,数字长度最长为18位数。
  • 如果您的公式引用任何数字、金额或百分比字段,则应选择一个选项以处理空白字段。
  • 可以在公式中引用当前对象上的“相关表”或“主表/子表”字段来实现跨对象公式。
  • 可以在公式中输入_id来引用当前记录的id值。
  • 可以在公式中输入$user变量来引用当前登录用户的相关信息。
  • 也可在描述框中输入公式字段描述,单击保存完成操作。

重算公式值

对于已经存在的历史记录数据,很多情况下公式字段值不会重新计算,此时您应该选择公式字段后台详细配置页面上的“重算公式值”按钮来手动重新计算该值。这些情况包括但是不限于以下情况:

  • 更改公式字段定义(如小数位数,公式内容,数据类型、空白字段处理等)。
  • 更改在公式内容中引用字段的相关属性,比如更改其字段类型、小数位数,更改其公式字段的数据类型、公式表达式或其他属性等。

在正式环境中请谨慎修改对象的某些字段属性,比如字段类型,字段公式表达式,下拉选择框可选项列表等,因为对于已经存在的历史记录数据可能不会重新触发字段值重算,对于公式字段值,只能通过手动操作这里的“重算公式值”按钮来修正历史数据。

使用日期和日期时间公式字段的提示

  • 日期和日期时间字段不能交替使用。名称本身不能表示某个字段是日期还是日期时间。例如,创建日期和上次修改日期是日期时间字段,而上次活动日期是日期字段。使用 DATEVALUE 函数可将日期时间字段转换为日期字段。
  • 将加和减运算符与日期或日期时间字段结合使用来计算持续时间。例如,从一个日期中减去另一个日期来计算两者之间相差的天数。同样,您可以从一个日期时间中减去另一个日期时间,获得以数字表示的两者之间相差的天数。有关建议的使用方法,请参阅NOW 或TODAY
  • 将加和减运算符与数字结合使用,返回其他日期或日期时间。例如,CreatedDate + 5 计算记录的创建日期之后五天的日期和时间。注意,表达式返回的数据类型与给定的数据类型相同;日期字段加上或减去某个数字会返回日期,日期时间字段加上或减去某个数字会返回日期时间。
  • 在使用小数计算日期时,公式会忽略小数点后的所有数字。例如:
  • 公式TEXT(TODAY())将返回当天的日期字符串,比如2020-09-30, TODAY是按utc时间取日期,这点跟TODAY()一样。
    • 公式TODAY() + 1将返回当天日期+1天的日期值,即可以直接用+号运行运算。
    • 公式TODAY() + 0.7将返回当天的日期值,而不是+1天的日期值,因为日期计算时小数部分会被忽略只取整数部分,公式TODAY() + 1.2将返回当天日期+1天的日期值。
    • 公式TODAY() + 1.5 + 0.5或TODAY() + 0.5 + 1.5将返回当天日期+1天,而不是+2天的日期值,因为日期计算时所有的小数都部分都会被忽略不会累加,正确的写法是用括号让数值先计算:TODAY() + (1.5 + 0.5)。
    • 公式NOW() + 1.1将返回当前时间增加1.1天后的时间值,即增加1天2小时24分(1天的0.1)。就是说时间类型是支持小数点计算的,单位是天。
    • 公式T1 - T2,如果以上两个日期时间字段值之差是 5.52,将意味着两个值分隔 5 天、12 小时(1 天的 0.5)和 28 分钟(1 天的 0.02)。 要先计算两个小数的值,应该用括号将它们组合在一起。例如:
    • TODAY() + 0.5 + 0.5 与 TODAY() + 0 + 0 相同,即今天的日期。
    • TODAY() + (0.5+0.5) 与 TODAY() + 1 相同,即明天的日期。 关于时区,请参考在公式中使用日期、日期时间和时间值

使用数字公式字段的提示

  • 在公式中使用百分比字段时,使用百分比的小数形式。例如,IF(Probability =1...) 表示 100% 可能性,IF(Probability =0.9...)表示 90% 可能性。
  • 在公式中将自动编号字段作为文本字段引用。
  • 您的公式的输出值必须小于 18 位数。
  • 公式中可以包含数字、百分比和货币的混合:AnnualRevenue / NumberOfEmployees
  • 公式运算时把公式引用的其他字段作为变量传入以及华炎魔方界面显示公式字段时,都会识别字段上设置的小数位数,并使用四舍五入平分规则处理公式字段值。例如,12.345 变为 12.35 和 −12.345 变为 -12.35。但是公式字段本身的输出值不受这里设置的小数位数影响,所以公式中应该使用。
  • ROUND函数来处理计算结果的小数位数。
  • 要视任意空白字段为零值,请选择将空白字段视为零。要将这些字段留空,请选择将空白字段视为空白,在华炎魔方低代码中该属性默认为“空白字段视为零”。

使用文本公式字段的提示

  • 要在公式字段中插入文本,用引号将文本引起来。例如,要显示“CASE: 123”,使用本公式 “CASE: “& CaseNumber__c.
  • 在引号或反斜线之前使用反斜线 ( \ ) 字符,可在您的输出值中将其插入为文字值。例如,公式中的“Trouble\ \Case \"Ticket\": ” 会在详细信息页面显示 Trouble\Case “Ticket”:(暂不支持,即目前无法在公式中编写带引号或反斜线的字符串)

使用布尔公式字段的提示

部分函数是不支持输出boolean类型值的,已知不支持的函数有 BLANKVALUECASEIF

比如以下公式配置会报错:

IF(location_type = 'Van', true, false)

应该使用ocation_type = 'Van'来简化该公式。

同样的,以下公式配置也会报错:

CASE(Days_Open__c, 1,  true,false)

应该使用Days_Open__c = 1来简化该公式。

使用选项列表公式字段的提示

在公式中使用select字段类型时,有单选和多选两种,分别对应到公式中的单选选项列表picklist和多选选项列表multipicklist这两种数据类型,只有少量公式函数支持这两种数据类型。

支持单选选项列表的函数

  • ISPICKVAL: 将选项列表的值与单个值进行比较。
  • CASE:将选项列表的值与多个值进行比较。
  • TEXT:返回选项列表值的 API 名称,以便您可在支持文本值的函数(例如 CONTAINS)中使用对值的引用(即使显示值已更改)。
  • ISBLANK:判断字段值是否为空。

支持多选选项列表的函数

  • INCLUDES:决定多选选项列表字段中选择的任何值是否等于您所指定的文本文字。
  • ISBLANK:判断字段值是否为空。

跨对象公式

我们有时需要在当前对象上通过公式字段来引用其他关联对象上的字段值,这种跨越两个及以上的对象的公式我们称为跨对象公式。

可以在当前对象上配置“相关表”或“主表/子表”类型的字段来引用其他对象,相关规则请参考之前 主键/外键字段 小节,跨对象公式就是通过在公式中引用当前对象上这两种字段型,然后进一步引用其关联对象上的字段来实现跨对象公式。

跨对象公式一般形如fieldNameA.fieldNameB,其中fieldNameA是当前对象上的“相关表”或“主表/子表”字段名称,fieldNameBfieldNameA字段关联到的对象上的某个字段名称,比如联系人对象上有一个名为“所属客户”(account)的“主表/子表”字段,引用了对象“业务伙伴”(accounts),我们可以在联系人对象定义一个公式字段来输出联系人所属客户的网址,该公式字段的公式表达式应该配置为account.website

可以在跨对象公式中用点符号连接各级对象上的外键字段以形成引用链,理论上支持无限层次的引用,但是出于性能考虑请避免引用层级过多,比如上面提到的联系人对象上可以配置公式account.created_by.name表示输出联系人所属客户的记录创建人的名称。

需要注意的是,跨对象公式最后一个引用链不可以是外键字段,即不可以是相关表”或“主表/子表”类型的字段,比如上面提到的联系人对象上的公式如果配置为account.created_by是表示输出联系人的创建人,但是这是不合法的,因为created_by是一个外键字段,它指向了关联创建人整条记录,而不是只输出关联创建人的某个字段值,所以正确的写法是需要再向created_by这个外键字段进一步扩展引用其下一级对象的字段,比如上面提到的account.created_by.name就是一个合法的跨对象公式。

如果是想让公式输出外键字段值本身,可以在最后扩展引用下其关联对象的主键字段(即_id)即可,也就是把公式表达式写成account.created_by._id就可以输出联系人所属客户的创建人_id值。

$user

可以在公式中输入$user 变量来引用当前登录用户的相关信息,作为跨对象公式的一种,你也应该在其后用点符号来扩展引用链,$user指向的是space_users表而不是users表,所以只能从 space_users 表中外键字段开始扩展其引用链,比如$user.organization.owner.name,更多可扩展属性请参考 space_users对象源码

$userSession

在公式中输入$userSession 变量是引用当前登录用户信息的另一种方式,与 $user 变量不同,它是一个指向 userSession 的变量,而 $user 是一个指向space_users表的跨对象公式。

比如$userSession.roles可以获取当前用户所属权限集,$userSession.is_space_admin可以获取当前用户是否是工作区管理员,更多属性请参考文档 userSession

关于公式级联触发的提示

  • 在一个公式字段A被另一个公式字段B引用的情况下,当某种原因触发字段A更新重算后,会级联触发公式字段B也更新重算。
  • 当多个公式字段之间存在多层级联引用的情况下,其中一个字段被触发更新重算的话,会逐层触发级联更新重算。
  • 如果累计汇总字段汇总的是一个公式字段,那么当公式字段值变更时,会触发该汇总字段重新汇总更新值。
  • 如果累计汇总字段被一个公式字段引用,那么当汇总字段被更新时,也会触发该公式字段更新重算。
公式字段之间如果出现循环引用的话,华炎魔方是能智能识别并阻止相关字段配置生效的。

累计汇总计算

累计汇总字段会自动计算相关记录中的值。您可以创建累计汇总字段,使其值基于主表/子表关系中某个子表的字段值汇总,并在主记录中显示该汇总结果。子表记录必须通过主表/子表直接与主记录相关。例如,您要在客户的发票相关列表中显示所有相关发票自定义对象记录的发票总金额。您可在名为“发票总金额”的自定义金额字段中定义这一汇总信息。

可以使用累计汇总字段执行不同类型的汇总计算。比如可以计算与主记录相关的子记录的数量,也可以计算子记录中字段的总和、最小值或最大值。

创建累计汇总字段

在对象(位于主表/子表的主侧)上定义累计汇总字段。

如果关系已经不存在,请首先在子表侧创建一个主对象与子对象之间的主表/子表关系,用于表示正在汇总的记录的值与被汇总的记录之间的关系。

在您希望显示累计汇总字段值的对象上新建字段。 汇总字段汇总了相关对象上的记录中的值,因此该对象(您在上面创建了该字段)应位于主表/子表关系的主侧。

  • 所属对象:即主表/子表关系中的主对象。
  • 显示名称:希望该汇总字段显示的名称。
  • 字段名:该字段的唯一性api名称。
  • 字段类型:请选择“累计汇总”。
  • 默认值:因为字段值是计算得出的,所以默认值在此处无效。
  • 字段分组:希望该字段显示在哪个分组上。
  • 精度:数值字段的精度。
  • 小数位数:希望该汇总结果保留的小数位数。
  • 要汇总的对象:选择主表/子表关系中子表上的对象,该对象包含您要汇总的记录。
  • 汇总类型:
    • COUNT:汇总子表一共有多少条记录,返回记录总条数。
    • SUM:对在“要聚合的字段”选项中选择的字段的值进行累加汇总。仅数字、金额和百分比字段类型可用。
    • AVG:对在“要聚合的字段”选项中选择的字段的值进行总和平均值计算。仅数字、金额和百分比字段类型可用。
    • MIN:对在“要聚合的字段”选项中选择的字段的值进行大小比较并取出最小值。仅数字、金额、百分比、日期和日期时间字段可用。
    • MAX:对在“要聚合的字段”选项中选择的字段的值进行大小比较并取出最大值。仅数字、金额、百分比、日期和日期时间字段可用。
  • 要聚合的字段:请选择子表上的某个字段,这个字段就是要进行SUM/AVG/MIN/MAX进行聚合计算的字段。对于除COUNT外的其他汇总类型,此项必填,反之不需要填写该字段。
  • 过滤条件:如果要在汇总计算时,只包含特定的记录组,请在过滤条件中输入筛选条件,比如只汇总2021年1月1号早上8点前创建的记录。
  • 其他:勾选上需启用的功能开关等,单击保存结束操作。

汇总时过滤条件

如果要在汇总计算时,只包含特定的记录组,可以在过滤条件中输入对应的筛选条件。

  • 这些过滤条件过滤的是子表记录而不是主表记录。
  • 字段输入框中列出的是子表对象中可用于过滤的字段名称供选择。
  • 运算符输入框中列出的是基于左侧选中字段的字段类型所支持的过滤条件运算符,比如字符类型的字段有“包含”运算符,而金额类型没有。
  • 值是一个纯文本输入框,当左侧字段类型不同时,请按不同的输入规范输入文本字符:
    • 数值、金额、百分比:请输入合法的数值,比如1.2,3000。
    • 布尔:请输入"true", "True", "TRUE", "1"表示真,或输入"false", "False", "FALSE", "0"表示假。
    • 日期:请输入类似2020-02-12格式的值,它表示的值是2020-02-12T00:00:00.000Z,即这里转换为按utc的0点时间值来过滤。
    • 日期时间:请输入类似2020-02-12 12:00格式的值,它表示的值是2020-02-12T04:00:00.000Z,即这里会按当前时区转换为utc时区下的时间值来过滤。
    • 相关表:请输入记录的_id值,比如rbNxQ3mK6CFs8LWbr要表示要引用记录的ID值。
    • 主表/子表:同相关表。
    • 其他:按文本值过滤。
  • 可以输入多个过滤条件,最终会按AND逻辑连接输出这些条件,不支持按OR或更复杂的逻辑过滤。

华炎魔方低代码支持更丰富的过滤条件设置,比如支持按OR逻辑过滤,支持多个OR或AND嵌套使用,详情请参阅:筛选条件

批量重算汇总值

对于已经存在的历史记录数据,很多情况下累计汇总字段值不会重新计算,此时您应该选择累计汇总字段后台详细配置页面上的“批量重算汇总值”按钮来手动重新计算该值。这些情况包括但是不限于以下情况:

  • 更改累计汇总定义(如对象、要聚合的字段、汇总类型、过滤条件等)。
  • 更改在累计汇总字段“要聚合的字段”中引用字段的相关属性,比如更改其字段类型,更改其公式字段的表达式等。

在正式环境中请谨慎修改对象的某些字段属性,比如字段类型,字段公式表达式,下拉选择框可选项列表等,因为对于已经存在的历史记录数据可能不会重新触发字段值重算,对于累计汇总字段值,只能通过手动操作这里的“批量重算汇总值”按钮来修正历史数据。

实施提示

  • 可在所有具有主表/子表关系的主侧对象上创建累计汇总字段,无论两侧对象是标准对象还是自定义对象。
  • 当某个对象上无法创建累计汇总字段时,请先在该对象的子表上创建主表/子表关系。
  • 累计汇总字段中能够计算的字段类型取决于汇总类型及其要聚合的字段的字段类型。例如:
    • 当选择 SUM 或 AVG 作为累计类型时,数字、金额和百分比字段均可用。
    • 当选择 MIN 或 MAX 作为累计类型时,数字、金额、百分比、日期和日期时间字段均可用。
    • 当选择COUNT作为累计类型时,将直接汇总子表记录条数总合而与子表的字段无关,不需要选择“要聚合的字段”。
  • 有时,您无法更改您在累计汇总字段中引用字段的字段类型,这是因为累计汇总字段中能够计算的字段类型依赖于要聚合的字段的字段类型,华炎魔方暂时未处理此类逻辑校验,请谨慎随意变更正式环境中的字段类型。
  • 在对象上创建了累计汇总字段后,不能将该汇总字段依赖的子表对象中的主表/子表类型字段的字段类型变更为相关表或其他字段类型,华炎魔方暂时未处理此类逻辑校验,请谨慎随意变更正式环境中的字段类型。
  • 累计汇总字段可以引用公式字段,即“要聚合的字段”可以选择公式字段类型的字段,当公式值变更后会触发累计汇总字段重新汇总计算并更新字段值。
  • 公式字段中也可以引用累计汇总字段,当累计汇总字段值变更时会重新触发相关公式字段重算其字段值。
  • 就目前来说,累计汇总字段中引用了包含派生即时值的跨对象字段引用或函数(如 NOW 或 TODAY的)公式字段时,华炎魔方按普通公式的方式处理,不加以区别对待,但是您不应该这么配置,这不只是实际需求中不应该有这种逻辑,更是因为这种配置会带来性能方面的极大损耗。
  • 就目前来说,累计汇总字段值变更时,不会重新触发引用了该汇总字段的工作流规则、验证规则或其他自动规则中的公式计算。
  • 在正式环境中请谨慎修改对象的某些字段属性,比如字段类型,字段公式表达式,因为对于已经存在的历史记录数据可能不会重新触发字段值重算,详情请参考批量重算汇总值
  • 计算累计汇总字段值可能需要 30 分钟或以下,取决于受影响的记录的数量和其他因素。
  • 如果验证规则中引用了累计汇总字段,当汇总字段值在变更时也不会触发执行验证规则,比如主记录有一个验证规则,要求累计汇总字段值必须小于100。如果用户对相关子记录的更改将输入超过 100 的值,希望用户无法保存该子表记录,实际上子记录变更时主记录的验证规则是不会被触发的,要实现这个需求,通常的做法是把验证规则配置在子表而不是主表中,类似:lookup_mater_object_field.summary_value + current_value >= 100。

最佳实践

  • 如果不想让用户看见累计汇总字段计算值,可以将字段设置为隐藏字段。详细记录上用户不能看见的字段仍然会在累计汇总字段中被计算。
  • 如果具有验证规则,请考虑它们将如何影响累计汇总字段。子表记录中的值发生变更时,主表记录的累计汇总字段的值也会发生变更。所以保存主表/子表记录时会显示一个验证错误,请参考上述实施提示最后一条。
  • 请注意从子表字段引用主表累计汇总字段与从主表字段引用自身的累计汇总字段是有区别的。从子记录引用的累计汇总字段可能拥有过时值,因为子记录保存时父记录尚未更新。但是,从父级记录中引用累计汇总字段的话,虽然累计汇总字段将始终拥有最新的更新值,但是子记录变更时主记录的验证规则是不会被触发的,请参考上述实施提示最后一条。
  • 创建累计汇总字段之前,请规划其实施。一旦创建,就不能更改所选详细对象,也不能删除累计汇总定义中引用的任何字段。
  • 创建累计汇总字段之前,请规划其实施。特别是在生产环境中,一旦产生有价值的历史数据,再修改对象的某些字段属性,比如字段类型,字段公式表达式的话,就需要手动执行批量重算汇总值来修正历史数据,这将增加不确认性风险。
  • 累计汇总字段中不允许自动派生字段,如当前日期或当前用户。禁止字段包含可动态派生值的函数(如 DATEVALUE、NOW 和 TODAY)的公式字段。累计汇总字段中也不允许包含相关对象合并字段的公式字段。
  • 应该适当配置 字段索引 以提升数据查询速度,这样可以明显提高累计汇总功能的整体性能。

在公式中使用日期、日期时间和时间值

日期使用了两种数据类型:日期和日期时间。数据类型时间不包括日期值,例如工作时间。处理日期时使用的大部分值都是日期数据类型,存储年、月和日。CreatedDate 等一些字段是日期时间字段,意味着它们不仅存储日期值,而且还存储时间值(以 GMT 存储,但以用户的时区显示)。当在记录详细信息页面查看时,日期、日期时间和时间字段以用户的区域设置格式化。时间值的精度以毫秒为单位。日期时间值的精度以秒为单位。

您可在日期、日期时间和时间值上使用加和减等运算符,以计算未来日期或两个日期或时间之间的已过去的时间。例如,如果您将一个日期减去另一个日期,由此得出的值将是两个初始值之差(天)(数字数据类型)。两个日期时间值之间的同一操作将返回十进制值,表示天、小时和分钟数之差。两个时间值的相同操作会返回毫秒。

例如,如果两个日期时间值之差是 5.52,这意味着两个值分隔 5 天、12 小时(1 天的 0.5)和 28 分钟(1 天的 0.02)。您还可以添加数字值到日期和日期时间。例如,操作 TODAY() + 3 将返回今天日期后的三天。

在整个示例中,使用了变量日期和日期时间以代替实际日期和日期时间字段或值。

today()、now() 和 timenow()

  • TODAY() 函数以日期数据类别返回当前日、月和年。对于希望了解自上一天过去的天数、未来某些天数中的日期或仅仅希望显示当前日期的公式,本函数非常有用。
  • NOW() 函数返回当前时刻的日期时间值。当关心当天的特定时间以及日期时,这将非常有用。
  • TIMENOW() 函数会返回 GMT 的值,并表示不带日期的当前时间。如果您需要当前小时、分钟、秒或毫秒,使用此函数,而不是 NOW() 函数。此值对跟踪时间(例如轮班或经过时间)有用。

有关如何在日期值和日期时间值之间转换的详细信息,请参阅 在日期时间和日期之间转换

date()函数

DATE() 函数返回日期值,给定年、月和日。数字 Y/M/D 值和 YEAR()、MONTH() 和 DAY() 函数是 DATE() 的有效参数。例如,DATE( 2013, 6, 1 ) 返回2013 年 6 月 1 日。同样,DATE( YEAR( TODAY() ), MONTH( TODAY() ) + 3, 1) 返回当年今天起三个月的第一天的日期值,假定该日期有效(例如,月份在 1 和 12 之间)。

如果输入的 Y/M/D 值导致无效的日期,DATE() 函数并不会报错,而是会返回一个可能错误的值,比如非闰年的DATE(2021,2,29)将返回2021-03-01,DATE(2021,121,29)将返回2031-01-29,因此错误检查是使用日期值的重要部分。您可在示例日期格式中阅读有关处理无效日期的方法。

在日期时间和日期之间转换

日期和日期时间是不可交换的数据类型,因此在日期和日期时间值之间执行操作时,您需要转换这些值,使它们具有相同的类型。一些函数(如 YEAR()MONTH() 和 DAY())还仅适用于日期值,因此必须首先转换日期时间值。

使用 DATEVALUE( datetime ) 函数返回日期时间的日期值。例如,要从日期时间获取年,使用 YEAR( DATEVALUE( datetime ) )

您可以使用 DATETIMEVALUE( TEXT(date) ) 函数将日期值按GMT时区转换为日期时间。时间将设置为格林威治标准时间 (GMT) ,然后显示时会按用户所有时区显示。对于北京时间,DATETIMEVALUE( TEXT(TODAY()) ) 将返回当天的utc0点,华炎魔方界面上将显示为当天的上午8:00而不是当天的 00:00。有关详细信息,请参阅有关日期时间和时区的备注

在日期时间和时间之间转换

TIMEVALUE() 函数返回的时间数据类型值的格式为 24 小时制的“HH:MM:SS.MS”(hours:minutes:seconds.milliseconds)数字 H/M/S/MS 值和 HOUR()、MINUTE()、SECOND() 和 MILLISECOND() 函数是 TIMEVALUE() 的有效参数。

使用 TIMEVALUE(text) 函数,把文本值、文本类型合并字段或表达式转换为时间类型。例如,使用 TIMEVALUE(LPAD(TEXT(HOUR(ClosedDate)), 2, "0") & ":" & LPAD(TEXT(MINUTE(ClosedDate)), 2, "0") & ":" & LPAD(TEXT(SECOND(ClosedDate)), 2, "0") & "." & LPAD(TEXT(MILLISECOND(ClosedDate)), 3, "0")) 从 ClosedDate 日期时间值中提取时间。

在日期和文本之间转换

如果希望将日期作为字符串一部分包含,在 TEXT() 函数中包含日期值以转换为文本。例如,如果希望将今天的日期转换为文本,使用: "Today's date is " & TEXT( TODAY() )

这将以格式“YYYY-MM-DD”而不是取决于区域设置的格式返回日期。先从日期中提取日、月、年,然后按所需格式重新组合,即可更改公式。例如: "Today's date is " & TEXT( MONTH( date ) ) & "/" & TEXT( DAY( date ) ) & "/" & TEXT( YEAR( date ) )

您还可以将文本转换为日期,以便将字符串值与您的其他日期字段和公式一起使用。您将希望文本的格式为“YYYY-MM-DD”。使用本公式以返回日期值: DATEVALUE( "YYYY-MM-DD" )

在日期时间和文本之间转换

您可使用 TEXT() 函数在字符串包含日期时间值,但需要小心时区。例如,考虑本公式: "The current date and time is " & TEXT( NOW() )

在本公式中,NOW() 偏移到 GMT。通常,NOW() 将在查看时转换成用户的时区,但由于被转换为文本,因此转换不会发生。因此,如果您在 8 月 1 日北京时间 (GMT-10) 下午6点 执行本公式,结果是“The current date and time is 2021-08-01 10:00:00Z”。

当将日期时间转换为文本时,将在最后包含“Z”以表示 GMT。

要将字符串转换为日期时间值,使用 DATETIMEVALUE() 将以“YYYY-MM-DD HH:MM:SS”的格式传输字符串。本方法将返回 GMT 的日期时间值。

在时间和文本之间转换

如果您想要将时间作为字符串的一部分包含,在 TEXT() 函数中封装时间值,以将其转换为文本。例如,如果您想要将当前时间返回为文本,使用: "The time is " & TEXT( TIMENOW() ) 此函数会返回格式为“HH:MM:SS.MS”的时间。

您也可以将文本转换为时间数据类型,以便将字符串值与其他时间字段和公式一起使用。按 24 小时制将文本格式化为“HH:MM:SS.MS”。使用 TIMEVALUE() 函数: TIMEVALUE("17:30:45.125")

有关日期时间和时区的备注

日期和日期时间值以 GMT 存储。保存好记录后,字段值存储为 GMT时区下的值,然后在记录详细信息页面显示时以查看者的时区显示。不会因日期转换而造成问题,因为转换日期时间为日期会得到相同的日期值。

然而,当使用日期时间值时,转换始终以 GMT 而不是用户的时区完成。如果在两个日期时间字段之前比较不会有时区问题,因为这两个字段都在同一时区。然而,当计算中的一个值从文本或日期值转换为日期时间值时,结果将不同。

让我们假定北京用户在名为 Date_Time_c 的自定义日期时间字段输入 2020 年 8 月 2 日 9点的值。该值被存储为 2020-08-02 01:00:00Z,因为存在 GMT+8的时区差。在北京时间 8 月 2 日21:00,用户编辑记录时运行以下公式字段: Date_Time_c - NOW() 在计算中,NOW() 是 2020-08-02 13:00:00Z,然后从 2020-08-02 01:00:00Z 相减会返回 -0.5(-12 小时)的预期结果。

假定不使用 NOW(),公式将转换字符串“2020-08-02 21:00:00”为日期时间值: Date_Time_c - DATETIMEVALUE( "2020-08-02 21:00:00") 在这种情况下,DATETIMEVALUE( “2020-08-02 21:00:00”)是 2020-08-02 21:00:00Z,最后运算结果会返回-0.8333333333333334(-20小时),与之前的-12小时不同。

假定当前时间还是北京时间2020年11月10日21点,即2020-11-10T13:00:00Z,把上面的NOW换为当天日期函数TODAY: TODAY() - DATEVALUE("2020-11-10T19:00:00Z") 运算结果为0,因为减号左右两侧都是北京时间11月10号,但是如果假定当前时间为北京时间2020年11月10日早上7点的话,因为北京时间时区差8小时,TODAY()将输出为2020-11-09号,两者相减将得到-1(-24小时)。

无法在公式中确定用户的时区。如果您的所有用户都在同一时区,则可以通过加或减用户的时区和 GMT 之间的时差以调整时区差别为您的已转换值。然而,由于时区会受夏令时的影响,同时每年的 DST 开始和结束日期都不同,因此很难在公式中管理。