18 · グループ + 小計行
シナリオ
取引明細書 / 精算書 / 発注書でライン項目を顧客別または月別セクションに分け、各セクションの最後に小計行 +(オプション)最後に総合計行を置くパターン:
アクメ ウィジェット-A 10,000
アクメ ウィジェット-B 5,000
小計 15,000
ベータ ウィジェット-A 20,000
小計 20,000
総合計 35,000
XTL 0.6 はこのパターンを 1 つのデータブロック内で作ってくれます ― ソースで事前集計したり、出力後に後処理する必要はありません(ADR-0038)。
2 つの要素
@group [Key1], [Key2], …
@group はアクティブな行集合を N レベルのネストされたグループに分割します。行を並べ直しはしません ― グループ順序は @filter / @sort が適用された後の登場順序に従います。グループ順序を安定させたければ同じキーで @sort も掛けてください。
{{ @sort [取引先] }}
{{ @group [取引先] }}
@subtotal <aggregate>
セルに {{ @subtotal SUM([金額]) }} 式が入った行が 小計行です。
この行はソース行ごとに反復せず、レンダー時点で各グループ境界に 1 度ずつバインドされたレベルで emit されます。サポート集計: SUM、COUNT、AVERAGE、MIN、MAX。
ソース順で最初の @subtotal 行が最も内側のグループキーにバインドされます。下に追加した @subtotal 行がだんだん外側のレベルにバインドされます ― 一番下の行が最も外側のキーにバインドされます。
単一レベルグループ
{{ @sort [取引先] }}
{{ @group [取引先] }}
{{ [取引先] }} | {{ [品目] }} | {{ [金額] }}
"小計" | | {{ @subtotal SUM([金額]) }}
ソース 3 行(アクメ/ウィジェット/100、ベータ/ボルト/50、アクメ/ギア/200)でレンダリング:
アクメ ウィジェット 100
アクメ ギア 200
小計 300
ベータ ボルト 50
小計 50
2 レベルネスト + 総合計
{{ @sort [地域] }}
{{ @sort [取引先] }}
{{ @group [地域], [取引先] }}
{{ [地域] }} | {{ [取引先] }} | {{ [金額] }}
"顧客小計" | | {{ @subtotal SUM([金額]) }}
"地域小計" | | {{ @subtotal SUM([金額]) }}
上の @subtotal(顧客小計)が内側のキー([取引先])にバインドされ、下の
@subtotal(地域小計)が [地域] にバイ ンドされます。両方とも境界ごとに emit されますが、
共通境界では内側が先に fire されます。
「最外 @subtotal による総合計」パターン: @group [取引先] 1 行 + 2 つの
@subtotal 行を置くと、外の行はデータブロックの最後にちょうど 1 度だけ fire されます ― 最も
外側のグループの境界が即データの終わりだからです。
他のディレクティブとの組み合わせ
| Directive | 動作 |
|---|---|
@filter | グループ化の 前に適用。フィルタされた行はどのグループにも属さない。すべての行がフィルタされたグループは出力に登場しない。 |
@sort | グループ化の前に適用。グループ順序を固定したければ @group と同じキーで同じ順序で @sort を掛けてください。 |
@source | 各 @source ブロックは独立したグループ化 scope を持ちます。 |
@join | ジョインされた行の列も primary 列と同じくグループ化に参加可能。 |
@top | グループ化の 後に行レベルで適用。@top cut を通過したグループのデータ行がある場合にのみ小計が emit。 |
@repeat right | @group と互換性なし(xl3/directive/invalid-syntax)。 |
エッジケース
- 単一グループ degenerate ―
@group [Key]ですべての行が同じ[Key]値を 持つ場合、小計はそのグループ境界で 1 度 emit されます。データセットが偶然単一の 外側グループ値を持つときに総合計パターンと一致します。 - 空グループ ― ADR-0007 基準ですべてのデータ行が empty なグループはスキップされます
(データ行も
@subtotalも emit されない)。 - 集計引数 ―
@subtotal内には列参照だけ許容されます。複合式 (SUM([A]) - SUM([B])、IF(...))はxl3/subtotal/bad-aggregateを投げ、 今後の ADR に延期されます。 @subtotal行のリテラルテキストセル ― 可能。「小計:」のようなラベルセルが集計セル の隣に入り、emit のたびに一緒にレンダーされます。ただしリテラルセルは現在行の列を 参照してはいけません ― グループ境界には「現在行」がありません。
エラーコード
xl3/group/missing-key―@groupにキーがない。xl3/subtotal/outside-group―@groupがないブロックで@subtotalセルが 登場したか、@groupキー数より@subtotal行が多い。xl3/subtotal/bad-aggregate―@subtotal本体がSUM、COUNT、AVERAGE、MIN、MAXのいずれでもないか、引数が許容された列参照形式ではない。
参照
- ADR-0038 —
@groupと@subtotaldirective spec/language.md§ "Group + Subtotal"- Cookbook 03 — 集計関数 ― グループ化なしでブロックレベルで使う
SUM/COUNT/AVERAGE - Cookbook 15 — Directive 組み合わせ ― 全 directive 順序ルール