4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Power Query】集計定義をExcelシートに外出してTable.Groupをクエリの外から制御する

4
Last updated at Posted at 2026-02-07

動機

Power Queryでデータのグループ化(SQLで言うところのGROUP BY)を行う際、「集計する列を増やしたい」「合計も見たいけど、平均も見たくなった」といった感じで、変更があるたびにクエリを編集してメンドクサイと思ってました。
ということで、「集計の定義(キー項目や計算方法)をExcelのテーブルに記述して、Power Query側は一切触らずに集計結果を変える」 ということにチャレンジしました。

Power QueryのM言語は「関数を値として扱えるという性質」があるので、これを活用しています。

やりたいこと

  1. データソース: T_売上 というテーブル。
  2. 設定ファイル: T_CONFIG というテーブルに、「どの列をキーにするか」「どの列をどう集計するか(SUM, MAXなど)」を記述して、 Table.Groupを外から制御します。
  3. Power Query: 設定ファイルを読み込み、動的に Table.Group を生成・実行する。

テスト用売上データ(T_売上)

集計対象のテスト用データ。

地域名 都道府県 売上金額 点数 来店回数 日付
東北 青森 1,000 80 1 2025/1/31
東北 青森 2,000 90 5 2026/2/7
東北 青森 1,500 85 3 2026/2/7
関東 東京 5,000 60 2 2025/1/31
関東 東京 3,000 70 1 2026/2/7
東海 名古屋 8,000 100 10 2025/1/31
東海 名古屋 1,000 40 1 2026/2/7

設定テーブル(T_CONFIG)のイメージ

これが今回の Table.Groupを外から制御するテーブル」 です。

新しい列名 対象列 集計タイプ
(指定しなくてよい) 地域名 KEY text
(指定しなくてよい) 都道府県 KEY text
売上合計 売上金額 SUM number
最高スコア 点数 MAX number
最低スコア 点数 MIN number
平均来店数 来店回数 AVG number
取引件数 (指定しなくてよい) COUNT Int64
最終取引日 日付 MAX date
  • KEY: グループ化のキー項目(複数指定可)
  • SUM, MAX 等: 集計関数
  • COUNT: 行数のカウント

M言語コード

詳細エディタに記述するコードです。

let
    // 1. データと設定の読み込み
    Source = Excel.CurrentWorkbook(){[Name="T_売上"]}[Content],
    Config = Excel.CurrentWorkbook(){[Name="T_CONFIG"]}[Content],

    // 2. 設定を「キー」と「集計」に分離
    KeyRows = Table.SelectRows(Config, each [集計タイプ] = "KEY"),
    AggRows = Table.SelectRows(Config, each [集計タイプ] <> "KEY"),

    // グループ化キーをリストとして取得(Table.Groupの第2引数用)
    GroupKeys = Table.Column(KeyRows, "対象列"),

    // ★関数を「辞書(Record)」で管理する
    // 3. 文字列と関数のマッピング辞書
    FuncMap = [
        SUM   = List.Sum,
        MAX   = List.Max,
        MIN   = List.Min,
        AVG   = List.Average,
        // COUNTはテーブル全体を受け取る関数として定義(後述のif分岐で使用)
        COUNT = Table.RowCount 
    ],

    // 4. 文字列と型のマッピング辞書
    TypeMap = [
        number   = type number,
        Int64    = Int64.Type,
        text     = type text,
        date     = type datetime,
        any      = type any
    ],

    // 5. 動的な集計リストの生成(ここが心臓部!)
    Aggregations = List.Transform(
        Table.ToRecords(AggRows), 
        (row) => {
            // 第1要素: 新しい列名
            row[新しい列名],

            // 第2要素: 集計ロジック(関数)
            (groupedTable) => 
                // ★COUNT(テーブル操作)とSUM等(リスト操作)の分岐
                if row[集計タイプ] = "COUNT" 
                then
                    // List.Countを使えばif文で分けなくても良いのですが、List.Countはnull値をカウントしないため、このようにしてます。
                    FuncMap[COUNT](groupedTable) 
                else 
                    // 文字列から関数を取り出し、列データを抽出して適用
                    Record.Field(FuncMap, row[集計タイプ])(Table.Column(groupedTable, row[対象列])),

            // 第3要素: 型(文字列から型オブジェクトへ変換)
            Record.FieldOrDefault(TypeMap, row[], type any)
        }
    ),

    // 6. グループ化の実行
    Grouped = Table.Group(
        Source, 
        GroupKeys,   // 動的キー
        Aggregations // 動的集計定義
    )
in
    Grouped

実行結果

こんな感じ。
image.png

このコードのポイント

1. 関数を「辞書(Record)」で管理する

M言語では、関数も 1"A" と同じようにデータとして扱えます。
FuncMap というレコードを作り、SUM という文字列キーに対して List.Sum という関数そのものを値として持たせています。

これにより、Record.Field(FuncMap, "SUM") とすることで、動的に関数を呼び出せるようになります。

2. リスト操作 vs テーブル操作

集計関数には2種類あります。

  • List系: List.Sum([売上]) のように、列(リスト) を引数に取るもの。
  • Table系: Table.RowCount(_) のように、テーブル を引数に取るもの。

Table.Group の内部では、グループ化された「サブテーブル(groupedTable)」が渡されてきます。
そのため、コード内の の部分で条件分岐を行っています。

  • COUNTの場合: サブテーブルをそのまま Table.RowCount に渡す。
  • それ以外: Table.Column を使って、サブテーブルから特定の列(リスト)を引き抜いてから List.Sum などに渡す。

Note:
List.Count を使えばList系に統一できるので if 分岐は消せるんですが、その場合 List.Countnull をカウントしないため、NULLを含む列を数える際に Table.RowCount と結果がズレる可能性がありまして、あえてif 分岐してます。

3. 型を動的に指定する

type number などの型情報は、Excelのセルには書けません(ただの文字列 "number" になってしまう)。
これも TypeMap を用意することで、Excel上の文字列を Power Query の正しい型オブジェクトに変換しています。
Record.FieldOrDefault を使うことで、未知の型が来た場合はとりあえず type any で逃げてます。

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?