Power Query 実務テンプレ | データ取込・更新系:フォルダ内Excel一括取込

Excel VBA Power Query M Formula Language
スポンサーリンク

ゴールのイメージをそろえる

今回のテーマは「フォルダの中にある複数の Excel ファイルを、Power Query で“まとめて一括取込して、1つの表に縦に並べる”実務テンプレ」を、初心者でも腹落ちするレベルで理解することです。

毎月ブック・毎日ブック・店舗別ブックなど、「構造は同じ Excel がたくさんある」状況を前提にします。
キーワードは Folder.FilesExcel.Workbook、そして「Content 列をどう扱うか」です。


全体の流れをざっくり言葉でつかむ

一括取込の4ステップ

やっていることを、いったん日本語だけで整理します。

フォルダの中のファイル一覧を表として取得する。
その中から「取り込み対象の Excel だけ」に絞り込む。
各ファイルの中身(シート)をテーブルに変換する。
それらのテーブルを縦にくっつけて、1つの大きな表にする。

この「一覧 → 絞り込み → 中身をテーブル化 → 結合」という流れさえ頭に入れば、
M コードを見ても「何をしているか」が追いやすくなります。


例題の前提を決める

想定するフォルダ構成

たとえば、こんなフォルダを想定します。

C:\Data\MonthlyBooks

中には、毎月の売上ブックが入っています。

売上_2024-08.xlsx
売上_2024-09.xlsx
売上_2024-10.xlsx

各ブックの構造は同じで、1枚目のシートにこんな表があるとします。

日付 / 店舗 / 商品 / 数量 / 金額

やりたいことは、「この3つ(今後増える分も含めて)を全部縦に並べて、1つの売上テーブルにする」です。


実務テンプレ M コード(1枚目シートを一括取込)

完成コードを先に出す

まずは、よく使う“型”をそのまま出します。

let
    // 1) フォルダ内のファイル一覧を取得
    Source = Folder.Files("C:\Data\MonthlyBooks"),

    // 2) .xlsx だけに絞り込む
    OnlyXlsx =
        Table.SelectRows(
            Source,
            each Text.Lower([Extension]) = ".xlsx"
        ),

    // 3) 各ブックの 1 枚目シートをテーブル化
    WithSheetTable =
        Table.AddColumn(
            OnlyXlsx,
            "SheetTable",
            each
                let
                    wb =
                        Excel.Workbook(
                            [Content],
                            true,
                            true
                        ),
                    firstSheetRow =
                        Table.SelectRows(wb, each [Kind] = "Sheet"){0},
                    firstSheetTable = firstSheetRow[Data],
                    promoted =
                        Table.PromoteHeaders(
                            firstSheetTable,
                            [PromoteAllScalars = true]
                        )
                in
                    promoted,
            type table
        ),

    // 4) 代表テーブルから列名を取得
    SampleTable = WithSheetTable[SheetTable]{0},
    ColNames = Table.ColumnNames(SampleTable),

    // 5) SheetTable を展開して、全ブック分を縦に結合
    Combined =
        Table.ExpandTableColumn(
            WithSheetTable,
            "SheetTable",
            ColNames,
            ColNames
        )
in
    Combined
Power Query

ここから、重要なところを一つずつかみ砕いていきます。


ステップごとの分解と深掘り

ステップ1:Folder.Files で「ファイル一覧テーブル」を作る

Source = Folder.Files("C:\Data\MonthlyBooks"),
Power Query

Folder.Files は、「このフォルダにあるファイルを全部、1行1ファイルの表にして返してくれる関数」です。
返ってくるテーブルには、こんな列が含まれます。

Name(ファイル名)
Extension(拡張子)
Folder Path(フォルダパス)
Date modified(更新日時)
Size(サイズ)
Content(中身のバイナリ)

この中で、今回特に大事なのは ExtensionContent です。
Extension で「どのファイルを対象にするか」を決め、Content から「中身を読む」ことになります。

ステップ2:Extension で .xlsx だけに絞る

OnlyXlsx =
    Table.SelectRows(
        Source,
        each Text.Lower([Extension]) = ".xlsx"
    ),
Power Query

ここでは、「.xlsx のファイルだけ残す」というフィルタをかけています。

Text.Lower([Extension]) としているのは、拡張子が .XLSX のように大文字で入る環境でも確実にヒットさせるためです。
Text.Lower で小文字にそろえてから、.xlsx と比較する——これは実務テンプレとしてクセにしておくと安全です。

ステップ3:Content から 1枚目シートをテーブル化する

ここが一番“魔法っぽく”見えるところなので、丁寧に分解します。

WithSheetTable =
    Table.AddColumn(
        OnlyXlsx,
        "SheetTable",
        each
            let
                wb =
                    Excel.Workbook(
                        [Content],
                        true,
                        true
                    ),
                firstSheetRow =
                    Table.SelectRows(wb, each [Kind] = "Sheet"){0},
                firstSheetTable = firstSheetRow[Data],
                promoted =
                    Table.PromoteHeaders(
                        firstSheetTable,
                        [PromoteAllScalars = true]
                    )
            in
                promoted,
        type table
    ),
