Power Queryでフォルダ内のExcelブックを一括取り込みし、1つのテーブルに結合する方法

フォルダ配下の複数の Excel ブックから同一形式のシートを集約し、1つの表として分析に使える形へ整形する手順をご説明いたします。パス、列名、変数名は本記事用に変更しております。


目次

Mコード(「詳細エディター」に貼り付け)

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

    // 2) 拡張子 .xlsx のみ対象(大文字・小文字を吸収)
    OnlyXlsx       = Table.SelectRows(
                        SourceFolder,
                        each Text.Lower([Extension]) = ".xlsx"
                     ),

    // 3) 必要列だけ保持(バイナリ本体と元ファイル名)
    PickColumns    = Table.SelectColumns(OnlyXlsx, {"Content", "Name"}),

    // 4) 各ブックの先頭シートを取り出して Data を得る
    WithSheetTable = Table.AddColumn(
                        PickColumns,
                        "SheetData",
                        each
                            let
                                wb         = Excel.Workbook([Content], true, true),
                                firstSheet = Table.SelectRows(wb, each [Kind] = "Sheet"){0}[Data]
                            in
                                firstSheet,
                        type table
                     ),

    // 5) 取り出し失敗(例:シートが無い)レコードを除外
    NonNullOnly    = Table.SelectRows(WithSheetTable, each [SheetData] <> null),

    // 6) 元ファイル名を分かりやすい列名に変更
    Renamed        = Table.RenameColumns(NonNullOnly, {{"Name", "SourceWorkbook"}}, MissingField.Ignore),

    // 7) 先頭ファイルの列名を使って全テーブルを展開
    ColNames       = Table.ColumnNames(Renamed{0}[SheetData]),
    Expanded       = Table.ExpandTableColumn(Renamed, "SheetData", ColNames, ColNames),

    // 8) 列型を明示(実データの列名に合わせて調整)
    //    例として英字の列名を採用:InvoiceNo, OrderDate, Client, NetSales, Owner
    TypedBase      = Table.TransformColumnTypes(Expanded, {{"SourceWorkbook", type text}}),
    TypedFinal     =
        let
            cols = {"InvoiceNo","OrderDate","Client","NetSales","Owner"}
        in
            if Table.HasColumns(TypedBase, cols) then
                Table.TransformColumnTypes(
                    TypedBase,
                    {
                        {"InvoiceNo", Int64.Type},
                        {"OrderDate", type date},
                        {"Client", type text},
                        {"NetSales", type number},
                        {"Owner", type text}
                    }
                )
            else
                TypedBase
in
    TypedFinal

使い方の要点

  • 先頭シートではなく特定シート名を読みたい場合は、firstSheet の代わりに
    Table.SelectRows(wb, each [Kind] = "Sheet" and [Name] = "Sheet1"){0}[Data]
    のように Name を条件に加えてください。
  • 列名がファイルごとに微妙に異なる場合は、展開前に Table.PromoteHeaders や列名の置換を挟み、列名を統一してから結合すると安定します。
  • 数値や日付の並べ替え・集計を行う前に、Table.TransformColumnTypes で型を確定してください。

よくあるつまずきと対処

  • フォルダに異なる形式(.xlsm など)が混在する場合は、拡張子の条件を追加してください。
  • シートが非表示や空のブックがあると …{0} でエラーになることがあります。上記コードでは NonNullOnly で除外していますが、必要に応じて try … otherwise null を追加するとより堅牢になります。
  • 列名の自動取得は先頭ファイルに依存します。列構成が不揃いな場合は、明示リストで展開するか、欠損列を Table.AddColumn で補ってください。

まとめ

  • Folder.Files で一括取得し、Excel.Workbook からシートの Data を抽出して結合します。
  • 列名の統一と型指定を行うことで、後段の集計・可視化が安定します。
  • 運用環境に合わせてシート名条件や例外処理を追加すると保守性が高まります。
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次