メインコンテンツへスキップ

XTL 言語

ノート

この日本語訳は読みやすさのための補助資料です。仕様の正典は英語原文で、規範的な解釈の差異が生じた場合は英語版が優先します。

本ドキュメントは XTL 0.1 テンプレート言語のサーフェスを定義します。本文の記法はテンプレート作成者と実装にとって規範的(normative)です。

{{ ... }} テンプレートブロックの内容に対する形式文法は grammar.ebnf にあります。これはポーターおよびツール作成者のための非規範的な補助資料です。用語の定義は glossary.md を参照してください。

テンプレートブロック

テンプレート式は二重中括弧の中に書きます。

{{ expression }}

{{}} の直後・直前の空白には意味がありません。パーサーは正規化(normalization)の前に先頭・末尾の空白をトリムします。以下はすべて等価です。

{{ [name] }}
{{[name]}}
{{ [name] }}
{{
[name]
}}

演算子周辺の空白(例:{{ [a] + [b] }}{{ [a]+[b] }})にも意味はありません。文字列リテラル内の空白は保持されます("hello world" のスペースはそのまま残ります)。

中身が空のテンプレートブロック({{ }} または空白のみ)は ADR-0021 によりパースエラーとなります(xl3/parser/empty-block)。

テンプレートブロックは {{ で開かれ、セルテキスト上で最初に現れる }} で閉じられます。デリミタスキャナは文字列リテラルを認識しません。すなわち "..." リテラル中の }} はブロックを閉じます(ADR-0051)。値の中に }} を含めたい作成者は、それを __config__[key] に保持し、{{ __config__[key] }} で参照してください。式本体中の " の数が奇数であるもの(リテラルの不整合。ほぼ常に埋め込まれたデリミタによって発生)は xl3/parser/unbalanced-literal を発生させます。

データブロック

シート上の データブロック は、ソース行をレンダリングするときにエンジンが展開する矩形です。2 つの次元を持ちます。

  • 行範囲 [r_start..r_end] — 各行に少なくとも 1 つの データ行セル{{ ... }} 本体が、集計関数の外側で少なくとも 1 つの [Column] を参照するセル)が含まれる、連続行の最大範囲です。2 つのデータ行の間に非データ行([Column] 参照を持たない行)があると、そこでブロックは閉じます。
  • 列範囲 [c_start..c_end] — ブロックの行範囲内にある任意の {{ ... }} 式セルすべての bounding box を、隣接する非空セルを通って外側へ拡張したものです。marker セルに直に隣接するネイティブ Excel 数式({ formula: "..." })または静的値はブロックの内側です。完全に空の列で隔てられた非空セルは外側です。

矩形内のセルは block cells です。矩形の外側にある同一シート上のセルは outside cells です(ADR-0066)。

シートあたり 1 ブロック(0.x)。 XTL 0.x では、1 シートに高々 1 つのデータブロックがあります。パーサーが [Column] データ行セルの disconnected cluster を 2 つ以上検出した場合、パース時点で xl3/expression/bracket-outside-block を発生させ、2 つ目の cluster の開始行を示します。multi-block サポート(境界を曖昧にしないための明示的な @block directive)は将来の ADR に繰り延べです。

ブロック展開セマンティクス(レンダリング側。evaluation.md の「Render Phases」で規範化):

  • block cells は展開後の行へクローンされます — (r_end - r_start + 1) 個のテンプレート行ごとに 1 レコードです。
  • r < r_start の outside cells は元の位置に残ります(ブロックより上の header / configuration 行)。
  • r >= r_start の outside cells は、ブロック展開で splice が行を挿入しても、元の行 r に残ります。下方向へシフトしませんNOT)。数式テキストは逐語的に保持されます。
  • 内側列にあり、かつ r > r_end のセル(つまり、データと同じ列に "Total" ラベルや footer 数式を置く footer-row ケース)は、展開済みデータブロックの下に来るよう (N - 1) × (r_end - r_start + 1) 行だけ下へシフトします。