Power Query

Table.AddColumn は、「既存のテーブルに新しい列を追加する」関数です。
ここでは、OnlyXlsx の各行(各ファイル)に対して、「SheetTable という列」を追加しています。

each ... の中身が、「1ファイル分の処理」です。
順番に見ていきます。

Excel.Workbook([Content], true, true)
Content(バイナリ)を Excel として開き、「中にあるシートやテーブルの一覧」をテーブルとして返します。
このテーブルには、Name(シート名)、Kind(Sheet / Table など)、Data(そのシートの中身のテーブル)といった列が入っています。

Table.SelectRows(wb, each [Kind] = "Sheet"){0}
wb の中から「Kind が Sheet の行だけ」を選び、そのうち最初の1行({0})を取り出しています。
つまり、「1枚目のシート」を選んでいるイメージです。

firstSheetRow[Data]
その行の Data 列には、「シートの中身(まだヘッダー昇格前)のテーブル」が入っています。
これを firstSheetTable として受け取っています。

Table.PromoteHeaders(firstSheetTable, [PromoteAllScalars = true])
先頭行をヘッダー(列名)として昇格させています。
これで、「普通の表」として扱いやすい状態になります。

最後に in promoted としているので、SheetTable 列には「ヘッダー昇格済みのテーブル」が入ることになります。
結果として、WithSheetTable は「1行1ファイル+そのファイルのシートのテーブル」という構造になります。

ステップ4:代表テーブルから列名を取得する

SampleTable = WithSheetTable[SheetTable]{0},
ColNames = Table.ColumnNames(SampleTable),
Power Query

ここは「展開の準備」です。

WithSheetTable[SheetTable]{0} は、「SheetTable 列の 0 番目(最初)のテーブル」を取り出しています。
これを SampleTable と呼んでいます。

Table.ColumnNames(SampleTable) で、そのテーブルの列名一覧をリストとして取得します。
これを ColNames としておき、後で展開するときに使います。

なぜこんなことをするかというと、「展開するときに列名を手書きしなくて済むようにするため」です。
列名が変わったときにも、ここを自動で取り直してくれるので、メンテナンス性が上がります。

ステップ5:SheetTable を展開して縦に結合する

Combined =
    Table.ExpandTableColumn(
        WithSheetTable,
        "SheetTable",
        ColNames,
        ColNames
    )
Power Query

Table.ExpandTableColumn は、「テーブル型の列を展開して、親テーブルにくっつける」関数です。

ここでは、WithSheetTable の SheetTable 列(中身はテーブル)を展開し、
ColNames で指定した列を、親テーブルの列として展開しています。

結果として、「各ファイルのシートの行が、全部縦に並んだ1つの大きなテーブル」ができます。
これが、フォルダ内 Excel 一括取込のゴールです。


応用:元ファイル名を列として残す

「どの行がどのファイル由来か」を見える化する

実務では、「この行はどのファイルから来たのか」を知りたいことがよくあります。
その場合は、展開前に Name 列を残しておき、展開後も一緒に持たせておくと便利です。

さっきのテンプレに、ほんの少しだけ手を加えます。

let
    Source = Folder.Files("C:\Data\MonthlyBooks"),

    OnlyXlsx =
        Table.SelectRows(
            Source,
            each Text.Lower([Extension]) = ".xlsx"
        ),

    WithSheetTable =
        Table.AddColumn(
            OnlyXlsx,
            "SheetTable",
            each
                let
                    wb =
                        Excel.Workbook(
                            [Content],
                            true,
                            true
                        ),
                    firstSheetRow =
                        Table.SelectRows(wb, each [Kind] = "Sheet"){0},
                    firstSheetTable = firstSheetRow[Data],
                    promoted =
                        Table.PromoteHeaders(
                            firstSheetTable,
                            [PromoteAllScalars = true]
                        )
                in
                    promoted,
            type table
        ),

    SampleTable = WithSheetTable[SheetTable]{0},
    ColNames = Table.ColumnNames(SampleTable),

    Combined =
        Table.ExpandTableColumn(
            WithSheetTable,
            "SheetTable",
            ColNames,
            ColNames
        ),

    // 元ファイル名を「ファイル名」列として残す
    WithFileName =
        Table.RenameColumns(
            Combined,
            {{"Name", "元ファイル名"}}
        )
in
    WithFileName
Power Query

こうしておけば、最終テーブルの各行に「元ファイル名」が付くので、
「この売上はどの月のブックから来たのか」が一目で分かります。


実務テンプレとしてのまとめ

フォルダ内 Excel 一括取込の型は、次の流れに集約できます。

Folder.Files でファイル一覧テーブルを作る。
Extension で対象の Excel だけに絞る。
ContentExcel.Workbook に渡し、欲しいシートの Data を取り出してヘッダー昇格する。
そのテーブルを列として持たせ、最後に Table.ExpandTableColumn で展開して縦に結合する。

一度この型を体に入れてしまえば、
「月次ブック」「店舗別ブック」「担当者別ブック」など、構造が同じ Excel が並んでいるフォルダは、
ほぼすべて“自動でまとめる”対象になります。

タイトルとURLをコピーしました