Skip to Content
核心概念欄位型別公式

公式型別:formula

用途

formula 用現有欄位推導數字、精確小數、布林或字串,例如訂單明細的「小計 = 單價 × 數量」、庫存表的「需要補貨 = 庫存 < 安全水位」,或把姓氏與名字串成顯示名稱。預設為 live 公式,每次讀取紀錄時由伺服器求值。

本頁說明 legacy 版本 1(省略 formula_version 時的預設)。明確選用公式 v2可使用型別化擴充函式、版本化工作日及選用 stored 結果;同列相依規則與本頁 v1 跨表範例不同。Commands 尊重選定公式版本。

建立 schema

以下是 columns.create body。被引用欄位必須先存在:

{ "name": "小計", "type": "formula", "expression": "[單價] * [數量]", "description": "未稅小計" }

顯示名稱與 col_<hex> 都可放在方括號中。伺服器會把引用改寫成內部鍵保存,再於回應中盡可能轉回顯示名稱;名稱含 [、] 或 -> 時,必須直接使用內部鍵。

運算子與函式

類別語法行為
算術+、-、*、/、一元 -只接受數值;除以 0 回 null。運算元含 decimal 時 / 會被拒絕,請改用 DIVIDE
比較<、<=、>、>=、==、!=回布林值;不支援鏈式比較
分組( )調整算術優先序;比較不可藏在一般括號內
條件IF(condition, then, else)依條件選一個分支;兩分支型別必須相容
邏輯AND(a, b)、OR(a, b)至少兩個參數,回布林值
字串CONCAT(a, b)、UPPER(x)、LOWER(x)、LEN(x)字串組合、大小寫與長度
日期TODAY()、YEAR(x)、MONTH(x)、DATEDIFF(a, b)回日期字串、年月數字或相差天數
小數DECIMAL(x)、QUANTIZE(x, scale, MODE)、DIVIDE(a, b, scale, MODE)精確轉換、捨入到 scale 位,以及捨入到 scale 位的除法;見精確小數公式

設有公司業務時區時,TODAY() 使用該時區,每個 evaluation unit 固定使用一個時間點與日曆版本。業務時區為 null 時沿用伺服器當地日期,不會重寫既有值。

例如把數值比較與條件組合:

{ "name": "覆核等級", "type": "formula", "expression": "IF(AND([金額] > 10000, [折扣率] > 0.2), 2, 1)" }

跨表引用

語法 [LinkCol -> TargetNumericCol] 可沿本表的 cardinality-one link 讀取目標表的 integer 或 float:

{ "name": "可用額度", "type": "formula", "expression": "[客戶 -> 信用額度] - [本次金額]" }

跨表引用與 lookup 使用同一套權限遮蔽,但它只是 formula 的求值輸入,不會額外建立可獨立顯示的 lookup 欄。many link 會產生清單,因此不允許直接跨表引用;請先建立 rollup,或改用 one link。每個公式最多 5 組不同跨表 hop,整張表最多 30 組。

精確小數公式

公式只要讀取 decimal 欄位——不論是直接讀取,或透過 decimal 的 lookup、rollup 或 formula——或呼叫 decimal 函式,就會改用精確小數運算求值,而不是二進位浮點數:

  • +、-、*、一元 - 與比較運算都是精確的。可以混用 integer 欄位與數字字面值,但結果為 decimal 的公式不能引用 float 欄位(decimal formulas cannot mix float columns)。
  • / 會被拒絕:decimal division requires DIVIDE(value, value, result_scale, mode)。
  • DECIMAL(x) 把數字轉成 decimal。QUANTIZE(x, scale, MODE) 把 decimal 捨入到 scale 位,DIVIDE(a, b, scale, MODE) 把兩個 decimal 相除並捨入到 scale 位。它們的值運算元必須已經是 decimal,因此請用 DECIMAL(...) 包住 integer 欄位或字面值。scale 是 0 到 18 的字面整數,MODE 是 HALF_EVEN、HALF_UP、DOWN、FLOOR 或 CEILING。
  • decimal 結果是沒有指數、沒有尾端零的純小數字串,例如 "1354.5",即使經過 QUANTIZE 也一樣。運算元為 null 或 float、DIVIDE 除以 0,或中間值超過 128 位時,cell 會顯示 null。
{ "name": "含稅價", "type": "formula", "expression": "QUANTIZE([定價] * 1.05, 2, HALF_UP)" }

