@rezti/dsh-rez-suite 0.1.49 → 0.1.51
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -2
- package/README.md +3 -3
- package/README.zh.md +2 -2
- package/cordis.patch.yml +1 -1
- package/lib/client.d.ts +31 -3
- package/lib/client.js +343 -7
- package/lib/index.js +244 -15
- package/lib/style.css +7 -0
- package/package.json +12 -11
- package/src/boss/mount.ts +4 -3
- package/src/boss/register.ts +1 -1
- package/src/boss/seed.ts +34 -0
- package/src/changelog.ts +48 -0
- package/src/channel-board.ts +55 -0
- package/src/client/locales.ts +62 -6
- package/src/client/panel/BoardTab.tsx +136 -0
- package/src/client/panel/ConfigTab.tsx +2 -2
- package/src/client/panel/StatusTab.tsx +31 -0
- package/src/client/panel/panel.module.css +7 -0
- package/src/client/settings-card.tsx +4 -1
- package/src/index.ts +3 -2
- package/src/protocol.ts +14 -0
- package/src/routes.ts +7 -1
- package/src/tools.ts +49 -6
- package/src/wecom-cli.ts +125 -0
- package/templates/boss/ops/AGENTS.md +2 -0
- package/templates/shared/wecom-cli.SOURCE.md +9 -0
- package/templates/shared/wecom-office/SKILL.md +32 -0
- package/templates/shared/wecomcli-calendar/SKILL.md +303 -0
- package/templates/shared/wecomcli-calendar/references/calendar-agenda.md +224 -0
- package/templates/shared/wecomcli-calendar/references/calendar-cancel.md +108 -0
- package/templates/shared/wecomcli-calendar/references/calendar-create.md +238 -0
- package/templates/shared/wecomcli-calendar/references/calendar-freebusy.md +207 -0
- package/templates/shared/wecomcli-calendar/references/calendar-meeting-room.md +170 -0
- package/templates/shared/wecomcli-calendar/references/calendar-search.md +206 -0
- package/templates/shared/wecomcli-calendar/references/calendar-update.md +272 -0
- package/templates/shared/wecomcli-contact/SKILL.md +58 -0
- package/templates/shared/wecomcli-disk/SKILL.md +389 -0
- package/templates/shared/wecomcli-doc/SKILL.md +137 -0
- package/templates/shared/wecomcli-doc/references/doc-contents-append.md +20 -0
- package/templates/shared/wecomcli-doc/references/doc-contents-overwrite.md +27 -0
- package/templates/shared/wecomcli-doc/references/doc-create.md +161 -0
- package/templates/shared/wecomcli-doc/scripts/build_docx.py +1375 -0
- package/templates/shared/wecomcli-doc-manage/SKILL.md +132 -0
- package/templates/shared/wecomcli-doc-manage/references/doc-members-update.md +24 -0
- package/templates/shared/wecomcli-doc-manage/references/doc-names-update.md +20 -0
- package/templates/shared/wecomcli-doc-manage/references/doc-rules-update.md +22 -0
- package/templates/shared/wecomcli-email/SKILL.md +218 -0
- package/templates/shared/wecomcli-email/references/forward-mail.md +131 -0
- package/templates/shared/wecomcli-email/references/get-mail.md +166 -0
- package/templates/shared/wecomcli-email/references/reply-mail.md +138 -0
- package/templates/shared/wecomcli-email/references/search-mail.md +111 -0
- package/templates/shared/wecomcli-email/references/security.md +53 -0
- package/templates/shared/wecomcli-email/references/send-mail.md +186 -0
- package/templates/shared/wecomcli-email/references/send-schedule.md +83 -0
- package/templates/shared/wecomcli-media/SKILL.md +98 -0
- package/templates/shared/wecomcli-meeting/SKILL.md +373 -0
- package/templates/shared/wecomcli-meeting/references/meeting-cancel.md +113 -0
- package/templates/shared/wecomcli-meeting/references/meeting-create.md +167 -0
- package/templates/shared/wecomcli-meeting/references/meeting-list.md +226 -0
- package/templates/shared/wecomcli-meeting/references/meeting-original-get.md +98 -0
- package/templates/shared/wecomcli-meeting/references/meeting-search.md +173 -0
- package/templates/shared/wecomcli-meeting/references/meeting-update.md +217 -0
- package/templates/shared/wecomcli-message/SKILL.md +200 -0
- package/templates/shared/wecomcli-shared/SKILL.md +73 -0
- package/templates/shared/wecomcli-sheet/SKILL.md +172 -0
- package/templates/shared/wecomcli-sheet/references/sheet-contents-update.md +47 -0
- package/templates/shared/wecomcli-sheet/references/sheet-ranges-get.md +45 -0
- package/templates/shared/wecomcli-sheet/references/sheet-rows-append.md +45 -0
- package/templates/shared/wecomcli-sheet/references/sheet-subsheets-add.md +26 -0
- package/templates/shared/wecomcli-sheet/references/sheet-subsheets-delete.md +20 -0
- package/templates/shared/wecomcli-smartpage/SKILL.md +170 -0
- package/templates/shared/wecomcli-smartpage/references/data-driven-pages.md +50 -0
- package/templates/shared/wecomcli-smartpage/references/formula/arraylist.md +369 -0
- package/templates/shared/wecomcli-smartpage/references/formula/datetime.md +283 -0
- package/templates/shared/wecomcli-smartpage/references/formula/logic.md +247 -0
- package/templates/shared/wecomcli-smartpage/references/formula/math.md +362 -0
- package/templates/shared/wecomcli-smartpage/references/formula/operators.md +246 -0
- package/templates/shared/wecomcli-smartpage/references/formula/pageblock.md +76 -0
- package/templates/shared/wecomcli-smartpage/references/formula/templates.md +410 -0
- package/templates/shared/wecomcli-smartpage/references/formula/text.md +377 -0
- package/templates/shared/wecomcli-smartpage/references/formula/user.md +22 -0
- package/templates/shared/wecomcli-smartpage/references/formula-reference.md +192 -0
- package/templates/shared/wecomcli-smartpage/references/mdx-syntax.md +739 -0
- package/templates/shared/wecomcli-smartpage/references/smartpage-edit.md +506 -0
- package/templates/shared/wecomcli-smartsheet/SKILL.md +154 -0
- package/templates/shared/wecomcli-smartsheet/assets/templates/README.md +53 -0
- package/templates/shared/wecomcli-smartsheet/assets/templates/ai_efficiency.md +709 -0
- package/templates/shared/wecomcli-smartsheet/assets/templates/connect_to_app.md +380 -0
- package/templates/shared/wecomcli-smartsheet/assets/templates/financial_accounting.md +369 -0
- package/templates/shared/wecomcli-smartsheet/assets/templates/hr_and_administration.md +475 -0
- package/templates/shared/wecomcli-smartsheet/assets/templates/ledger_records.md +156 -0
- package/templates/shared/wecomcli-smartsheet/assets/templates/manufacturing.md +395 -0
- package/templates/shared/wecomcli-smartsheet/assets/templates/marketing.md +186 -0
- package/templates/shared/wecomcli-smartsheet/assets/templates/office_essentials.md +299 -0
- package/templates/shared/wecomcli-smartsheet/assets/templates/personal_efficiency.md +70 -0
- package/templates/shared/wecomcli-smartsheet/assets/templates/procurement_logistics.md +325 -0
- package/templates/shared/wecomcli-smartsheet/assets/templates/project_management.md +564 -0
- package/templates/shared/wecomcli-smartsheet/assets/templates/rd_process_customer.md +222 -0
- package/templates/shared/wecomcli-smartsheet/assets/templates/rd_process_ops.md +105 -0
- package/templates/shared/wecomcli-smartsheet/assets/templates/rd_process_project.md +109 -0
- package/templates/shared/wecomcli-smartsheet/assets/templates/rd_process_research.md +92 -0
- package/templates/shared/wecomcli-smartsheet/assets/templates/sales_and_operations.md +446 -0
- package/templates/shared/wecomcli-smartsheet/assets/templates/store_management.md +431 -0
- package/templates/shared/wecomcli-smartsheet/assets/templates/team_tasks.md +274 -0
- package/templates/shared/wecomcli-smartsheet/assets/templates/wechat_customer.md +384 -0
- package/templates/shared/wecomcli-smartsheet/assets/templates/work_report.md +100 -0
- package/templates/shared/wecomcli-smartsheet/references/common.md +143 -0
- package/templates/shared/wecomcli-smartsheet/references/smart-sheet-chart-types.md +95 -0
- package/templates/shared/wecomcli-smartsheet/references/smart-sheet-edit.md +589 -0
- package/templates/shared/wecomcli-smartsheet/references/smart-sheet-field-types.md +438 -0
- package/templates/shared/wecomcli-smartsheet/references/smart-sheet-formula.md +845 -0
- package/templates/shared/wecomcli-smartsheet/references/smart-sheet-read.md +391 -0
- package/templates/shared/wecomcli-smartsheet/references/smart-sheet-record-values.md +201 -0
- package/templates/shared/wecomcli-smartsheet/references/smart-sheet-view-types.md +356 -0
- package/templates/shared/wecomcli-smartsheet/references/smart-sheet-webhook-examples.md +176 -0
- package/templates/shared/wecomcli-smartsheet/references/smart-sheet-webhook.md +169 -0
- package/templates/shared/wecomcli-todo/SKILL.md +76 -0
- package/templates/shared/wecomcli-todo/references/todo-create.md +137 -0
- package/templates/shared/wecomcli-todo/references/todo-delete.md +63 -0
- package/templates/shared/wecomcli-todo/references/todo-finish.md +72 -0
- package/templates/shared/wecomcli-todo/references/todo-get.md +66 -0
- package/templates/shared/wecomcli-todo/references/todo-list.md +133 -0
- package/templates/shared/wecomcli-todo/references/todo-update.md +112 -0
- package/templates/staff/design/AGENTS.md +2 -1
- package/templates/staff/ecommerce/.agents/skills/ops-ecommerce/SKILL.md +6 -0
- package/templates/staff/ecommerce/AGENTS.md +49 -0
- package/templates/staff/ecommerce/BOOTSTRAP.md +23 -0
- package/templates/staff/ecommerce/IDENTITY.md +8 -0
- package/templates/staff/ecommerce/MEMORY.md +9 -0
- package/templates/staff/ecommerce/PRIORITIES.md +3 -0
- package/templates/staff/ecommerce/SOUL.md +5 -0
- package/templates/staff/ecommerce/USER.md +8 -0
- package/templates/staff/hr/.agents/skills/staff-onboard-keys/SKILL.md +3 -3
- package/templates/staff/publish/.agents/skills/ops-publish/SKILL.md +6 -0
- package/templates/staff/publish/AGENTS.md +59 -0
- package/templates/staff/publish/BOOTSTRAP.md +23 -0
- package/templates/staff/publish/IDENTITY.md +8 -0
- package/templates/staff/publish/MEMORY.md +9 -0
- package/templates/staff/publish/PRIORITIES.md +3 -0
- package/templates/staff/publish/SOUL.md +6 -0
- package/templates/staff/publish/USER.md +8 -0
|
@@ -0,0 +1,845 @@
|
|
|
1
|
+
# 智能表格公式字段使用指南
|
|
2
|
+
|
|
3
|
+
## 概述
|
|
4
|
+
|
|
5
|
+
公式字段(`formula`)通过 `property_formula` 定义,其核心是 **`formulaModel`**——一个由多个 `FormulaItem` 组成的数组,用于描述完整的公式表达式。
|
|
6
|
+
|
|
7
|
+
**关键原则**:
|
|
8
|
+
- 所有公式必须通过构建 `formulaModel` 数组来表达
|
|
9
|
+
- 公式中的字符串常量使用**双引号** `""` 包裹(写在 `text` 字段中需转义为 `\""`)
|
|
10
|
+
- 函数名使用**大写**(如 `SUM`、`FILTER`、`IF`),写在 `type: "text"` 的 `text` 中
|
|
11
|
+
- 四则运算遵循数学优先级(`*` `/` 优先于 `+` `-`),需要改变优先级时**必须**用 `{"type":"text","text":"("}` 和 `{"type":"text","text":")"}` 括号分组
|
|
12
|
+
- 仅支持**四则运算 + 本文档列出的函数**,不支持取模 `%`、三元表达式 `?:` 等
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## 一、数据结构
|
|
17
|
+
|
|
18
|
+
### 1.1 property_formula
|
|
19
|
+
|
|
20
|
+
公式字段通过 `property_formula` 属性定义,包含两个核心部分:
|
|
21
|
+
|
|
22
|
+
| 字段 | 类型 | 说明 |
|
|
23
|
+
| --- | --- | --- |
|
|
24
|
+
| `formulaModel` | FormulaItem[] | 公式表达式模型,由多个公式项组成的数组 |
|
|
25
|
+
| `formatter` | Formatter | 展示格式配置,控制公式计算结果的显示格式 |
|
|
26
|
+
|
|
27
|
+
### 1.2 FormulaItem(公式项)
|
|
28
|
+
|
|
29
|
+
每个 `FormulaItem` 是公式中的一个原子片段。
|
|
30
|
+
|
|
31
|
+
| 字段 | 类型 | 说明 |
|
|
32
|
+
| --- | --- | --- |
|
|
33
|
+
| `type` | string (FormulaType) | 公式项类型枚举,见下方 |
|
|
34
|
+
| `text` | string | 文本内容(仅 `type="text"` 时使用) |
|
|
35
|
+
| `field_title` | string | 字段名称(`type="field"/"field_ref"` 时使用) |
|
|
36
|
+
| `field_type` | string (FieldType) | 字段类型常量(仅 `type="field"` 时使用) |
|
|
37
|
+
| `sheet_title` | string | 子表名称(`type="table_ref"/"field_ref"/"table_field_ref"` 时使用) |
|
|
38
|
+
|
|
39
|
+
> 公式 `formulaModel[].type` 必须传枚举值字符串(如 `"text"`、`"field"`、`"table_ref"` 等),不能写整数。字段用 `field_title`(字段名称)标识,子表用 `sheet_title`(子表名称)标识,无需传 ID。
|
|
40
|
+
|
|
41
|
+
### 1.3 FormulaType 枚举
|
|
42
|
+
|
|
43
|
+
| 枚举值 | 说明 | 何时使用 |
|
|
44
|
+
| --- | --- | --- |
|
|
45
|
+
| `text` | 文本片段 | 运算符 `+` `-` `*` `/`、函数名 `IF(` `SUM(`、常量、括号、参数分隔符等 |
|
|
46
|
+
| `field` | 当前记录字段 | 引用当前记录中的字段,需提供 `field_title` 和 `field_type` |
|
|
47
|
+
| `table_ref` | 表引用 | 引用整个表,需提供 `sheet_title`,通常配合 `FILTER` 函数 |
|
|
48
|
+
| `field_ref` | 列引用 | 在表引用/FILTER 结果后引用具体列,需提供 `field_title` 和 `sheet_title` |
|
|
49
|
+
| `table_field_ref` | 表.列引用 | 直接引用某表的某列(返回该列所有值),需提供 `sheet_title` + `field_title` |
|
|
50
|
+
| `current_value` | 当前值 | FILTER 等遍历函数中代表当前迭代的记录 |
|
|
51
|
+
|
|
52
|
+
### 1.4 Formatter(展示格式)
|
|
53
|
+
|
|
54
|
+
控制公式结果的显示方式,结构与字段属性一致:
|
|
55
|
+
|
|
56
|
+
| 字段 | 类型 | 说明 |
|
|
57
|
+
| --- | --- | --- |
|
|
58
|
+
| `field_type` | string (FieldType) | 展示格式类型 |
|
|
59
|
+
| `property_*` | 对应的 FieldProperty | 根据 `field_type` 传入对应属性 |
|
|
60
|
+
|
|
61
|
+
常见配置:
|
|
62
|
+
|
|
63
|
+
```json
|
|
64
|
+
// 数字:保留2位小数,千分位
|
|
65
|
+
{ "field_type": "number", "property_number": { "decimal_places": 2, "use_separate": true } }
|
|
66
|
+
|
|
67
|
+
// 百分比:保留1位小数
|
|
68
|
+
{ "field_type": "percentage", "property_percentage": { "decimal_places": 1, "use_separate": false } }
|
|
69
|
+
|
|
70
|
+
// 货币:人民币
|
|
71
|
+
{ "field_type": "currency", "property_currency": { "currency_type": "cny", "decimal_places": 2, "use_separate": true } }
|
|
72
|
+
|
|
73
|
+
// 纯文本
|
|
74
|
+
{ "field_type": "text" }
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## 二、FormulaItem 各类型用法
|
|
80
|
+
|
|
81
|
+
### type="text":文本片段
|
|
82
|
+
|
|
83
|
+
所有非引用内容都用 `type: "text"` 表示,包括运算符、函数调用语法、常量值等。
|
|
84
|
+
|
|
85
|
+
```json
|
|
86
|
+
{ "type": "text", "text": " + " } // 加法
|
|
87
|
+
{ "type": "text", "text": " * " } // 乘法
|
|
88
|
+
{ "type": "text", "text": " - " } // 减法
|
|
89
|
+
{ "type": "text", "text": " / " } // 除法
|
|
90
|
+
{ "type": "text", "text": "(" } // 左括号(用于分组,控制运算优先级)
|
|
91
|
+
{ "type": "text", "text": ")" } // 右括号(用于分组,控制运算优先级)
|
|
92
|
+
{ "type": "text", "text": "IF(" } // IF 函数开始
|
|
93
|
+
{ "type": "text", "text": "AND(" } // AND 函数开始
|
|
94
|
+
{ "type": "text", "text": ", " } // 参数分隔
|
|
95
|
+
{ "type": "text", "text": ")" } // 函数/括号结束
|
|
96
|
+
{ "type": "text", "text": "\"完成\"" } // 字符串常量
|
|
97
|
+
{ "type": "text", "text": "100" } // 数字常量
|
|
98
|
+
{ "type": "text", "text": ".SUM()" } // 聚合函数(跟在列引用后)
|
|
99
|
+
{ "type": "text", "text": ".AVERAGE()" } // 聚合函数
|
|
100
|
+
{ "type": "text", "text": ".COUNTA()" } // 聚合函数
|
|
101
|
+
{ "type": "text", "text": ".FILTER(" } // FILTER 函数(跟在表引用后)
|
|
102
|
+
{ "type": "text", "text": "." } // 属性访问点号
|
|
103
|
+
{ "type": "text", "text": "TODAY()" } // 日期函数
|
|
104
|
+
{ "type": "text", "text": "MONTH(" } // 月份函数开始
|
|
105
|
+
{ "type": "text", "text": "DATEDIF(" } // 日期差函数开始
|
|
106
|
+
{ "type": "text", "text": ", TODAY(), \"Y\")" } // DATEDIF 后续参数
|
|
107
|
+
{ "type": "text", "text": " = " } // 等于比较
|
|
108
|
+
{ "type": "text", "text": " > " } // 大于比较
|
|
109
|
+
{ "type": "text", "text": " < " } // 小于比较
|
|
110
|
+
{ "type": "text", "text": " <> " } // 不等于比较
|
|
111
|
+
{ "type": "text", "text": " & " } // 文本连接
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### type="field":当前记录字段引用
|
|
115
|
+
|
|
116
|
+
引用当前记录中的字段值,必须提供 `field_title` 和 `field_type`:
|
|
117
|
+
|
|
118
|
+
```json
|
|
119
|
+
{ "type": "field", "field_title": "单价", "field_type": "number" }
|
|
120
|
+
{ "type": "field", "field_title": "备注", "field_type": "text" }
|
|
121
|
+
{ "type": "field", "field_title": "截止日期", "field_type": "date_time" }
|
|
122
|
+
{ "type": "field", "field_title": "优先级", "field_type": "single_select" }
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### type="table_ref":表引用
|
|
126
|
+
|
|
127
|
+
引用整个表,通常后接 `.FILTER()`:
|
|
128
|
+
|
|
129
|
+
```json
|
|
130
|
+
{ "type": "table_ref", "sheet_title": "订单表" }
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### type="field_ref":列引用
|
|
134
|
+
|
|
135
|
+
在表引用或 FILTER 结果之后,引用具体列。前面必须有 `{ "type": "text", "text": "." }`。必须提供 `field_title` 和 `sheet_title`:
|
|
136
|
+
|
|
137
|
+
```json
|
|
138
|
+
{ "type": "field_ref", "field_title": "金额", "sheet_title": "订单表" }
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### type="table_field_ref":表.列引用
|
|
142
|
+
|
|
143
|
+
直接引用某表某列的所有值(返回数组),通常后接聚合函数:
|
|
144
|
+
|
|
145
|
+
```json
|
|
146
|
+
{ "type": "table_field_ref", "sheet_title": "订单表", "field_title": "金额" }
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### type="current_value":当前迭代值
|
|
150
|
+
|
|
151
|
+
FILTER 中代表当前记录,后接 `.` + `type="field_ref"` 访问该记录的字段:
|
|
152
|
+
|
|
153
|
+
```json
|
|
154
|
+
{ "type": "current_value" }
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## 三、支持的函数
|
|
160
|
+
|
|
161
|
+
### 3.1 聚合函数
|
|
162
|
+
|
|
163
|
+
写在 `type: "text"` 的 `text` 中,跟在列引用(`type="table_field_ref"` 或 `type="field_ref"`)之后。
|
|
164
|
+
|
|
165
|
+
| 函数 | text 值 | 说明 |
|
|
166
|
+
| --- | --- | --- |
|
|
167
|
+
| SUM | `.SUM()` | 求和 |
|
|
168
|
+
| AVERAGE | `.AVERAGE()` | 平均值 |
|
|
169
|
+
| MIN | `.MIN()` | 最小值 |
|
|
170
|
+
| MAX | `.MAX()` | 最大值 |
|
|
171
|
+
| COUNTA | `.COUNTA()` | 非空计数 |
|
|
172
|
+
| COUNTIF | `.COUNTIF(条件)` | 条件计数 |
|
|
173
|
+
| SUMIF | `.SUMIF(条件)` | 条件求和 |
|
|
174
|
+
|
|
175
|
+
### 3.2 列表函数
|
|
176
|
+
|
|
177
|
+
| 函数 | text 值 | 调用方式 | 说明 | 示例 |
|
|
178
|
+
| --- | --- | --- | --- | --- |
|
|
179
|
+
| FILTER | `.FILTER(` | 点调用,跟在表引用(`type="table_ref"`)后 | 筛选满足条件的记录。内部用 `type="current_value"` 代表当前记录,用 `type="field_ref"` 访问字段。多条件**必须**用 `AND()`/`OR()` 包裹。结束后可 `.列.聚合函数()` 链式调用 | `[表].FILTER(cur.状态 = "完成").任务名.COUNTA()` |
|
|
180
|
+
| CONTAINS | `.CONTAINS(` | 点调用,跟在列引用或 `LIST()` 后 | 判断范围中是否包含**任一**查找值,返回 TRUE/FALSE | `LIST(1,2,3,4).CONTAINS(2,5)` → TRUE;`[多选].CONTAINS("选项1","选项2")` |
|
|
181
|
+
| CONTAINSALL | `.CONTAINSALL(` | 点调用,跟在列引用或 `LIST()` 后 | 判断范围是否包含**所有**查找值,返回 TRUE/FALSE | `LIST(1,2,3,4).CONTAINSALL(1,2)` → TRUE;`LIST(1,2,3,4).CONTAINSALL(1,2,5)` → FALSE |
|
|
182
|
+
| CONTAINSONLY | `.CONTAINSONLY(` | 点调用,跟在列引用或 `LIST()` 后 | 判断范围是否**恰好仅**包含所有查找值(不要求顺序),返回 TRUE/FALSE | `LIST(1,2,3,4).CONTAINSONLY(1,2)` → FALSE;`LIST(1,2,3,4).CONTAINSONLY(1,2,4,3)` → TRUE |
|
|
183
|
+
| LOOKUP | `LOOKUP(` | 独立函数调用 | 查找匹配值并返回对应字段。参数:查找值, 匹配列, 返回列, [模式: 1=拆分选项, 0=不拆分] | `LOOKUP([负责人], [人员表].[姓名], [人员表].[部门], 1)` |
|
|
184
|
+
| LIST | `LIST(` | 独立函数调用 | 将任意个值组合为一个列表 | `LIST("智","能","表","格")` → `[智,能,表,格]` |
|
|
185
|
+
| LISTCOMBINE | `.LISTCOMBINE(` 或 `LISTCOMBINE(` | 点调用或独立调用 | 合并多个列表为一个(嵌套会被展开) | `LISTCOMBINE(LIST(1,2,LIST(3,4)),5,6)` → `[1,2,3,4,5,6]`;`字段1.LISTCOMBINE(字段2)` |
|
|
186
|
+
| LISTJOIN | `.LISTJOIN(` | 点调用,跟在列表后 | 用分隔符拼接列表为文本。参数:[分隔符],默认英文逗号 | `LIST(1,2,3,4).LISTJOIN()` → `1,2,3,4`;`LIST("智","能","表","格").LISTJOIN("-")` → `智-能-表-格` |
|
|
187
|
+
| UNIQUE | `.UNIQUE()` | 点调用,跟在列表后 | 列表去重,可链式接聚合函数 | `LIST(1,2,2,3,1).UNIQUE()` → `[1,2,3]`;`[表].[列].UNIQUE().COUNTA()` |
|
|
188
|
+
|
|
189
|
+
### 3.3 逻辑函数
|
|
190
|
+
|
|
191
|
+
| 函数 | text 值 | 说明 |
|
|
192
|
+
| --- | --- | --- |
|
|
193
|
+
| IF | `IF(` | 条件判断,三个参数:条件, 真值, 假值 |
|
|
194
|
+
| IFS | `IFS(` | 多条件判断,参数:条件1, 值1, [条件2, ...], [值2, ...],返回第一个 TRUE 条件对应的结果,比嵌套 IF 可读性更好 |
|
|
195
|
+
| AND | `AND(` | 逻辑与,包裹多个条件 |
|
|
196
|
+
| OR | `OR(` | 逻辑或,包裹多个条件 |
|
|
197
|
+
| TRUE | `TRUE()` | 返回逻辑值 TRUE |
|
|
198
|
+
| FALSE | `FALSE()` | 返回逻辑值 FALSE |
|
|
199
|
+
| IFBLANK | `IFBLANK(` | 检测值是否为空,为空则返回第二个参数,非空则返回值本身,两个参数:值, 空值情况的返回值 |
|
|
200
|
+
| IFERROR | `IFERROR(` | 检查值是否错误,错误则返回指定值,否则返回值本身,两个参数:值, 错误情况的返回值 |
|
|
201
|
+
| ISBLANK | `ISBLANK(` | 检测值是否为空,为空返回 TRUE,否则返回 FALSE |
|
|
202
|
+
| ISERROR | `ISERROR(` | 检测值是否为错误值,错误值返回 TRUE,否则返回 FALSE |
|
|
203
|
+
| ISNULL | `ISNULL(` | 检测值内容是否为空,为空返回 TRUE,否则返回 FALSE(空字符串不为空) |
|
|
204
|
+
| SWITCH | `SWITCH(` | 通过和表达式结果比较,按匹配结果返回对应值,如果不匹配,则返回可选默认值。参数:表达式, 值1, 结果1, [值2, ...], [结果2, ...],末尾可附加一个不配对的参数作为默认值 |
|
|
205
|
+
|
|
206
|
+
> **重要**:FILTER 和 IF 中如果有多个条件,**必须**用 `AND()` 或 `OR()` 包裹,不能让条件散放。
|
|
207
|
+
|
|
208
|
+
### 3.4 日期函数
|
|
209
|
+
|
|
210
|
+
| 函数 | text 值 | 说明 |
|
|
211
|
+
| --- | --- | --- |
|
|
212
|
+
| TODAY | `TODAY()` | 返回今天日期 |
|
|
213
|
+
| NOW | `NOW()` | 返回当前日期和时间 |
|
|
214
|
+
| DATE | `DATE(` | 将年、月、日数字转换为日期,参数:年, 月, 日。如 `DATE(2026, 4, 18)` |
|
|
215
|
+
| DATEVALUE | `DATEVALUE(` | 将日期字符串转换为数字(距 1900-01-01 的天数)。如 `DATEVALUE("2026/04/18")` |
|
|
216
|
+
| TODATE | `TODATE(` | 将文本/字符串转换为日期值(文本→日期的唯一函数)。参数:日期文本。如 `TODATE("2026-5-9")` → `2026/05/09`,`TODATE([日期文本字段])` 将文本字段转为日期 |
|
|
217
|
+
| YEAR | `YEAR(` | 获取日期的年份。如 `YEAR("2026-4-20")` 返回 `2026` |
|
|
218
|
+
| MONTH | `MONTH(` | 获取日期的月份 |
|
|
219
|
+
| DAY | `DAY(` | 获取日期的日。如 `DAY("2026-4-20 10:30:55")` 返回 `20` |
|
|
220
|
+
| HOUR | `HOUR(` | 获取时间的小时数。如 `HOUR("2026-4-20 10:30:55")` 返回 `10` |
|
|
221
|
+
| MINUTE | `MINUTE(` | 获取时间的分钟数。如 `MINUTE("2026-4-20 10:30:55")` 返回 `30` |
|
|
222
|
+
| SECOND | `SECOND(` | 获取时间的秒数。如 `SECOND("2026-4-20 10:30:55")` 返回 `55` |
|
|
223
|
+
| WEEKDAY | `WEEKDAY(` | 返回日期对应一周中的第几天,参数:日期值, [类型]。类型用于确定返回值:1 或省略=1(周日)~7(周六),2=1(周一)~7(周日),3=0(周一)~6(周日),11=1(周一)~7(周日),12=1(周二)~7(周一),13=1(周三)~7(周二),14=1(周四)~7(周三),15=1(周五)~7(周四),16=1(周六)~7(周五),17=1(周日)~7(周六) |
|
|
224
|
+
| WEEKNUM | `WEEKNUM(` | 返回日期在当前年份的第几周,参数:日期, [类型]。类型表示一周的第 1 天从星期几开始:1 或省略=周日开始,2=周一开始,11=周一开始,12=周二开始,13=周三开始,14=周四开始,15=周五开始,16=周六开始,17=周日开始,21=周一开始(ISO) |
|
|
225
|
+
| DATEDIF | `DATEDIF(` | 计算日期差,参数:开始日期, 结束日期, 单位。单位:`"Y"`(年) `"M"`(月) `"D"`(天) |
|
|
226
|
+
| NETWORKDAYS | `NETWORKDAYS(` | 返回两个日期之间的净工作日天数(排除周末和指定假期),参数:开始日期, 终止日期, [节假日]。节假日可选,默认仅排除双休日,可传入日期范围或数组常量如 `{"2026/4/19","2026/5/18"}` |
|
|
227
|
+
| WORKDAY | `WORKDAY(` | 返回起始日期之前或之后指定工作日数的日期(排除周末和指定假期),参数:起始日期, 天数, [节假日]。节假日可选,默认仅排除双休日,可传入日期范围或数组常量如 `{"2026/4/19","2026/5/18"}` |
|
|
228
|
+
|
|
229
|
+
### 3.5 数学函数
|
|
230
|
+
|
|
231
|
+
| 函数 | text 值 | 说明 |
|
|
232
|
+
| --- | --- | --- |
|
|
233
|
+
| ABS | `ABS(` | 返回数值的绝对值,参数:数值。如 `ABS(-3.5)` 返回 `3.5` |
|
|
234
|
+
| CEILING | `CEILING(` | 将数值向上舍入到最接近的指定基数的倍数,参数:数值, 基数。如 `CEILING(2.3, 1)` 返回 `3`,`CEILING(-2.5, 2)` 返回 `-2` |
|
|
235
|
+
| FLOOR | `FLOOR(` | 将数值向下舍入到最接近的指定基数的倍数,参数:数值, 基数。如 `FLOOR(2.7, 1)` 返回 `2`,`FLOOR(-2.5, 2)` 返回 `-4` |
|
|
236
|
+
| INT | `INT(` | 向下取整为最接近的整数,参数:数值。如 `INT(8.9)` 返回 `8`,`INT(-8.1)` 返回 `-9` |
|
|
237
|
+
| ROUND | `ROUND(` | 按指定小数位数四舍五入,参数:数值, 小数位数。如 `ROUND(2.155, 2)` 返回 `2.16`,小数位数可为负数表示到整数位 |
|
|
238
|
+
| POWER | `POWER(` | 返回数值的指定次幂,参数:底数, 指数。如 `POWER(2, 10)` 返回 `1024` |
|
|
239
|
+
| SQRT | `SQRT(` | 返回数值的平方根,参数:数值(必须为非负数)。如 `SQRT(16)` 返回 `4` |
|
|
240
|
+
| EXP | `EXP(` | 返回 e 的指定次幂,参数:指数。如 `EXP(1)` 返回 `2.71828...` |
|
|
241
|
+
| LOG | `LOG(` | 返回数值以指定数为底的对数,参数:数值, [底数]。底数省略时默认为 10。如 `LOG(100, 10)` 返回 `2`,`LOG(8, 2)` 返回 `3` |
|
|
242
|
+
| RAND | `RAND()` | 返回一个大于等于 0 且小于 1 的随机数,无参数 |
|
|
243
|
+
|
|
244
|
+
### 3.6 文本函数
|
|
245
|
+
|
|
246
|
+
| 函数 | text 值 | 说明 |
|
|
247
|
+
| --- | --- | --- |
|
|
248
|
+
| TEXTJOIN | `TEXTJOIN(` | 将多个文本值组合并在之间插入分隔符,参数:分隔符(文本字符串), 是否忽略空白值(TRUE/FALSE), 文本1, [文本2, ...]。如 `TEXTJOIN(" ", TRUE, "hello", "world")` 返回 `"hello world"`,分隔符为空字符串 `""` 时直接拼接 |
|
|
249
|
+
| & | ` & ` | 文本连接运算符 |
|
|
250
|
+
| CHAR | `CHAR(` | 返回数字代码所对应的 Unicode 字符,参数:数字。常用:`CHAR(10)` 换行符、`CHAR(32)` 空格、`CHAR(48~57)` 数字 0~9、`CHAR(65~90)` 大写字母 A~Z、`CHAR(97~122)` 小写字母 a~z |
|
|
251
|
+
| CONCAT | `CONCAT(` | 将多个文本拼接成单个文本,参数:文本1, [文本2, ...]。若要拼接双引号字符,需连续输入两个双引号 `""""`。如 `CONCAT([姓名], "-", [年龄])` → `小明-28` |
|
|
252
|
+
| CONTAINTEXT | `CONTAINTEXT(` | 判断文本中是否包含要查找的文本,返回 TRUE/FALSE,参数:文本, 查找文本。如 `CONTAINTEXT("智能表格", "表格")` → TRUE |
|
|
253
|
+
| FIND | `FIND(` | 从指定位置开始查找值,找到值在查找范围中第一次出现的位置,参数:查找的值, 查找范围, [起始位置]。起始位置默认为 1。如 `FIND("花", "人面桃花相映红")` → `4`;`FIND("红", LIST("人","面","桃","花","相","映","红"))` → `7` |
|
|
254
|
+
| LEFT | `LEFT(` | 从左提取字符串指定长度的子串,参数:字符串, [字符数]。如 `LEFT("人面桃花相映红", 2)` → `人面` |
|
|
255
|
+
| LEN | `LEN(` | 返回文本字符串中的字符个数(空格计为字符),参数:文本。如 `LEN("abcd")` → `4` |
|
|
256
|
+
| LOWER | `LOWER(` | 将文本中的全部大写字母替换为小写字母,参数:文本。如 `LOWER("SmartSheet")` → `smartsheet` |
|
|
257
|
+
| MID | `MID(` | 提取字符串中从指定开始位置开始的指定长度的子串,参数:文本, 开始位置, 提取长度。位置从 1 开始。如 `MID("腾讯文档智能表格", 5, 4)` → `智能表格` |
|
|
258
|
+
| REPLACE | `REPLACE(` | 将文本中指定位置和长度的部分替换为新文本,参数:文本, 位置, 长度, 新文本。如 `REPLACE("人面桃花相映红", -5, -1, "梨")` → `人面梨花相映红` |
|
|
259
|
+
| RIGHT | `RIGHT(` | 从右提取字符串指定长度的子串,参数:字符串, [字符数]。如 `RIGHT("人面桃花相映红", 2)` → `映红` |
|
|
260
|
+
| SEARCH | `SEARCH(` | 在被查询文本中查找查询文本,返回第一次出现的起始位置(从 1 开始),参数:查询文本, 被查询文本, [编号]。编号为开始搜索的字符位置。如 `SEARCH("e", "Hello", 1)` → `2` |
|
|
261
|
+
| SPLIT | `SPLIT(` | 使用分隔符对文本进行分割,返回列表,参数:文本, 分隔符。如 `SPLIT("智-能-表-格", "-")` → `["智","能","表","格"]` |
|
|
262
|
+
| SUBSTITUTE | `SUBSTITUTE(` | 在文本中用新文本替代指定的旧文本,参数:文本, 被替换文本, 新文本, [被替换文本序号]。序号省略时替换所有,指定序号时只替换第 N 个出现。如 `SUBSTITUTE("hello world", "hello", "Hello")` → `Hello world` |
|
|
263
|
+
| TEXT | `TEXT(` | 按指定格式将数值/日期转为文本,参数:数值, 格式。常用格式:`"YYYY/MM/DD"` 年月日、`"DDDD"` 星期全称、`"DDD"` 星期简称、`"0.0%"` 百分比。如 `TEXT("2026-05-14", "ddd")` → `周四` |
|
|
264
|
+
| TRIM | `TRIM(` | 移除文本最前和最后的空格,参数:文本。如 `TRIM(" 智能 表格 ")` → `智能 表格`(中间空格保留) |
|
|
265
|
+
| UPPER | `UPPER(` | 将文本中的全部小写字母替换为大写字母,参数:文本。如 `UPPER("SmartSheet")` → `SMARTSHEET` |
|
|
266
|
+
| VALUE | `VALUE(` | 将表示数值的文本字符串转换为数值,参数:文本。如 `VALUE("1,000")` → `1000` |
|
|
267
|
+
|
|
268
|
+
---
|
|
269
|
+
|
|
270
|
+
## 四、完整 formulaModel 示例
|
|
271
|
+
|
|
272
|
+
### 示例 1:简单乘法
|
|
273
|
+
|
|
274
|
+
语义:`单价 * 数量`
|
|
275
|
+
|
|
276
|
+
```json
|
|
277
|
+
{
|
|
278
|
+
"formulaModel": [
|
|
279
|
+
{ "type": "field", "field_title": "单价", "field_type": "number" },
|
|
280
|
+
{ "type": "text", "text": " * " },
|
|
281
|
+
{ "type": "field", "field_title": "数量", "field_type": "number" }
|
|
282
|
+
],
|
|
283
|
+
"formatter": {
|
|
284
|
+
"field_type": "number",
|
|
285
|
+
"property_number": { "decimal_places": 2, "use_separate": true }
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
### 示例 2:括号分组 — 折后率
|
|
291
|
+
|
|
292
|
+
语义:`(原价 - 折后价) / 原价`
|
|
293
|
+
|
|
294
|
+
> **注意**:当需要改变默认运算优先级时,**必须**使用括号 `(` `)` 进行分组。括号也是 `type: "text"` 的项。如果不加括号,`原价 - 折后价 / 原价` 会先算除法再算减法,结果完全错误。
|
|
295
|
+
|
|
296
|
+
```json
|
|
297
|
+
{
|
|
298
|
+
"formulaModel": [
|
|
299
|
+
{ "type": "text", "text": "(" },
|
|
300
|
+
{ "type": "field", "field_title": "原价", "field_type": "number" },
|
|
301
|
+
{ "type": "text", "text": " - " },
|
|
302
|
+
{ "type": "field", "field_title": "折后价", "field_type": "number" },
|
|
303
|
+
{ "type": "text", "text": ")" },
|
|
304
|
+
{ "type": "text", "text": " / " },
|
|
305
|
+
{ "type": "field", "field_title": "原价", "field_type": "number" }
|
|
306
|
+
],
|
|
307
|
+
"formatter": {
|
|
308
|
+
"field_type": "percentage",
|
|
309
|
+
"property_percentage": { "decimal_places": 2, "use_separate": false }
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
### 示例 3:条件判断
|
|
315
|
+
|
|
316
|
+
语义:如果 状态="完成" 则显示"是",否则显示"否"
|
|
317
|
+
|
|
318
|
+
```json
|
|
319
|
+
{
|
|
320
|
+
"formulaModel": [
|
|
321
|
+
{ "type": "text", "text": "IF(" },
|
|
322
|
+
{ "type": "field", "field_title": "状态", "field_type": "single_select" },
|
|
323
|
+
{ "type": "text", "text": " = \"完成\", \"是\", \"否\")" }
|
|
324
|
+
],
|
|
325
|
+
"formatter": { "field_type": "text" }
|
|
326
|
+
}
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
### 示例 4:聚合 — 对某表某列求和
|
|
330
|
+
|
|
331
|
+
语义:订单表的金额列求和
|
|
332
|
+
|
|
333
|
+
```json
|
|
334
|
+
{
|
|
335
|
+
"formulaModel": [
|
|
336
|
+
{ "type": "table_field_ref", "sheet_title": "订单表", "field_title": "金额" },
|
|
337
|
+
{ "type": "text", "text": ".SUM()" }
|
|
338
|
+
],
|
|
339
|
+
"formatter": {
|
|
340
|
+
"field_type": "number",
|
|
341
|
+
"property_number": { "decimal_places": 2, "use_separate": true }
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
### 示例 5:聚合 — 对某表某列求平均值
|
|
347
|
+
|
|
348
|
+
语义:订单表的金额列平均值
|
|
349
|
+
|
|
350
|
+
```json
|
|
351
|
+
{
|
|
352
|
+
"formulaModel": [
|
|
353
|
+
{ "type": "table_field_ref", "sheet_title": "订单表", "field_title": "金额" },
|
|
354
|
+
{ "type": "text", "text": ".AVERAGE()" }
|
|
355
|
+
],
|
|
356
|
+
"formatter": {
|
|
357
|
+
"field_type": "number",
|
|
358
|
+
"property_number": { "decimal_places": 2, "use_separate": true }
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
### 示例 6:聚合 — 对某表某列计数
|
|
364
|
+
|
|
365
|
+
语义:订单表的订单号列非空计数
|
|
366
|
+
|
|
367
|
+
```json
|
|
368
|
+
{
|
|
369
|
+
"formulaModel": [
|
|
370
|
+
{ "type": "table_field_ref", "sheet_title": "订单表", "field_title": "订单号" },
|
|
371
|
+
{ "type": "text", "text": ".COUNTA()" }
|
|
372
|
+
],
|
|
373
|
+
"formatter": {
|
|
374
|
+
"field_type": "number",
|
|
375
|
+
"property_number": { "decimal_places": 0, "use_separate": false }
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
### 示例 7:FILTER + 聚合
|
|
381
|
+
|
|
382
|
+
语义:筛选任务表中 状态="完成" 的记录,对任务名列计数
|
|
383
|
+
|
|
384
|
+
```json
|
|
385
|
+
{
|
|
386
|
+
"formulaModel": [
|
|
387
|
+
{ "type": "table_ref", "sheet_title": "任务表" },
|
|
388
|
+
{ "type": "text", "text": ".FILTER(" },
|
|
389
|
+
{ "type": "current_value" },
|
|
390
|
+
{ "type": "text", "text": "." },
|
|
391
|
+
{ "type": "field_ref", "field_title": "状态", "sheet_title": "任务表" },
|
|
392
|
+
{ "type": "text", "text": " = \"完成\")" },
|
|
393
|
+
{ "type": "text", "text": "." },
|
|
394
|
+
{ "type": "field_ref", "field_title": "任务名", "sheet_title": "任务表" },
|
|
395
|
+
{ "type": "text", "text": ".COUNTA()" }
|
|
396
|
+
],
|
|
397
|
+
"formatter": {
|
|
398
|
+
"field_type": "number",
|
|
399
|
+
"property_number": { "decimal_places": 0, "use_separate": false }
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
### 示例 8:FILTER + 多条件(AND)
|
|
405
|
+
|
|
406
|
+
语义:筛选任务表中 截止日期 < 今天 且 状态 ≠ "完成" 的记录,对任务名计数
|
|
407
|
+
|
|
408
|
+
```json
|
|
409
|
+
{
|
|
410
|
+
"formulaModel": [
|
|
411
|
+
{ "type": "table_ref", "sheet_title": "任务表" },
|
|
412
|
+
{ "type": "text", "text": ".FILTER(AND(" },
|
|
413
|
+
{ "type": "current_value" },
|
|
414
|
+
{ "type": "text", "text": "." },
|
|
415
|
+
{ "type": "field_ref", "field_title": "截止日期", "sheet_title": "任务表" },
|
|
416
|
+
{ "type": "text", "text": " < TODAY(), " },
|
|
417
|
+
{ "type": "current_value" },
|
|
418
|
+
{ "type": "text", "text": "." },
|
|
419
|
+
{ "type": "field_ref", "field_title": "状态", "sheet_title": "任务表" },
|
|
420
|
+
{ "type": "text", "text": " <> \"完成\"))" },
|
|
421
|
+
{ "type": "text", "text": "." },
|
|
422
|
+
{ "type": "field_ref", "field_title": "任务名", "sheet_title": "任务表" },
|
|
423
|
+
{ "type": "text", "text": ".COUNTA()" }
|
|
424
|
+
],
|
|
425
|
+
"formatter": {
|
|
426
|
+
"field_type": "number",
|
|
427
|
+
"property_number": { "decimal_places": 0, "use_separate": false }
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
### 示例 9:FILTER + 金额求和
|
|
433
|
+
|
|
434
|
+
语义:筛选订单表中 金额 > 10000 的记录,对金额列求和
|
|
435
|
+
|
|
436
|
+
```json
|
|
437
|
+
{
|
|
438
|
+
"formulaModel": [
|
|
439
|
+
{ "type": "table_ref", "sheet_title": "订单表" },
|
|
440
|
+
{ "type": "text", "text": ".FILTER(" },
|
|
441
|
+
{ "type": "current_value" },
|
|
442
|
+
{ "type": "text", "text": "." },
|
|
443
|
+
{ "type": "field_ref", "field_title": "金额", "sheet_title": "订单表" },
|
|
444
|
+
{ "type": "text", "text": " > 10000)" },
|
|
445
|
+
{ "type": "text", "text": "." },
|
|
446
|
+
{ "type": "field_ref", "field_title": "金额", "sheet_title": "订单表" },
|
|
447
|
+
{ "type": "text", "text": ".SUM()" }
|
|
448
|
+
],
|
|
449
|
+
"formatter": {
|
|
450
|
+
"field_type": "number",
|
|
451
|
+
"property_number": { "decimal_places": 2, "use_separate": true }
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
### 示例 10:FILTER + MONTH 日期筛选
|
|
457
|
+
|
|
458
|
+
语义:筛选订单表中 日期的月份 = 今天月份 的记录,对金额列求和
|
|
459
|
+
|
|
460
|
+
```json
|
|
461
|
+
{
|
|
462
|
+
"formulaModel": [
|
|
463
|
+
{ "type": "table_ref", "sheet_title": "订单表" },
|
|
464
|
+
{ "type": "text", "text": ".FILTER(MONTH(" },
|
|
465
|
+
{ "type": "current_value" },
|
|
466
|
+
{ "type": "text", "text": "." },
|
|
467
|
+
{ "type": "field_ref", "field_title": "日期", "sheet_title": "订单表" },
|
|
468
|
+
{ "type": "text", "text": ") = MONTH(TODAY()))" },
|
|
469
|
+
{ "type": "text", "text": "." },
|
|
470
|
+
{ "type": "field_ref", "field_title": "金额", "sheet_title": "订单表" },
|
|
471
|
+
{ "type": "text", "text": ".SUM()" }
|
|
472
|
+
],
|
|
473
|
+
"formatter": {
|
|
474
|
+
"field_type": "number",
|
|
475
|
+
"property_number": { "decimal_places": 2, "use_separate": true }
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
### 示例 11:日期差计算
|
|
481
|
+
|
|
482
|
+
语义:从入职日期到今天的年数
|
|
483
|
+
|
|
484
|
+
```json
|
|
485
|
+
{
|
|
486
|
+
"formulaModel": [
|
|
487
|
+
{ "type": "text", "text": "DATEDIF(" },
|
|
488
|
+
{ "type": "field", "field_title": "入职日期", "field_type": "date_time" },
|
|
489
|
+
{ "type": "text", "text": ", TODAY(), \"Y\")" }
|
|
490
|
+
],
|
|
491
|
+
"formatter": {
|
|
492
|
+
"field_type": "number",
|
|
493
|
+
"property_number": { "decimal_places": 0, "use_separate": false }
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
### 示例 12:文本连接
|
|
499
|
+
|
|
500
|
+
语义:姓 & 名
|
|
501
|
+
|
|
502
|
+
> 字符串常量必须用双引号包裹(`\"...\"`),且每个片段之间**必须**用 `&` 连接。不能将字符串常量和字段引用直接相邻排列,否则公式无法正确执行。
|
|
503
|
+
|
|
504
|
+
```json
|
|
505
|
+
{
|
|
506
|
+
"formulaModel": [
|
|
507
|
+
{ "type": "field", "field_title": "姓", "field_type": "text" },
|
|
508
|
+
{ "type": "text", "text": " & " },
|
|
509
|
+
{ "type": "field", "field_title": "名", "field_type": "text" }
|
|
510
|
+
],
|
|
511
|
+
"formatter": { "field_type": "text" }
|
|
512
|
+
}
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
### 示例 13:嵌套条件 IF + AND
|
|
516
|
+
|
|
517
|
+
语义:如果 截止日期 < 今天 且 状态 ≠ "完成",显示"超期",否则显示"正常"
|
|
518
|
+
|
|
519
|
+
```json
|
|
520
|
+
{
|
|
521
|
+
"formulaModel": [
|
|
522
|
+
{ "type": "text", "text": "IF(AND(" },
|
|
523
|
+
{ "type": "field", "field_title": "截止日期", "field_type": "date_time" },
|
|
524
|
+
{ "type": "text", "text": " < TODAY(), " },
|
|
525
|
+
{ "type": "field", "field_title": "状态", "field_type": "single_select" },
|
|
526
|
+
{ "type": "text", "text": " <> \"完成\"), \"超期\", \"正常\")" }
|
|
527
|
+
],
|
|
528
|
+
"formatter": { "field_type": "text" }
|
|
529
|
+
}
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
### 示例 14:SUMIF 条件求和
|
|
533
|
+
|
|
534
|
+
语义:对商品销售表的销售额列,仅对值 > 1000 的求和
|
|
535
|
+
|
|
536
|
+
```json
|
|
537
|
+
{
|
|
538
|
+
"formulaModel": [
|
|
539
|
+
{ "type": "table_field_ref", "sheet_title": "销售表", "field_title": "销售额" },
|
|
540
|
+
{ "type": "text", "text": ".SUMIF(" },
|
|
541
|
+
{ "type": "current_value" },
|
|
542
|
+
{ "type": "text", "text": " > 1000)" }
|
|
543
|
+
],
|
|
544
|
+
"formatter": {
|
|
545
|
+
"field_type": "number",
|
|
546
|
+
"property_number": { "decimal_places": 2, "use_separate": true }
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
### 示例 15:除法 — 完成率
|
|
552
|
+
|
|
553
|
+
语义:已完成任务数 / 总任务数
|
|
554
|
+
|
|
555
|
+
> 当 formatter 设置为 `percentage` 时,公式只需返回小数值(如 0.8),系统会自动显示为百分比(80%)。
|
|
556
|
+
|
|
557
|
+
```json
|
|
558
|
+
{
|
|
559
|
+
"formulaModel": [
|
|
560
|
+
{ "type": "table_ref", "sheet_title": "任务表" },
|
|
561
|
+
{ "type": "text", "text": ".FILTER(" },
|
|
562
|
+
{ "type": "current_value" },
|
|
563
|
+
{ "type": "text", "text": "." },
|
|
564
|
+
{ "type": "field_ref", "field_title": "状态", "sheet_title": "任务表" },
|
|
565
|
+
{ "type": "text", "text": " = \"完成\")" },
|
|
566
|
+
{ "type": "text", "text": "." },
|
|
567
|
+
{ "type": "field_ref", "field_title": "任务名", "sheet_title": "任务表" },
|
|
568
|
+
{ "type": "text", "text": ".COUNTA() / " },
|
|
569
|
+
{ "type": "table_field_ref", "sheet_title": "任务表", "field_title": "任务名" },
|
|
570
|
+
{ "type": "text", "text": ".COUNTA()" }
|
|
571
|
+
],
|
|
572
|
+
"formatter": {
|
|
573
|
+
"field_type": "percentage",
|
|
574
|
+
"property_percentage": { "decimal_places": 1, "use_separate": false }
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
### 示例 16:关联字段引用
|
|
580
|
+
|
|
581
|
+
语义:通过关联字段"项目"访问被关联表的"预算"字段
|
|
582
|
+
|
|
583
|
+
```json
|
|
584
|
+
{
|
|
585
|
+
"formulaModel": [
|
|
586
|
+
{ "type": "field", "field_title": "项目", "field_type": "reference" },
|
|
587
|
+
{ "type": "text", "text": "." },
|
|
588
|
+
{ "type": "field_ref", "field_title": "预算", "sheet_title": "项目表" }
|
|
589
|
+
],
|
|
590
|
+
"formatter": {
|
|
591
|
+
"field_type": "number",
|
|
592
|
+
"property_number": { "decimal_places": 2, "use_separate": true }
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
```
|
|
596
|
+
|
|
597
|
+
### 示例 17:FILTER + 部门匹配(引用当前记录字段)
|
|
598
|
+
|
|
599
|
+
语义:筛选员工表中 部门 = 当前记录的部门 的记录,对姓名列计数
|
|
600
|
+
|
|
601
|
+
```json
|
|
602
|
+
{
|
|
603
|
+
"formulaModel": [
|
|
604
|
+
{ "type": "table_ref", "sheet_title": "员工表" },
|
|
605
|
+
{ "type": "text", "text": ".FILTER(" },
|
|
606
|
+
{ "type": "current_value" },
|
|
607
|
+
{ "type": "text", "text": "." },
|
|
608
|
+
{ "type": "field_ref", "field_title": "部门", "sheet_title": "员工表" },
|
|
609
|
+
{ "type": "text", "text": " = " },
|
|
610
|
+
{ "type": "field", "field_title": "部门", "field_type": "single_select" },
|
|
611
|
+
{ "type": "text", "text": ")" },
|
|
612
|
+
{ "type": "text", "text": "." },
|
|
613
|
+
{ "type": "field_ref", "field_title": "姓名", "sheet_title": "员工表" },
|
|
614
|
+
{ "type": "text", "text": ".COUNTA()" }
|
|
615
|
+
],
|
|
616
|
+
"formatter": {
|
|
617
|
+
"field_type": "number",
|
|
618
|
+
"property_number": { "decimal_places": 0, "use_separate": false }
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
```
|
|
622
|
+
|
|
623
|
+
### 示例 18:LOOKUP 跨子表查找
|
|
624
|
+
|
|
625
|
+
语义:在"考勤表"中根据当前记录的 `员工姓名` 到同一智能表格下的"员工表"中匹配 `姓名`,返回对应的 `部门`。
|
|
626
|
+
|
|
627
|
+
> **关键点**:
|
|
628
|
+
> - `LOOKUP` 是独立函数调用,以 `LOOKUP(` 开头,参数之间用 `, ` 分隔。
|
|
629
|
+
> - 四个参数依次为:**查找值、匹配列、返回列、模式**。
|
|
630
|
+
> - 查找值用 `type="field"` 引用当前记录字段;匹配列/返回列用 `type="table_field_ref"` 直接引用目标子表的列(需 `sheet_title` + `field_title`)。
|
|
631
|
+
> - 模式 `0` = 不拆分(整体匹配,适用于文本/数字等单值字段);模式 `1` = 拆分多选选项(见示例 19)。
|
|
632
|
+
|
|
633
|
+
```json
|
|
634
|
+
{
|
|
635
|
+
"formulaModel": [
|
|
636
|
+
{ "type": "text", "text": "LOOKUP(" },
|
|
637
|
+
{ "type": "field", "field_title": "员工姓名", "field_type": "text" },
|
|
638
|
+
{ "type": "text", "text": ", " },
|
|
639
|
+
{ "type": "table_field_ref", "sheet_title": "员工表", "field_title": "姓名" },
|
|
640
|
+
{ "type": "text", "text": ", " },
|
|
641
|
+
{ "type": "table_field_ref", "sheet_title": "员工表", "field_title": "部门" },
|
|
642
|
+
{ "type": "text", "text": ", 0)" }
|
|
643
|
+
],
|
|
644
|
+
"formatter": { "field_type": "text" }
|
|
645
|
+
}
|
|
646
|
+
```
|
|
647
|
+
|
|
648
|
+
### 示例 19:LOOKUP 多选字段拆分匹配
|
|
649
|
+
|
|
650
|
+
语义:当前记录的 `负责人` 字段是多选(可能包含多个员工),需要按每个选项分别在"员工表"中匹配 `姓名` 并返回对应的 `部门` 列表。此时模式参数用 `1`,LOOKUP 会把多选值拆开逐个查找。
|
|
651
|
+
|
|
652
|
+
```json
|
|
653
|
+
{
|
|
654
|
+
"formulaModel": [
|
|
655
|
+
{ "type": "text", "text": "LOOKUP(" },
|
|
656
|
+
{ "type": "field", "field_title": "负责人", "field_type": "select" },
|
|
657
|
+
{ "type": "text", "text": ", " },
|
|
658
|
+
{ "type": "table_field_ref", "sheet_title": "员工表", "field_title": "姓名" },
|
|
659
|
+
{ "type": "text", "text": ", " },
|
|
660
|
+
{ "type": "table_field_ref", "sheet_title": "员工表", "field_title": "部门" },
|
|
661
|
+
{ "type": "text", "text": ", 1)" }
|
|
662
|
+
],
|
|
663
|
+
"formatter": { "field_type": "text" }
|
|
664
|
+
}
|
|
665
|
+
```
|
|
666
|
+
|
|
667
|
+
---
|
|
668
|
+
|
|
669
|
+
## 五、通过 API 创建公式字段
|
|
670
|
+
|
|
671
|
+
通过 `wecom-cli smartsheet fields add` 命令传入公式字段定义:
|
|
672
|
+
|
|
673
|
+
```json
|
|
674
|
+
{
|
|
675
|
+
"docid": "<docid>",
|
|
676
|
+
"sheet_title": "<子表名称>",
|
|
677
|
+
"fields": [
|
|
678
|
+
{
|
|
679
|
+
"field_title": "总价",
|
|
680
|
+
"field_type": "formula",
|
|
681
|
+
"property_formula": {
|
|
682
|
+
"formulaModel": [
|
|
683
|
+
{ "type": "field", "field_title": "单价", "field_type": "number" },
|
|
684
|
+
{ "type": "text", "text": " * " },
|
|
685
|
+
{ "type": "field", "field_title": "数量", "field_type": "number" }
|
|
686
|
+
],
|
|
687
|
+
"formatter": {
|
|
688
|
+
"field_type": "number",
|
|
689
|
+
"property_number": { "decimal_places": 2, "use_separate": true }
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
]
|
|
694
|
+
}
|
|
695
|
+
```
|
|
696
|
+
|
|
697
|
+
---
|
|
698
|
+
|
|
699
|
+
## 六、formulaModel 构建模式总结
|
|
700
|
+
|
|
701
|
+
### 模式 A:当前记录字段运算
|
|
702
|
+
|
|
703
|
+
`字段A op 字段B`
|
|
704
|
+
|
|
705
|
+
```
|
|
706
|
+
[type="field", field_title=字段A] → [type="text", " op "] → [type="field", field_title=字段B]
|
|
707
|
+
```
|
|
708
|
+
|
|
709
|
+
需要括号分组时:`(字段A op 字段B) op2 字段C`
|
|
710
|
+
|
|
711
|
+
```
|
|
712
|
+
[type="text", "("] → [type="field", field_title=字段A] → [type="text", " op "] → [type="field", field_title=字段B] → [type="text", ")"] → [type="text", " op2 "] → [type="field", field_title=字段C]
|
|
713
|
+
```
|
|
714
|
+
|
|
715
|
+
### 模式 B:表.列聚合
|
|
716
|
+
|
|
717
|
+
`表.列.聚合函数()`
|
|
718
|
+
|
|
719
|
+
```
|
|
720
|
+
[type="table_field_ref", sheet_title+field_title] → [type="text", ".SUM()"]
|
|
721
|
+
```
|
|
722
|
+
|
|
723
|
+
### 模式 C:FILTER + 列聚合
|
|
724
|
+
|
|
725
|
+
`表.FILTER(条件).列.聚合函数()`
|
|
726
|
+
|
|
727
|
+
```
|
|
728
|
+
[type="table_ref", sheet_title] → [type="text", ".FILTER("] → 条件部分 → [type="text", ")"] → [type="text", "."] → [type="field_ref", field_title+sheet_title] → [type="text", ".COUNTA()"]
|
|
729
|
+
```
|
|
730
|
+
|
|
731
|
+
### 模式 D:FILTER 条件内部
|
|
732
|
+
|
|
733
|
+
访问当前记录的字段:
|
|
734
|
+
```
|
|
735
|
+
[type="current_value"] → [type="text", "."] → [type="field_ref", field_title+sheet_title] → [type="text", " = \"值\""]
|
|
736
|
+
```
|
|
737
|
+
|
|
738
|
+
多条件必须用 AND/OR 包裹:
|
|
739
|
+
```
|
|
740
|
+
[type="text", "AND("] → 条件1 → [type="text", ", "] → 条件2 → [type="text", ")"]
|
|
741
|
+
```
|
|
742
|
+
|
|
743
|
+
### 模式 E:IF 条件判断
|
|
744
|
+
|
|
745
|
+
```
|
|
746
|
+
[type="text", "IF("] → 条件部分 → [type="text", ", \"真值\", \"假值\")"]
|
|
747
|
+
```
|
|
748
|
+
|
|
749
|
+
### 模式 F:关联字段引用
|
|
750
|
+
|
|
751
|
+
```
|
|
752
|
+
[type="field", field_title=关联字段, "reference"] → [type="text", "."] → [type="field_ref", field_title+sheet_title(被关联表字段)]
|
|
753
|
+
```
|
|
754
|
+
|
|
755
|
+
### 模式 G:文本拼接(字符串常量 & 字段引用)
|
|
756
|
+
|
|
757
|
+
字符串常量**必须**用双引号包裹,片段之间**必须**用 `&` 连接,**不能直接相邻**。
|
|
758
|
+
|
|
759
|
+
`"常量文本A" & 字段B & "常量文本C"`
|
|
760
|
+
|
|
761
|
+
```
|
|
762
|
+
[type="text", "\"常量文本A\""] → [type="text", " & "] → [type="field", field_title=字段B] → [type="text", " & "] → [type="text", "\"常量文本C\""]
|
|
763
|
+
```
|
|
764
|
+
|
|
765
|
+
---
|
|
766
|
+
|
|
767
|
+
## 七、常见错误
|
|
768
|
+
|
|
769
|
+
### 7.1 FILTER/IF 多条件未用 AND/OR 包裹
|
|
770
|
+
|
|
771
|
+
```json
|
|
772
|
+
// 错误:条件散放
|
|
773
|
+
{ "type": "text", "text": ".FILTER(" },
|
|
774
|
+
// ... 条件1 ...
|
|
775
|
+
{ "type": "text", "text": ", " },
|
|
776
|
+
// ... 条件2 ...
|
|
777
|
+
{ "type": "text", "text": ")" }
|
|
778
|
+
|
|
779
|
+
// 正确:用 AND 包裹
|
|
780
|
+
{ "type": "text", "text": ".FILTER(AND(" },
|
|
781
|
+
// ... 条件1 ...
|
|
782
|
+
{ "type": "text", "text": ", " },
|
|
783
|
+
// ... 条件2 ...
|
|
784
|
+
{ "type": "text", "text": "))" }
|
|
785
|
+
```
|
|
786
|
+
|
|
787
|
+
### 7.2 type="field" 缺少 field_type
|
|
788
|
+
|
|
789
|
+
```json
|
|
790
|
+
// 错误
|
|
791
|
+
{ "type": "field", "field_title": "单价" }
|
|
792
|
+
|
|
793
|
+
// 正确
|
|
794
|
+
{ "type": "field", "field_title": "单价", "field_type": "number" }
|
|
795
|
+
```
|
|
796
|
+
|
|
797
|
+
### 7.3 type="table_field_ref" 缺少 sheet_title 或 field_title
|
|
798
|
+
|
|
799
|
+
```json
|
|
800
|
+
// 错误
|
|
801
|
+
{ "type": "table_field_ref", "field_title": "金额" }
|
|
802
|
+
|
|
803
|
+
// 正确
|
|
804
|
+
{ "type": "table_field_ref", "sheet_title": "订单表", "field_title": "金额" }
|
|
805
|
+
```
|
|
806
|
+
|
|
807
|
+
### 7.4 对文本字段误用数学运算
|
|
808
|
+
|
|
809
|
+
文本连接应使用 `&`,不能用 `+`。
|
|
810
|
+
|
|
811
|
+
### 7.5 四则运算缺少括号导致优先级错误
|
|
812
|
+
|
|
813
|
+
`*` `/` 优先级高于 `+` `-`。当需要先做加减再做乘除时,**必须**用括号分组。
|
|
814
|
+
|
|
815
|
+
```json
|
|
816
|
+
// 错误:想算 (A - B) / A,但实际计算的是 A - (B / A)
|
|
817
|
+
[
|
|
818
|
+
{ "type": "field", "field_title": "原价", "field_type": "number" },
|
|
819
|
+
{ "type": "text", "text": " - " },
|
|
820
|
+
{ "type": "field", "field_title": "折后价", "field_type": "number" },
|
|
821
|
+
{ "type": "text", "text": " / " },
|
|
822
|
+
{ "type": "field", "field_title": "原价", "field_type": "number" }
|
|
823
|
+
]
|
|
824
|
+
|
|
825
|
+
// 正确:用 type="text" 的 "(" 和 ")" 包裹需要优先计算的部分
|
|
826
|
+
[
|
|
827
|
+
{ "type": "text", "text": "(" },
|
|
828
|
+
{ "type": "field", "field_title": "原价", "field_type": "number" },
|
|
829
|
+
{ "type": "text", "text": " - " },
|
|
830
|
+
{ "type": "field", "field_title": "折后价", "field_type": "number" },
|
|
831
|
+
{ "type": "text", "text": ")" },
|
|
832
|
+
{ "type": "text", "text": " / " },
|
|
833
|
+
{ "type": "field", "field_title": "原价", "field_type": "number" }
|
|
834
|
+
]
|
|
835
|
+
```
|
|
836
|
+
|
|
837
|
+
> **规则**:遇到混合使用 `+-` 和 `*/` 的表达式,先写出数学公式,确认哪些部分需要括号,然后在 formulaModel 中对应位置插入 `{"type":"text","text":"("}` 和 `{"type":"text","text":")"}` 。
|
|
838
|
+
|
|
839
|
+
### 7.6 不支持的运算符/语法
|
|
840
|
+
|
|
841
|
+
公式系统**不支持**:
|
|
842
|
+
- 取模运算 `%`
|
|
843
|
+
- 三元表达式 `?:`
|
|
844
|
+
- 本文档未列出的任何函数
|
|
845
|
+
遇到不支持的需求应提示用户。
|