15 · 組合指示子(@filter、@sort、@top、@source、@join)
指示子是什麼,不是什麼
指示子(@filter、@sort、@top、@source、@join)住在資料區塊內,塑造區塊迭代的列集合。不論它們在來源儲存格中的順序,都會以固定順序求值:
@source <Name>— 選擇區塊要迭代的來源。@join <Source> on ...— 把主列和另一來源的列配對。@filter <condition>— 保留條件為 truthy 的列。@sort <column> [asc|desc]— 對列排序。@top <N>— 在篩選與排序後保留前 N 列。
寫作建議:把指示子依執行順序排列。規格沒有強制 — 但能讓範本可讀性更好。
怎麼組合
常見形態:金額最大的 5 筆台北續約。
{{ @filter [地區] = "台北" }}
{{ @filter [金額] > 1000 }}
{{ @sort [金額] desc }}
{{ @top 5 }}
{{ [客戶] }} | {{ [金額] }}
求值順序:
- 篩選 地區=台北。
- 篩選 金額>1000(與上一條 AND 串接)。
- 對倖存的列依金額由大到小排序。
- 取前 5。
多個 @filter 以 AND 串接
依 ADR-0029,同一區塊內多個 @filter 以 AND 合併。沒有 OR 關鍵字。要表達 OR:
- 用
IN合併成單一 filter:{{ @filter [地區] in __lists__[active_regions] }} - 拆成兩個資料區塊(各放在自己的範本區域),讓兩個被渲染的列集合自然聯集。
- 在來源端先處理。
組合 @source + @join
{{ @source 續約資料 }}
{{ @join 客戶資料 on 續約資料[customer_id] = 客戶資料[id] }}
{{ @filter 客戶資料[tier] = "A" }}
{{ @sort 續約資料[amount] desc }}
{{ @top 10 }}
{{ 續約資料[customer_id] }}
{{ 客戶資料[name] }}
{{ 續約資料[amount] }}
步驟:
- 在 續約資料 上迭代(依
@source)。 - 以 id 做 inner-join 配對 客戶資料;沒比對到的列丟掉。
- 只保留 客戶資料 等級為 "A" 的聯結列。
- 依 續約資料.amount 降冪排序。
- 取前 10。
@filter 可以參照任一來源的欄位;裸方括號參照活動區塊的來源,明確的 Source[Column] 則指向聯結那邊。
禁用的組合
依 ADR-0029:
- 每個資料區塊最多一個
@source。重複會丟xl3/directive/invalid-syntax。 - 每個資料區塊最多一個
@join。多重 join 不在範圍內。 - 不允許自我聯結。
@join S on S[a] = S[b](S是當前活動來源)會丟xl3/join/bad-on-clause。
@top 接 @sort
{{ @sort [金額] desc }}
{{ @top 10 }}
沒有排序的 Top-N 沒有意義。若沒搭配 @sort 就寫 @top,會取得來源順序的前 N 列 — 偶有用處,但很少是作者本意。
filter 後變空
如果 @filter 把所有列都篩掉,資料區塊展開為零列。範本列的樣式 / 格式會留在輸出,但不會產生任何資料列。下方的頁尾列仍可見。
規格指引
- ADR-0029 — Directive composition + source edge semantics。
spec/language.md的「Filter」、「Sort」、「Top」、「Source」、「Join」。- 食譜 05 介紹
@filter in __lists__[…]。 - 食譜 07 介 紹
@source+@join基本用法。 - 食譜 09 介紹
@sort+@top基本用法。