這裡的 定價 是 decimal 欄位。對 decimal 公式做計算欄篩選與排序仍然是精確的:當查詢範圍內有列無法精確求值時,請求可能以 ct.numeric_overflow 或 ct.numeric_invalid 失敗,而不是默默略過該列。

合法與不合法的值

formula 是唯讀欄;寫紀錄時必須省略公式值:

{ "data": { "數量": 2, "單價": 1290.5 } }

自行送出「小計」會被拒,即使值剛好等於伺服器計算結果:

{ "data": { "數量": 2, "單價": 1290.5, "小計": 2581.0 } }

以下 expression 也不合法:單一 = 不是相等運算子,鏈式比較不支援。

{ "name": "錯誤公式", "type": "formula", "expression": "[數量] = 2 < 3" }

顯示與回傳

公式值在讀取時計算並併入 data。算術回數字(運算元含 decimal 時是小數字串)、比較與 AND/OR 回布林、字串函式回字串:

{ "data": { "數量": 2, "單價": 1290.5, "小計": 2581.0 } }

任一必要運算元為 null、除以 0、非有限結果、依賴失效、循環或超深時,cell 會降級為 null,不會讓整頁讀取失敗。公式鏈最多 5 層;expression 最長 1000 字、括號最深 20 層、欄位引用最多 20 個,而且 AND、OR 與 CONCAT 各最多接受 20 個引數。

用 columns.preview 在伺服器試算

在真正建立前,把完全相同的 body 送到 columns.preview。成功時回正規化設定與前 5 筆 sample:

{ "valid": true, "normalized": { "name": "小計", "type": "formula", "required": false, "default_value": null, "max_length": null, "description": "未稅小計", "precision": null, "scale": null, "allow_negative": null, "result_scale": null, "rounding_mode": null, "target_table_id": null, "cardinality": null, "link_field": null, "aggregation": null, "target_column": null, "direction": null, "source_table_id": null, "match": null, "filter": null, "expression": "[單價] * [數量]", "options": null, "restricted": null }, "sample": [ { "record_id": "33333333-3333-4333-8333-333333333333", "value": 2581.0 } ], "errors": [], "hint": null }

引用型別、循環或跨表設定錯誤會以 valid: false 與 errors[].field/message/hint 回傳。純語法錯誤更早就會被伺服器的 ColumnCreate 驗證器拒絕:columns.create 與 columns.preview 都回 422(preview 不會把它報成 valid: false),錯誤訊息包含 invalid formula expression:,例如上面的無效範例會得到 invalid formula expression: use '==' for equality (position 11)。語法錯誤包括不支援的字元(如 %)、單一 =、連鎖比較、括號內的比較、未知的函式或捨入模式名稱、引數個數不對的函式呼叫,以及超過 20 層括號、20 個欄位引用或單一呼叫 20 個引數;expression 超過 1000 字同樣是 422。這不是瀏覽器端自行產生的錯誤,因此前端仍應顯示伺服器訊息。

注意事項

  • formula 只接受 expression,不可再帶 link_field、aggregation、target_column、required、default_value 或 max_length。
  • Legacy v1 expression 仍為建立時設定;明確的 v2 路徑 可更新 expression、formula_version、computation_mode,仍檢查目前 dependency/rule;formula retype 拒絕。先用 identity-bound update preview,再 PATCH 保留的 body,不必重建 v2 欄位。
  • 一般算術只能引用數值輸出。字串與日期欄可和同類輸出比較,也可放進相容的字串/日期函式,但不能當成算術運算元。未 pick 的 cardinality-many lookup 不能作為純量公式輸入;用 pick 收斂成單一值的 many lookup 則可以。
  • IF 的條件為 null 時整個結果為 null;AND、OR 與列出的函式也會在任一參數為 null 時傳播 null。
  • 公式引用會持久化為內部鍵,欄位改名安全;刪除或改型別時,後端會用 409 依賴衝突保護仍被引用的欄位。

試試看

到 API Playground 選擇 columns.preview,先觀察 sample 與結構化錯誤,再把同一份 body 送到 columns.create。

Last updated on