この非対称性 — ブロックより下の内側列セルはシフトし、同じ行にある外側列セルはシフトしない — は意図的です。メインデータブロックの右または左に置かれる、ブロック非依存の並列レポート領域である一般的な「サイド集計表」パターンを、別シート宣言なしで支えるためです。

ラベルと数式のペアを一緒にシフトさせたい場合(例: A4='footer'、B4=LOWER(A4))、作成者は両方のセルをブロックの列範囲内に置きます。marker セルがたまたま B まで届かない場合(例: A2 のみに marker がある場合)、B は外側となり A のシフトに追従しません。回避策は、B2 に marker を追加すること({{ "" }} のような trivial literal expression でも可)、または — 将来のリリースで利用可能になれば — 明示的な @block A:B 形式を使うことです。

ソース列

ソース列はブラケット構文で参照します。

{{ [Customer] }}
{{ [Customer Name] }}
{{ [Units Per Case] }}

[] の間のテキストは、囲む空白をトリムした後の正確なソース列名です。列名にはスペース、英字、数字、句読点を含めることができます(MAY)。ただし ] と改行は除きます。

セル内の {{ Customer }} のような裸の名前はソース列参照ではありません。裸の名前はシートおよびファイルグループキー専用です。

ADR-0054 により、テンプレートブロック内の裸の識別子は以下の順序で解決され、解決できない場合は xl3/expression/unknown-name が発生します。

コンテキスト解決順
output_file_patternファイルグループキー → __inputs__[name]__config__[name]
シート名パターンシートグループキー → __inputs__[name]__config__[name]
データセル外側のファイルグループキー → 外側のシートグループキー → __inputs__[name]__config__[name](真偽値リテラル TRUE/FALSE はこのチェインの前にリテラルとして解決される)

データセル内の裸の識別子はソース列に解決されません。列を参照するには、作成者は必ず明示的な [Column] 形式を使う必要があります(MUST)。データセル内のショートハンド解決チェインは、output_file_pattern{{ [Region] }}.xlsx であるシート内で {{ Region }} がそのアクティブグループの値を意図通りに読めるようにするために存在します。

リテラル

XTL 0.1 は以下をサポートします。

"text"
123
123.45
-123

文字列リテラル(ADR-0028 による)

" で囲まれた、対応のとれた組です。エスケープシーケンスはありません。バックスラッシュはそのまま透過します。0.x では文字列リテラル内に " を埋め込む規範的な方法はありません。値の中に " を含めたい作成者は、__config__ の作成者キーに保持し(セル内容には任意の文字を入れられます)、{{ __config__[key] }} で参照してください。

不整合または重複した引用符("a"b""a など)の挙動は実装定義です。ポータブルなテンプレートはリテラルごとにちょうど 1 組の対応した引用符を使ってください。

数値リテラル(ADR-0028 による)

10 進数で、負の符号として先頭に - を任意に置けます。許容される形:5-53.14-3.140。Unicode マイナス U+2212 は符号として認識されません(ADR-0009 の amendment による)。

非リテラル式に対する単項演算子は XTL 0.x ではサポートされません。 以下はすべて xl3/eval/unsupported-syntax を発生させます。

  • +5+[col](単項プラス)
  • --5-(0 - 5)(二重否定)
  • -[col]-(expr)-__config__[k](非リテラルに対する単項マイナス)

列の符号反転のワークアラウンド:(0 - [col]) または [col] * -1 と書きます。

演算子

算術 — +-*/

両オペランドは有限数に強制変換できる必要があります(MUST)。強制変換規則は ADR-0023 によります。

