Excel の GROUPBY / PIVOTBY で、明細の「取引日(毎日)」を“月別(年月)”にまとめたいのに、EOMONTH などの補助列を追加したくない——そんなときは「同じ月なら同じ値になる“月キー”」を式の中で生成して、そのまま行(列)キーに渡すのが最短ルートです。
結論:月キーを“式の中で生成”して GROUPBY / PIVOTBY のキーに渡せばOK
GROUPBY / PIVOTBY は「キー(row_fields / col_fields)」に入れた値でグルーピングします。つまり、日付が毎日バラバラでも、同じ月なら同じ値になる“月キー”に変換して渡せば、補助列なしで月別集計できます。
月キーの作り方は大きく2系統あります。
- 当月1日に丸める(例:2026/01/23 → 2026/01/01)
- 月末日に丸める(例:2026/01/23 → 2026/01/31)
どちらでも「同じ月なら同じ値」になるので集計可能ですが、実務では当月1日丸めがトラブルが少なくおすすめです(締め日運用が月末固定なら月末丸めも相性良い)。
前提:日付に“時刻”が混ざると月キーがズレることがある
請求・売上データの取引日が、見た目は日付でも中身が「2026/01/23 14:32」のように時刻を含むケースがあります。この場合、月キー計算に DAY を使っても大きく崩れることは少ないですが、後工程で比較や一致判定をしたときに思わぬ差が出ます。
安定させたい場合は、まず INT で日付部分だけに落とすのが堅いです。
INT(Table1[Invoice Date])
解決策A:その月の「1日」に丸めて月キー化(ヘルパー列不要・最推奨)
「日付 – DAY(日付) + 1」で必ず当月1日になります。これを row_fields(行方向のキー)に渡すだけです。
GROUPBY:月別合計(最小構成)
=GROUPBY(
Table1[Invoice Date]-DAY(Table1[Invoice Date])+1,
Table1[Amount],
SUM
)
テーブル参照(Table1[Invoice Date])は列(配列)なので、算術演算が“行ごと”に自然に働き、補助列なしで月キー配列が作れます。
GROUPBY:日付に時刻が混じる可能性がある版(より堅牢)
=LET(
d, INT(Table1[Invoice Date]),
m, d-DAY(d)+1,
GROUPBY(m, Table1[Amount], SUM)
)
LET を使うと読みやすく、同じ計算を繰り返さないのでパフォーマンス面でも有利です。
(参考)質問でよく使われる「ヘッダー無し・総計あり」の形
GROUPBY の構文は GROUPBY(row_fields,values,function,[field_headers],[total_depth],...) です。
以下は「フィールドヘッダー無し(0)」「総計だけ表示(1)」の例です。
=GROUPBY(
Table1[Invoice Date]-DAY(Table1[Invoice Date])+1,
Table1[Amount],
SUM,
0,
1
)
月キーがどう揃うのか(イメージ)
| 取引日 | 当月1日(月キー) | 同じ月なら一致? |
|---|---|---|
| 2026/01/01 | 2026/01/01 | 一致 |
| 2026/01/23 | 2026/01/01 | 一致 |
| 2026/01/31 | 2026/01/01 | 一致 |
| 2026/02/01 | 2026/02/01 | 別月なので不一致 |
解決策B:EOMONTH で月末に丸める(月末締め・月末基準の帳票向け)
月末日を月キーにすると「締め日=月末」の運用や、「各月末時点」の集計と相性が良いです。基本形は次のとおりです。
=GROUPBY(
EOMONTH(Table1[Invoice Date], 0),
Table1[Amount],
SUM
)
ただし環境やデータ状態によっては、EOMONTH(Table1[Invoice Date],0) が期待どおり配列評価されず、エラーや意図しない結果になることがあります。その場合の定番回避策が「単項プラス」です。
=GROUPBY(
EOMONTH(+Table1[Invoice Date], 0),
Table1[Amount],
SUM
)
単項プラス(+Table1[Invoice Date])は、値を数値(シリアル値)として扱う方向に寄せるため、配列として評価されやすくなります。日付が文字列で混入している場合の“あぶり出し”にもなります(変換できない行があるとエラーになりやすい)。
「当月1日」丸めと「月末」丸め、どっちを選ぶ?
| 方式 | 月キー例(2026/01/23) | 向いている場面 | 注意点 |
|---|---|---|---|
当月1日丸めd-DAY(d)+1 | 2026/01/01 | 月別集計の基本形、時系列ソートを安定させたい | 締め日が月末固定で「月末日」を表示したい帳票は表示側で工夫 |
月末丸めEOMONTH(d,0) | 2026/01/31 | 月末締め、月末時点の残高・実績など | 配列評価やデータ型(文字列日付)でつまずくときがある |
PIVOTBY でも同じ:月キーを col_fields(列方向キー)に渡すだけ
PIVOTBY は、行と列の2軸でグルーピングできます。構文は PIVOTBY(row_fields,col_fields,values,function,...) です。
たとえば「行=商品」「列=月(当月1日キー)」「値=金額」の月別クロス集計は次のイメージになります。
=LET(
d, INT(Table1[Invoice Date]),
m, d-DAY(d)+1,
PIVOTBY(
Table1[Product],
m,
Table1[Amount],
SUM
)
)
これだけで、ピボットテーブル風の「商品 × 月」の表が動的に生成されます。元データが増減しても式が追従するのが強みです。
並び順を時系列に揃えたいとき(列の月を昇順)
月キーが日付型なら、基本は昇順に並びやすく、時系列も崩れにくいです。さらに制御したい場合は、PIVOTBY の row_sort_order / col_sort_order を指定します(数値は「どのフィールド/値列でソートするか」を表し、負数で降順)。
下は「行も列も昇順、総計なし」の一例です(省略した引数は既定値)。
=LET(
d, INT(Table1[Invoice Date]),
m, d-DAY(d)+1,
PIVOTBY(
Table1[Product],
m,
Table1[Amount],
SUM,
0, /* field_headers */
0, /* row_total_depth */
1, /* row_sort_order */
0, /* col_total_depth */
1 /* col_sort_order */
)
)
「なぜ引き算はOKで、EOMONTH がNGになりがちなのか」
Excel の列参照(テーブル列や範囲)に対して、-DAY(...)+1 のような算術演算は要素ごとに計算されやすく、動的配列として素直に展開されます。一方で、関数によっては列参照を渡したときの評価のされ方が揺れることがあり、EOMONTH はその影響を受けるケースがあります。
単項プラス(+列)は、値を数値として扱う方向に寄せるため、結果的に「列全体に関数が適用される」挙動に寄ることがあり、回避策として使われます。すべての環境で必ず必要になるわけではありませんが、「EOMONTH で弾かれる」症状が出たときの実用的な手当てとして覚えておくと役立ちます。
表示を「yyyy-mm」「mmm-yy」にしたい:集計キーは日付のまま、見た目だけ整える
月を TEXT で文字列化して集計することもできますが、文字列は環境やロケールによって並び順が崩れやすい(例:Apr が Feb より前に来るなど)ため、基本方針は次のとおりです。
- 集計キー:日付型の月キー(当月1日 or 月末)
- 表示:セルの表示形式、または結果に対して TEXT をかける
おすすめ:結果側のセル表示形式を変える
月キーが日付なら、出力表の月列(行)に表示形式を設定するだけで「2026-01」「2026年1月」などに整えられます。これが最も安全です(ソートも時系列のまま)。
式で表示文字列にしたい場合(並び順対策込み)
どうしても出力に文字列で出したいなら、「表示用テキスト」と「ソート用の月キー」を分離するのがコツです。たとえば GROUPBY 結果に対して、SORTBY で月キー順に並べてから表示を整えます。
=LET(
d, INT(Table1[Invoice Date]),
m, d-DAY(d)+1,
g, GROUPBY(m, Table1[Amount], SUM),
/* g の1列目(月キー)で並べ、表示だけ yyyy-mm に */
HSTACK(
TEXT(TAKE(g,,1), "yyyy-mm"),
TAKE(g,,-1)
)
)
ポイントは「内部の並び替え・集計は日付で行い、最後に表示だけ変える」ことです。
実務で効く応用:月別 × 取引先(2段階のグルーピング)
「月別だけ」でなく、月別×取引先、月別×部門など、2つ以上のキーで集計したい場面は多いです。GROUPBY の row_fields は複数列を渡せるので、HSTACK でキーを横に並べて渡します。
=LET(
d, INT(Table1[Invoice Date]),
m, d-DAY(d)+1,
k, HSTACK(m, Table1[Customer]),
GROUPBY(k, Table1[Amount], SUM, 0, 2)
)
total_depth を 2 にすると、可能な範囲で小計も出せます(階層として扱うかどうかはデータと意図次第)。
フィルタ条件を式だけで入れる(支払済みだけ、特定商品だけ等)
GROUPBY / PIVOTBY は filter_array(真偽値配列)で対象行を絞れます。
例:ステータスが「Paid」の行だけ月別合計
=LET(
d, INT(Table1[Invoice Date]),
m, d-DAY(d)+1,
f, Table1[Status]="Paid",
GROUPBY(m, Table1[Amount], SUM, 0, 1, 1, f)
)
このやり方なら、フィルタ済みの別テーブルを作らずに、1本の式で「条件つき月別集計」が完成します。
よくあるエラーと対処(補助列なし運用で詰まりやすい所)
| 症状 | 主な原因 | 対処 |
|---|---|---|
| #VALUE! / 計算できない | 取引日が文字列(見た目だけ日付) | 元データを日付型に直す/式側で DATEVALUE や -- を検討(変換できない行は要修正) |
| 月キーが期待と違う | 時刻が含まれている、タイムスタンプ混入 | INT(Table1[Invoice Date]) を挟んで日付部分に統一 |
| 並び順が月順にならない | TEXT で年月を文字列化している | 集計キーは日付のままにして、表示形式で整える(文字列化は最後) |
| EOMONTH でエラーになる | 配列評価やデータ型の揺れ | EOMONTH(+Table1[Invoice Date],0) を試す/日付が文字列なら元データを修正 |
| 出力がスピルできない | 結果の展開先にデータがある | 出力先を空ける/別シートに出す |
テンプレ:そのままコピペで使える月別集計レシピ
月別「合計」
=LET(
d, INT(Table1[Invoice Date]),
m, d-DAY(d)+1,
GROUPBY(m, Table1[Amount], SUM)
)
月別「件数」(行数を数える)
=LET(
d, INT(Table1[Invoice Date]),
m, d-DAY(d)+1,
GROUPBY(m, Table1[Invoice Date], COUNTA)
)
月別「平均単価」
=LET(
d, INT(Table1[Invoice Date]),
m, d-DAY(d)+1,
GROUPBY(m, Table1[Amount], AVERAGE)
)
月別 × 部門の「合計」(2キー)
=LET(
d, INT(Table1[Invoice Date]),
m, d-DAY(d)+1,
k, HSTACK(m, Table1[Department]),
GROUPBY(k, Table1[Amount], SUM)
)
会計年度(例:4月始まり)で月別にしたい場合
年度が4月始まりなら「3か月戻してから月キー化」すると、年度内の月並びが作りやすくなります。集計はシフトしたキーで行い、表示は必要に応じて戻します。
=LET(
d, INT(Table1[Invoice Date]),
shifted, EDATE(d, -3),
fyKey, shifted-DAY(shifted)+1,
GROUPBY(fyKey, Table1[Amount], SUM)
)
この出力は「会計年度内の月順」になりやすく、年度レポートで扱いやすいのが利点です。表示を「年度+月」にしたい場合は、結果側で TEXT を使うか、表示形式を整えます。
運用のコツ:補助列なしでも“読みやすく・壊れにくく”する
- LET で月キーを変数化:同じ計算を繰り返さず、式の保守が楽になります。
- 日付は INT で正規化:時刻混入や外部取り込みの癖に強くなります。
- 表示は最後に:月キー(日付)で集計・ソートして、見た目だけ yyyy-mm などに整えるのが安全です。
- フィルタは filter_array で完結:抽出用の別表を作らず、月別集計を1本の式に閉じ込められます。
補助列を作らない最大のメリットは「元データの形を変えずに、集計ロジックを式に閉じ込められる」ことです。月キー生成をパターン化しておけば、売上・請求・入金・工数など、日付が毎日並ぶデータはすべて同じ発想で月別に変換できます。

コメント