公式字段(Formula)
公式字段通过表达式自动计算并显示结果,支持引用当前记录的其他字段、使用内置函数和嵌套计算,还支持 [表名].[字段名] 整列引用对同 Base 内其他表的数据进行跨表聚合。适用于需要自动计算的场景,如总价、完成率、到期提醒、跨表汇总等。
适用场景
- 计算订单总价:数量 × 单价
- 计算任务完成率:已完成数 ÷ 总数
- 拼接显示文本:姓氏 + 名字
- 判断日期状态:
IF({截止日期} < TODAY(), "已逾期", "未逾期") - 跨表汇总:对另一张表的金额列求和
SUM([销售表].[金额]) - 条件计数:统计另一张表满足条件的记录数
COUNTIF([销售表].[城市], "北京")
创建公式字段
- 在数据表中点击「添加字段」。
- 选择字段类型为「公式」。
- 在公式编辑器中输入表达式:
- 引用本表字段:在「可用字段」区点击字段名,插入
{字段名}; - 引用其他表:在「跨表引用」区选择目标表,点击字段名,插入
[表名].[字段名]。
- 引用本表字段:在「可用字段」区点击字段名,插入
- 配置结果格式(如数字精度、日期格式等)。
- 点击保存。保存时系统会校验语法与引用(字段是否存在、跨表引用是否有效),有误会当场提示。
公式编辑器
SmartTable 提供公式助手组件,降低公式编写门槛:
- 可用字段:点击可插入当前记录的字段引用
{字段名}。 - 跨表引用:下拉选择同 Base 内的其他表,点击字段名插入
[表名].[字段名]整列引用。 - 函数列表:按分类展示全部 76 个内置函数,悬停查看语法、参数与示例,点击即可插入。
- 语法提示与校验:保存前校验语法、字段引用与整列引用的有效性。
- 实时预览:保存前可预览计算结果。
语法规则
字段引用
在公式中引用当前记录的字段值,使用花括号语法:
{数量} * {单价}- 字段名不区分大小写。
- 引用不存在的字段时,求值按空值(null)处理。
整列引用(跨表引用)
使用 [表名].[字段名] 语法引用某张表某个字段的整列值集合(数组):
SUM([销售表].[金额])规则说明:
| 规则 | 说明 |
|---|---|
| 引用范围 | 仅限同一 Base 内的表;跨 Base 或表名不存在时求值退化为 0 / 空值 |
| 大小写 | 表名与字段名均不区分大小写,忽略首尾空格 |
| 本表引用 | 引用本表字段也必须写全表名(如 [任务表].[工时]),不可省略表名 |
| 可引用的列 | 任意原始值字段(数字、文本、日期、单选、复选等) |
| 不可引用的列 | 公式字段、查找字段、关联字段(其值不直接落库,整列引用取不到值) |
| 重命名 | 表或字段重命名后,公式中的整列引用不会自动更新,需手动修改 |
| 求值时机 | 由服务端在读取记录时实时计算,数据始终与源表保持一致 |
CurrentValue(条件遍历)
在条件类函数(FILTER / COUNTIF / SUMIF / AVERAGEIF)的条件参数中,CurrentValue 代表整列引用遍历到的当前元素值:
COUNTIF([销售表].[金额], CurrentValue > 100)CurrentValue只能在上述四个函数的条件参数中使用。- 仅支持单元格值形态(如
CurrentValue > 100、CurrentValue = "北京");CurrentValue.[字段]形态暂不支持。
运算符与优先级
| 优先级 | 运算符 | 说明 | 示例 |
|---|---|---|---|
| 1(最高) | ( ) | 括号,先算括号内 | ({a} + {b}) * 2 |
| 2 | ^ | 幂运算 | 2 ^ 10 |
| 3 | * / | 乘、除 | {单价} * {数量} |
| 4 | + - | 加、减 | {a} + {b} |
| 5 | = <> > < >= <= | 比较,返回布尔值 | {分数} >= 60 |
- 同级运算从左到右结合。
- 字符串比较按字典序;数字与数字字符串比较时,系统会自动将数字字符串转为数值参与比较(如存储值为
"150.5"也能正确参与> 100判断)。
内置函数
SmartTable 公式引擎提供 76 个内置函数(前后端引擎保持一致),并支持加减乘除、括号等常用运算符,覆盖以下五大类别:
运算符
除函数外,公式助手还提供常用运算符,按「运算符」分类展示,点击即可插入到表达式中:
| 运算符 | 符号 | 说明 | 示例 |
|---|---|---|---|
| ADD | + | 加法:两个数值相加 | {单价} + {运费} |
| SUBTRACT | - | 减法:第一个数减去第二个数 | {总收入} - {总成本} |
| MULTIPLY | × | 乘法:两个数值相乘 | {单价} * {数量} |
| DIVIDE | ÷ | 除法:第一个数除以第二个数(除数为 0 时计算失败) | {总金额} / {数量} |
| PARENTHESES | ( ) | 括号:控制运算优先级,括号内先算 | ({字段A} + {字段B}) * 2 |
使用建议
运算符以符号形式(+ - × ÷ ( ))显示在公式助手中;括号可用于调整计算顺序,例如先求和再乘以系数。
数学函数(18 个)
| 函数 | 说明 | 示例 |
|---|---|---|
| SUM | 求和,支持整列引用 | SUM(1, 2, 3)、SUM([销售表].[金额]) |
| AVG | 平均值,支持整列引用 | AVG({语文}, {数学}) |
| MAX / MIN | 最大值 / 最小值,支持整列引用 | MAX({数值1}, {数值2}) |
| ROUND | 四舍五入 | ROUND({数值}, 2) |
| CEILING / FLOOR | 向上 / 向下取整 | CEILING({数值}) |
| ABS | 绝对值 | ABS({数值}) |
| MOD | 取模 | MOD(17, 5) |
| POWER | 幂运算 | POWER(2, 10) |
| SQRT | 平方根 | SQRT(16) |
| LN / LOG / EXP | 对数与指数 | LN({数值}) |
| PI / E | 圆周率 / 自然常数 | PI() |
| RAND / RANDBETWEEN | 随机数 | RANDBETWEEN(1, 10) |
文本函数(14 个)
| 函数 | 说明 | 示例 |
|---|---|---|
| CONCAT | 拼接文本 | CONCAT({姓}, {名}) |
| LEFT / RIGHT / MID | 截取文本 | LEFT({文本}, 3) |
| LEN | 文本长度 | LEN({文本}) |
| UPPER / LOWER | 大小写转换 | UPPER({文本}) |
| TRIM | 去除两端空格 | TRIM({文本}) |
| SUBSTITUTE / REPLACE | 替换文本 | SUBSTITUTE({文本}, "旧", "新") |
| FIND | 查找子串位置 | FIND("关键词", {文本}) |
| REPT | 重复文本 | REPT("★", {评分}) |
| TEXT | 格式化为文本 | TEXT({数值}, "0.00") |
| VALUE | 文本转数值 | VALUE({文本}) |
日期函数(15 个)
| 函数 | 说明 | 示例 |
|---|---|---|
| TODAY / NOW | 当前日期 / 日期时间 | TODAY() |
| YEAR / MONTH / DAY | 提取年月日 | YEAR({日期}) |
| HOUR / MINUTE / SECOND | 提取时分秒 | HOUR({日期时间}) |
| WEEKDAY | 星期几 | WEEKDAY({日期}) |
| DATEADD | 日期加减 | DATEADD({日期}, 3, "days") |
| DATEDIF / DATEDIFF | 日期差 | DATEDIFF({结束}, {开始}, "days") |
| DATETIME_FORMAT | 格式化日期 | DATETIME_FORMAT({日期}, "YYYY-MM-DD") |
| FROMUNIXTIME / UNIXTIMESTAMP | Unix 时间戳互转 | UNIXTIMESTAMP({日期}) |
逻辑函数(16 个)
| 函数 | 说明 | 示例 |
|---|---|---|
| IF | 条件判断 | IF({状态}="完成", 100, 0) |
| IFS / SWITCH | 多条件分支 | SWITCH({等级}, "A", 90, "B", 80, 0) |
| AND / OR / XOR | 逻辑组合 | AND({条件1}, {条件2}) |
| NOT | 取反 | NOT({条件}) |
| IFERROR | 捕获错误并返回默认值 | IFERROR({a}/{b}, 0) |
| ISBLANK / ISERROR / ISNUMBER / ISTEXT / ISDATE | 类型判断 | ISBLANK({字段}) |
| BLANK / NA / ERROR | 特殊值 | BLANK() |
统计函数(13 个)
其中 FILTER / COUNTIF / SUMIF / AVERAGEIF 支持结合整列引用与 CurrentValue 进行跨表条件聚合:
| 函数 | 说明 | 示例 |
|---|---|---|
| COUNT | 数值计数,支持整列引用 | COUNT([销售表].[金额]) |
| COUNTA | 非空计数,支持整列引用 | COUNTA([销售表].[金额]) |
| COUNTBLANK | 空值计数 | COUNTBLANK({字段1}, {字段2}) |
| COUNTIF | 条件计数 | COUNTIF([销售表].[城市], "北京") |
| SUMIF | 条件求和 | SUMIF([销售表].[城市], CurrentValue = "北京", [销售表].[金额]) |
| AVERAGEIF | 条件平均 | AVERAGEIF([销售表].[金额], CurrentValue > 100) |
| FILTER | 条件筛选(返回数组,常与 SUM/COUNT 嵌套) | SUM(FILTER([销售表].[金额], CurrentValue > 100)) |
| STDEV / VAR | 标准差 / 方差 | STDEV([销售表].[金额]) |
| MEDIAN / MODE | 中位数 / 众数 | MEDIAN([销售表].[金额]) |
| RANK | 排名 | RANK({分数}, [考试].[分数]) |
| UNIQUE | 去重 | UNIQUE([销售表].[城市]) |
跨表引用与条件聚合
结合 [表].[字段] 整列引用、CurrentValue 条件遍历与统计函数,可以在公式字段中实现类似报表的跨表计算。以下示例基于两张表:
- 销售表:字段
城市(文本)、金额(数字)、状态(单选:已完成 / 进行中)
| 城市 | 金额 | 状态 |
|---|---|---|
| 北京 | 100 | 已完成 |
| 上海 | 200 | 进行中 |
| 北京 | 300 | 已完成 |
| 广州 | 400 | 已完成 |
- 汇总表:放置跨表公式字段
示例 1:跨表求和
SUM([销售表].[金额])对销售表「金额」整列求和。预期结果:1000。
示例 2:条件计数(字符串条件)
COUNTIF([销售表].[城市], "北京")统计「城市」列等于「北京」的记录数。预期结果:2。
示例 3:条件求和(CurrentValue 条件)
SUMIF([销售表].[城市], CurrentValue = "北京", [销售表].[金额])遍历「城市」列,CurrentValue 为当前遍历到的城市名,等于「北京」时累加对应行的金额。预期结果:400(100 + 300)。
示例 4:FILTER 筛选后聚合
SUM(FILTER([销售表].[金额], CurrentValue > 150))FILTER 先筛出金额大于 150 的值集合 [200, 300, 400],再由 SUM 求和。预期结果:900。
示例 5:多条件聚合
SUM(FILTER([销售表].[金额], AND(CurrentValue > 100, CurrentValue < 400)))筛选「金额 > 100 且 < 400」的值,对结果求和。预期结果:500(200 + 300)。
能力边界
多条件聚合目前仅支持针对同一列的多个 CurrentValue 条件(如上例)。不支持在 FILTER 条件中同时引用另一个整列做逐行对应(如「金额 > 100 且状态 = 已完成」需要行级关联,暂不支持)。多条件聚合也不支持 SUMIFS / COUNTIFS 函数。
示例 6:条件平均与文本拼接
AVERAGEIF([销售表].[金额], CurrentValue >= 200)
CONCAT("北京成交:", COUNTIF([销售表].[城市], "北京"), " 单")第一式对金额 ≥ 200 的行求平均(预期结果:300);第二式输出 北京成交:2 单。
示例 7:本表整列与行级混合
{数量} * {单价} + SUM([销售表].[金额])行级计算与跨表聚合可自由组合:当前记录的数量乘单价,加上销售表整列金额。
引用查找字段(Lookup)
公式可通过 {字段名} 行级引用查找字段:服务端会先计算出查找字段的结果,再计算公式,公式取值与查找字段显示值保持一致。
取值说明
查找字段在公式中的取值形态取决于其「计算方式」配置:
| 查找字段计算方式 | 返回形态 | 公式中的表现 |
|---|---|---|
| 求和 / 计数 / 平均值 / 最大值 / 最小值等聚合方式 | 单值(可能为文本形态数字,如 "3.5") | 参与算术运算时系统会自动转为数值 |
| 原值 | 数组(关联的多条源记录值) | 不适合直接算术运算,建议先用 SUM / MAX 等函数聚合 |
使用 VALUE 显式转数值
当查找字段返回的是文本形态的数字时,推荐使用 VALUE 函数显式转换为数值,语义更清晰、前后端计算结果更稳定:
{预计工时} - VALUE({项目进度})VALUE 会自动剥离货币符号(¥、$ 等)与千分位逗号后转为数值;无法转换的文本返回空值。
示例
- 剩余工时:
{预计工时} - VALUE({项目进度}) - 查找结果换算:
VALUE({客户评级}) * 2
语法容错
函数名不区分大小写(value(...) 与 VALUE(...) 等价);误输入的全角括号 () 与全角逗号 , 也会自动按半角解析。
与整列引用的区别
查找字段支持行级引用({查找字段名}),但不支持整列引用([表名].[查找字段] 取不到值,求值退化为 0 / 空值)。
结果格式化
公式字段支持多种结果格式:
- 数字:配置小数位数、千分位分隔符。
- 货币:选择货币符号(¥、$ 等)。
- 百分比:自动乘以 100 并显示 %。
- 日期/日期时间:选择日期显示格式。
格式选择
公式保存后仍可修改格式。如果公式返回的是日期时间戳,请选择日期格式,避免显示为长数字。
常用基础示例
计算总价
{数量} * {单价}计算完成率
IF({总数} > 0, {已完成} / {总数} * 100, 0)逾期判断
IF({截止日期} < TODAY(), "已逾期", "未逾期")状态标签
IF({进度} = 100, "已完成", IF({进度} > 0, "进行中", "未开始"))常见问题(FAQ)
Q:跨表引用结果一直是 0? A:依次检查:① 被引用表是否与当前表在同一 Base 内(跨 Base 不支持);② 表名/字段名是否与实际一致(重命名后公式不会自动更新);③ 引用的列是否为公式、查找或关联字段(这类计算型字段暂不可被整列引用);④ 修改后刷新页面,公式值由服务端实时重算。
Q:公式显示 #ERROR 怎么办? A:#ERROR 表示求值失败,常见原因:除数为 0(可用 IFERROR({a}/{b}, 0) 兜底)、函数名拼写错误、参数个数或类型不符。将鼠标悬停在函数列表中对应函数上可查看正确的语法与示例。
Q:SUMIFS / COUNTIFS 多条件函数支持吗? A:暂不支持。请使用 FILTER + AND 组合实现等价效果,例如 SUM(FILTER([销售表].[金额], AND(CurrentValue > 100, [销售表].[状态] = "已完成")))。
Q:CurrentValue 是什么?可以用在哪? A:它代表条件函数遍历整列时的当前元素值,只能用在 FILTER / COUNTIF / SUMIF / AVERAGEIF 的条件参数中,例如 COUNTIF([销售表].[金额], CurrentValue > 100)。
Q:被引用表的数据变了,公式会自动更新吗? A:会。跨表公式在读取记录时由服务端实时计算,源表数据变更后刷新即可看到最新结果,无需手动重算。
Q:数字字段存的是文本(如 "1.3")会影响计算吗? A:不会。聚合与数值比较时会自动剥离货币符号(¥、$ 等)和千分位逗号并转为数值,无法转换的文本视为不命中或跳过。
Q:公式里引用查找字段报错或结果不对? A:行级引用 {查找字段} 已支持,服务端会先算查找字段的结果再算公式。若查找字段返回的是文本形态数字(如 "3.5"),请用 VALUE({查找字段}) 显式转数值;「原值」模式返回数组时,请先用 SUM / MAX 等函数聚合。注意整列引用([表].[查找字段])暂不支持。
调试技巧
- 善用编辑器校验:保存时系统会校验语法、字段引用与整列引用的有效性,报错信息会指出具体问题(如「未知的整列引用」)。
- 从小公式开始:先写最内层表达式(如
[销售表].[金额]),确认无误后逐层向外包函数(SUM(...)→SUM(FILTER(...)))。 - 用 FILTER 单独验证条件:条件不确定时,先用
FILTER([销售表].[金额], CurrentValue > 100)查看筛选结果是否符合预期,再嵌套聚合函数。 - 注意空值:空单元格在整列中表现为空值,
COUNT/SUM自动跳过;需要显式判断时用ISBLANK。 - 结果格式与公式类型匹配:公式返回时间戳但显示为长数字时,把字段格式改为「日期」;返回比例却显示整数时,检查是否需要乘 100 并选百分比格式。
- 避免循环引用:公式字段引用其他公式字段时,确保引用链不会绕回自身。
注意事项
- 公式字段为只读,不能手动编辑计算结果。
- 公式中引用的字段值变更后,公式结果会自动重算。
- 公式字段可以引用其他公式字段,但请避免循环引用。
- 整列引用的表必须与当前表在同一个 Base 内。