オペランド型強制変換後の値
Number(有限)そのまま
Boolean1(TRUE)/ 0(FALSE)
空(空値0
有限な数値としてパース可能な文字列パースされた数値
数値としてパースできない文字列エラー xl3/eval/operand-coercion
Dateエラー
その他エラー

文字列パースは ADR-0009 と ADR-0023 に従います。すなわち trim してから NaN を生まない Number()。カンマは桁区切りとして扱われ("1,234"1234 にパースされます)、リテラルでは指数表記なし、先頭の + もなしです。Unicode マイナス U+2212 は符号文字ではありません(ADR-0009 amendment)。

ADR-0064 により、文字列→数値の強制変換(リテラルパースとは別)は次の形を受け入れます。

受け入れ可?
10 進整数はい"42""-42"
10 進小数はい"3.14""-3.14"
桁区切りはい"1,234""-1,234.56"
指数表記はい"1e5""-1.5e-3""1.5E10"
16 進プレフィックス 0x/0Xいいえ — エラー xl3/eval/operand-coercion"0x10"
2 進プレフィックス 0b/0Bいいえ"0b101"
8 進プレフィックス 0o/0Oいいえ"0o17"
先頭 +いいえ"+5"
Unicode マイナス U+2212 プレフィックスいいえ"−5"
±Infinity を生じるいいえ"Infinity"、IEEE 754 オーバーフロー
末尾の非数値文字いいえ"5px""5 abc"
複数行文字列いいえ内部に LF を含む文字列

リテラルパース(厳格)と文字列強制変換(寛容)の間の非対称性は意図的です。リテラルは作成者が記述するものですが、強制変換される文字列はデータ(CSV エクスポート、財務システム)から来るもので、そこでは指数や 16 進表記が自然に出現します。

{{ [price] * [quantity] }}
{{ [total] / 10 }}
{{ [a] + [b] }}
{{ [a] - [b] }}

例:

結果
1 + 23
"10" + 515
"1,234" + 11235
TRUE + 12
[empty-cell] + 55
"abc" + 5エラー

ゼロ除算は Excel の #DIV/0! エラーセルを生成します(ADR-0025)。数値フォーマットの単一式セルは実際の Excel エラーセル(値 #DIV/0!)としてレンダリングされ、テキストフォーマットセル、混在テキストセル、または & 連結の内部では、その位置に文字列 "#DIV/0!" が置換されます。エラー値が同一セル式内の更なる算術演算子に流入する場合(例:(1/0) + 5)、有限数への強制変換に失敗し、上表に従い xl3/eval/operand-coercion を発生させます。

6 種類のソース側 Excel エラーセンチネル — #N/A#VALUE!#REF!#NAME?#NUM!#NULL! — は ADR-0017 に従いソースから空値として読み込まれます。ADR-0053 により、これらは混在テキストおよび & 連結位置で "" を寄与し、数値/日付フォーマットの単一式セルでは xl3/cell/numfmt-coercion を発生させます。#DIV/0! は XTL 評価中にエンジン自体が生成する唯一のセンチネルで、上記の規則に従います。ソース側センチネルに対して可視の「欠損」マーカーを出したい作成者は、列参照を IFEMPTY([col], "missing") でラップしてください。

文字列連結 — &

各オペランドは正規文字列形式(比較と文字列強制変換を参照)でストリング化され、結果が連結されます。常に成功し、型エラーは発生しません。

{{ [item] & " (" & [size] & ")" }}

比較 — =!=><>=<=

IF()@filter で使用します。比較と文字列強制変換のアルゴリズムに従います。型が混在する場合は正規文字列形式のコードポイント順にフォールスルーし、強制変換エラーは発生しません。

=
!=
>
<
>=
<=

比較と文字列強制変換

比較演算子(=!=><>=<=)と & 連結演算子は単一の強制変換モデルを共有します。IF() の条件と @filter ディレクティブは、ここで定義する比較アルゴリズムを使います。@sort も同じアルゴリズムを使います。

正規文字列形式

値の正規文字列形式は以下のとおりです。

  • 空値(空値)は空文字列 ""

  • Boolean:TRUE または FALSE(大文字)。

  • 有限な数値:その値を一意に識別する最短 10 進表現。小数点として . を用い、[1e-6, 1e21) の範囲では指数表記を使いません。整数は末尾の小数点を省略します。ECMA-262 §6.1.6.1.13 に一致します。

  • 文字列:その文字列自体。

  • 日付:時刻成分がちょうど真夜中(00:00:00)のときは YYYY-MM-DD、それ以外は YYYY-MM-DDTHH:mm:ss(ADR-0017 で定義。以前は ADR-0009 から繰り延べ)。

    日付要素は UTC で読まれる必要があります(MUST)。Excel のセルはタイムゾーンを持たないシリアル日付を格納し、ExcelJS などのライブラリはこれを UTC アンカーの Date オブジェクトとして返します。ローカルタイムゾーンのアクセサ(getFullYeargetMonthgetDate)を使うと、UTC ではないホスト上で 1 日ずれる現象が発生します。タイムゾーン考慮の日付(例:「ソウルの今日」のファイル名トークン)が必要なホストは、レンダラの外側で計算し、__inputs__ または __config__ を通して渡してください。

非有限な数値(NaNInfinity-Infinity)は仕様準拠の演算からは生じてはなりません(MUST NOT)。出現した場合は "" にストリング化されます。

比較アルゴリズム

比較演算子は以下の順に適用します。

  1. 両オペランドが空であれば等しい。= は真、!= は偽、>< は偽、>=<= は真。
  2. ちょうど一方のオペランドが空であれば、= は偽、!= は真。順序付けでは、空値は任意の非空値より小さい。
  3. 両オペランドが数値であるか、両方が「trim してから NaN を生まない Number()」を経て有限数にパースされる文字列であれば、数値として比較します。数値比較は IEEE 754 の等価性を使います。0.1 + 0.20.3 と等しくありません。許容差が必要なテンプレートは ROUND() で明示的に丸める必要があります(MUST)。
  4. 両オペランドが Boolean なら、falsetrue の前に置く順序で値として比較します。
  5. 両オペランドが日付であれば、内部タイムスタンプで比較します。これは、一方が真夜中のみの YYYY-MM-DD で他方が日時の場合をカバーします(そうでなければ異なる正規文字列として比較されてしまう)。
  6. それ以外の場合、正規文字列形式を Unicode コードポイント順で比較します。ロケール対応の照合は適用されません。Unicode 正規化も適用されません(ADR-0030)。NFC (U+D55C)と NFD (U+1112 U+1161 U+11AB)は同じに表示されますが、別の文字列として比較されます。混在形式のデータを持つ作成者は、上流で正規化してください。

& 連結

& は各オペランドを正規文字列形式にストリング化し、順に結合します。& の結果は常に文字列です。

関数

関数名は大文字小文字を区別しません。仕様では大文字で書きます。

ユーザ向けの各関数は規範的なアリティを持ちます(ADR-0024)。引数の数が誤っている呼び出しは、オペランド評価のに、パース/正規化時点で xl3/eval/arity-mismatch を発生させます。

関数引数備考
IF3条件, 真値, 偽値
IFEMPTY2値, フォールバック(別名:IFBLANK
ROUND2値, 桁数
ABS1
TEXT2値, フォーマット
ROW0現在のデータブロック内の行インデックス
TODAY0UTC 日付
YEAR1日付の 4 桁年(UTC) — ADR-0019 amendment
MONTH1日付の月 1-12(UTC) — ADR-0019 amendment
DAY1日付の日 1-31(UTC) — ADR-0019 amendment
EOMONTH2ある日付から N か月後の月の最終日(UTC 真夜中) — ADR-0019 amendment
EDATE2ある日付から N か月後の日付(同日にクランプ、UTC 真夜中) — ADR-0019 amendment
DATEDIF32 つの日付間の完全な "Y"/"M"/"D" 単位の整数カウント(start > end のときは負) — ADR-0019 amendment
HYPERLINK2url, ラベル — クリック可能なセルを生成 — ADR-0039
UPPER1文字列中の英字を大文字化 — ADR-0044
LOWER1文字列中の英字を小文字化 — ADR-0044
TRIM1先頭・末尾の空白を除去(内部は保持) — ADR-0044
IFERROR2値, フォールバック — 値がエラーセルマーカーのときフォールバックを返す — ADR-0044
IFS偶数 ≥ 2(条件, 値) のペア。最初に真の枝を返す。どれも真でなければ xl3/eval/no-match — ADR-0044
DATE3年, 1-based の月, 日 — UTC 真夜中 — ADR-0044
ISBLANK1値が ADR-0007 に従い空のとき真。IFEMPTY 述語の別名 — ADR-0047
XLOOKUP3 または 4値, lookup-array, return-array, [フォールバック]
SUM1列参照
AVERAGE(別名 AVG1列参照
MIN1列参照
MAX1列参照
COUNT0 または 10 = ブロック行数;1 = 列の非空カウント
CONCAT1+可変長。& の代替

IF

{{ IF([quantity] > 100, "bulk", "normal") }}

条件が真値(truthy)であるとき第 2 引数を返し、そうでなければ第 3 引数を返します。

値が真値(truthy)であるのは、次のいずれにも該当しない場合です。

  • Boolean の false
  • 数値 0
  • 空値に従い空である値 — 欠落、""、または空白のみの文字列。

文字列 "0""false" に対する特別な扱いはありません。非空白の内容を含む文字列は常に真値(truthy)で、文字列型のフラグ値 "0""false" であっても同様です。そうしたフラグを解釈する必要があるテンプレートは、明示的に比較する必要があります(MUST)。例:IF([flag] = "1", …)

比較式は Boolean に評価され、比較が成立するときに真値(truthy)となります。

IFEMPTY

{{ IFEMPTY([memo], "-") }}

第 1 引数が 空値 に従い空のとき第 2 引数を返します。それ以外の場合は第 1 引数を返します。

XLOOKUP

{{ XLOOKUP([Account], Customers[Account], Customers[Name]) }}
{{ XLOOKUP([Account], Customers[Account], Customers[Name], "(unknown)") }}

lookup_valuelookup_array の中から探し、対応する return_array の値を返します。配列はソース接頭辞付きのブラケット参照(例:Customers[Account])でなければならず(MUST)、同一のソースから来る必要があります(MUST)。

関数はソースの行をワークブック順に走査し、lookup_array 列が lookup_value比較アルゴリズム上で等しい最初の行を返します。マッチがない場合:

  • 第 4 引数が指定されていればそれを返す。
  • そうでなければエラー。

XTL 0.1 は完全一致のみをサポートします — ワイルドカード、近似一致、逆方向検索はありません。

ADR-0060 により、lookup_value(第 1 引数)とオプションの fallback(第 4 引数)は完全な XTL 式です。リテラル、裸のブラケット、ソース接頭辞付きブラケット、関数呼び出し、または合成式のいずれでもよい(MAY)。これらの位置の Source[Column] 参照はアクティブソース規則(ADR-0012)の対象となります。すなわち、Source が周囲のブロックのアクティブソースである場合のみ現在行に解決され、そうでなければ xl3/source/row-cross-block を発生させます。配列引数の制約(同一ソース、裸のブラケット禁止)は lookup_arrayreturn_array にのみ適用されます。

集計関数

集計はレンダリング中の現在の行セットに対して動作します。

{{ SUM([total]) }}
{{ COUNT() }}
{{ COUNT([customer]) }}
{{ AVERAGE([price]) }}
{{ MIN([date]) }}
{{ MAX([date]) }}

COUNT() は行数をカウントします。COUNT([field])[field] の値が空値に従い非空である行をカウントします。

ADR-0059 により、SUMAVERAGE(および別名 AVG)、MINMAX、および COUNT の 1 引数形式に渡す単一引数は、[Column] または Source[Column] の形の列参照でなければなりません(MUST)。それ以外の形(リテラル、式、関数呼び出し)は xl3/eval/bad-aggregate-arg を発生させます。行ごとの計算済み集計が必要な作成者は、上流でヘルパー列を追加するか、行ごとの値を別のセルで計算してください。

数値関数

{{ ROUND([amount], 0) }}
{{ ABS([delta]) }}

ROUND(value, places) は指定の小数点桁数に丸めます。丸めは half-away-from-zero(ゼロから遠ざかる方向)で、Excel の ROUND() と一致します(例:ROUND(2.5, 0)3ROUND(-2.5, 0)-3)。

テキスト書式

{{ TEXT([date], "YYYY-MM-DD") }}
{{ TEXT([amount], "#,##0") }}

以下のサポート対象フォーマットについて、TEXT() は文字列を返します。出力を数値や日付値のままにしたい場合は、テンプレートセルの数値/日付フォーマットを使ってください。

XTL 0.1 は以下の最小限の TEXT() フォーマットサブセットを定義します。

種別トークン/フォーマット意味
日付/時刻YYYY, YY, MM, DD, dd, HH, hh, mm, ssゼロパディングされたカレンダーフィールド(YYYYYY を除く)。DDdd はいずれも日。
数値0桁区切りなしの丸めた整数。
数値#,##0, の桁区切り付きの丸めた整数。
数値0.00桁区切りなしの 2 桁固定小数。
数値#,##0.00, の桁区切り付きの 2 桁固定小数。

数値の TEXT() の丸めは ROUND() と同じ half-away-from-zero の規則を使います。

この表の外のフォーマットは XTL 0.1 における拡張です。実装は追加のフォーマットを受け入れてよい(MAY)が、その正確な出力は実装定義であり、コア適合性の対象外です。ポータブルなテンプレートは上表のみを使う必要があります(MUST)。

行・日付関数

{{ ROW() }}
{{ TODAY() }}
{{ TEXT(TODAY(), "YYYY-MM-DD") }}

ROW() は現在のリピートブロック内の 1-based 行インデックスを返します。リピートブロックの外で ROW() を呼ぶのはエラーです。TODAY() はレンダリング時の UTC 日付を返します。実装はホストランタイムのローカルタイムゾーンを使ってはなりません(MUST NOT)。ロケール固有の日付が必要なテンプレートは、ソースワークブックで計算するか、__config__ を通じて作成者定義値として渡してください。

ディレクティブ

ディレクティブはテンプレート式として、通常データブロックの直上の行に書かれます。

{{ @filter [Status] = "Open" }}
{{ @filter [Customer] in __lists__[IncludedCustomers] }}
{{ @filter [Category] !in __lists__[ExcludedCategories] }}
{{ @sort [total] desc }}
{{ @group [Region], [Customer] }}
{{ @top 10 }}
{{ @repeat right 3 }}
{{ @source Renewals }}
{{ @join Customers on Customers[Account] = Renewals[Account] }}
{{ @block A:D }}

ディレクティブ名とソート方向は大文字小文字を区別しません。

@block — 明示的なデータブロック宣言

ADR-0067 により、@block は作成者がデータブロックの geometry を明示的に宣言できるようにします。3 つの形式を認識します。

@block — bare。列範囲は {{...}} marker から自動検出
@block <col-range> — 明示的な列範囲。例: A:D
@block <full-rect> — 明示的な行 × 列矩形。例: A2:D7

@block directive セルは、ブロックの最初の行より厳密に上の行に置かれます。引数なしの場合、ブロックの列範囲は directive の下にある {{ ... }} marker セルの bounding box です(ADR-0066 の列スコープ検出)。A:D のような col-range 引数では、列範囲が明示され、行範囲は自動検出されます。A2:D7 のような完全矩形では、行範囲と列範囲の両方が明示されます。矩形は少なくとも 1 つの marker cell を含む必要があり(MUST)、そうでなければ xl3/block/empty-table が発生します。

同一シート上の 2 つの @block 矩形は重なってはなりません(MUST NOT)。任意の行 × 列交差は xl3/block/overlap を発生させます。

ブロック検出モード(ADR-0068、strict): シートは zero 個の @block directive を持つ(implicit mode — ADR-0066 の single-block cluster detection が適用され、複数の disconnected cluster は xl3/expression/bracket-outside-block を発生させる)か、1 個以上の @block directive を持つ(explicit mode — すべての [Column] marker cells はいずれかの @block 矩形内に存在しなければならず(MUST)、orphan marker は同じエラーコードを発生させる)かのどちらかです。

multi-block シートでの directive スコープ(ADR-0069): その他すべての directive — @filter@sort@top@source@join@group@repeat — は proximity によって特定のブロックに attach されます。

directive D(r_D, c_D) にあるとする。これは、(1) r_D < B.startRow、(2) B.colStart ≤ c_D ≤ B.colEnd、(3) (1) と (2) を満たすブロックの中で B.startRow - r_D が最小、を満たすデータブロック B に attach される。(1) と (2) を満たすブロックがない場合、その directive は xl3/directive/orphan を発生させる。

この規則は single-block シートでは正しく退化します。候補が 1 つしかないため、closest-block-below check は自明です。

ブロック内の ROW() は、そのブロックの iteration index(レコードごとに 1-based)を返します。どのブロックにも属さない ROW() セルは xl3/expression/row-outside-block を発生させます。

Filter

@filter [field] operator value

演算子:

=
!=
>
<
>=
<=
in
!in

in!in__lists__[<name>] の形のリスト参照を要求します(ADR-0011)。ここで <name> は予約シート __lists__ 内の列ヘッダです。レガシーの _<name> リストシート形式は廃止されました。

複数の @filter ディレクティブは AND で合成されます。 行がブロックを通過するのは、すべての @filter 述語が満たされる場合のみです。XTL 0.1 に OR の形はありません。論理和が必要なテンプレートは、__lists__[…] メンバーシップフィルタで代替を合成するか、上流でソースを事前フィルタしてください。

{{ @filter [Region] = "Seoul" }}
{{ @filter [Amount] > 10000 }}

行は両方の条件を満たす場合のみ通過します。

Sort

@sort [field] asc
@sort [field] desc

方向を省略した場合は asc が使われます。

@sort は**安定(stable)**です。ソートキーが等しい行は、ソース順序を保ちます。複数の @sort ディレクティブがある場合、最初のディレクティブが主ソートキーで、以降のディレクティブは出現順にタイブレーカーとなります。ソース順序は最後のタイブレーカーです(Excel の「並べ替え … 次に並べ替え」や SQL の ORDER BY a, b と一致)。

Top

@top 10

フィルタとソートの後で先頭 N 行を保持します。ADR-0055 により、N は正の整数(≥ 1)でなければなりません(MUST)。@top 0@top -5@top 05(先頭ゼロ)はパースエラーで xl3/directive/invalid-syntax を発生させます。

Repeat Right

@repeat right
@repeat right 3

検出されたデータブロックを水平方向に繰り返します。オプションの数値は繰り返し 1 件あたりの列スパンです。省略時の列スパンは 1 です。ADR-0055 により、列スパンは正の整数(≥ 1)でなければなりません(MUST)。@repeat right 0@repeat right -3xl3/directive/invalid-syntax を発生させます。

Source

@source <SourceName>

周囲のデータブロックを、__sources__ で宣言された名前付きソースにスコープします(ADR-0012)。ブロック内では、ブラケットショートハンド [Column] はアクティブソースの行に解決され、Source[Column] 上の集計は従来通り動作します。@source がなければ、アクティブソースは __config__ で構成された既定の source_sheet です。

明示的な @source default は合法で、ディレクティブを省略するのと等価です(ADR-0065)。ソース名引数は大文字小文字を区別します。@source DEFAULTxl3/source/undeclared を発生させます。__sources__ の行でその名前を宣言したものがないためです。

未宣言ソースの参照はエラーです。ソースのヘッダに宣言されていない列の参照はエラーです(xl3/source/unknown-column)。空値への暗黙のフォールスルーはタイプミスを覆い隠します。

Join

@join <JoinedSource> on <JoinedSource>[<key>] = <PrimarySource>[<key>]

@source ブロックの各プライマリ行を、<JoinedSource> の最初にマッチした行とペアにします(ADR-0014、内部結合セマンティクス、最初のマッチ)。マッチしないプライマリ行はドロップされます。ブロック内では、<PrimarySource>[Column] と裸の [Column] はプライマリ行に解決され、<JoinedSource>[Column] はペアになった結合行に解決されます。複数の @join 句、左結合セマンティクス、複数行マッチは XTL 0.1 の範囲外です。

on 句の両辺はソース接頭辞付きのブラケット参照でなければなりません(MUST)。一方が <JoinedSource>、他方が <PrimarySource> を指名する必要があります(MUST)。いずれかのソースが __sources__ で未宣言、または on 句が不正な場合はエラーです。

Group + Subtotal

@group [Key1], [Key2], …, [KeyN]

@group は、アクティブな行セットを N レベルのネストされたグループに分割し、単一のデータブロック内で @subtotal 行を交互に出力するためのものです(ADR-0038)。グループの同定には ADR-0009 の正規文字列等価ルールを使い、グループ順は @filter@sort が適用されたの出現順です(@group 自体は並べ替えを行いません)。

データブロックは最大 1 つの @group を含むことができます(MAY)。キーリストのない @groupxl3/group/missing-key を発生させます。@group@repeat right と両立しません(xl3/directive/invalid-syntax)。

@subtotal 行は、1 つ以上の {{ @subtotal <aggregate> }} 式を含みます。各小計行は 1 つのグループネスティングレベルにバインドされます。ソース順で最初@subtotal 行は最内側のキー([KeyN])にバインドされ、次の行は [KeyN-1] にバインドされ、外側へと続きます。最外側の @subtotal はデータブロックの末尾で 1 度発火します(「最外側 subtotal による総合計」パターン)。

サポートする集計本体 — それ以外は xl3/subtotal/bad-aggregate を発生させます。

  • SUM(<column-ref>)
  • COUNT() または COUNT(<column-ref>)
  • AVERAGE(<column-ref>)
  • MIN(<column-ref>)
  • MAX(<column-ref>)

合成式(SUM([A]) - SUM([B])IF(...) など)は繰り延べです。集計内の列参照は他の箇所と同じ [Column] / Source[Column] 形式に従います。ADR-0038 § "Aggregate scoping" のスコープ規則が適用されます — 集計はブロック全体ではなく、現在のグループの行セットに対して動作します。

ADR-0058 により、@subtotal 行は異なるセルに任意の数の {{ @subtotal <aggregate> }} 式を含むことができます(MAY)。これらはすべて、行の単一のネスティングレベルバインディング(行順から推測されるレベル)を共有し、各発火時に同じグループ行セットに対して評価されます。1 つの小計行に集計種類(SUM + COUNT + AVERAGE)と列参照を混在させることが許容されます。

@subtotal 行は、リテラルテキストセル、静的数式、および現在行の列を参照しない他の {{ ... }} 式も持つことができます(MAY)。グループ境界では「現在行」が存在しないためです。集計の外で現在行の列を参照すると xl3/expression/unknown-name クラスのエラーが発生します。

空のグループ — すべてのデータ行が空(ADR-0007)— はスキップされます。

{{ @sort [Region] }}
{{ @sort [Customer] }}
{{ @group [Region], [Customer] }}
{{ [Region] }} | {{ [Customer] }} | {{ [Amount] }}
"Customer subtotal" | | {{ @subtotal SUM([Amount]) }}
"Region subtotal" | | {{ @subtotal SUM([Amount]) }}

エラー:

  • xl3/group/missing-key — キーリストのない @group
  • xl3/subtotal/outside-group@group のないブロック内の @subtotal セル、または @group のキー数より多い @subtotal 行。
  • xl3/subtotal/bad-aggregate@subtotal 本体が SUMCOUNTAVERAGEMINMAX のいずれでもないか、引数が許容形式の列参照ではない。

グループキー

Excel のシート名には [] を含められないので、シート名は裸のグループキーを使います。

{{ Customer }}

ファイルパターンは裸のグループキーまたはブラケット付きソース列のいずれかを使うことができます。

{{ Customer }}_report.xlsx
{{ [Customer] }}_report.xlsx
{{ TEXT(TODAY(), "YYYY-MM-DD") }}_report.xlsx