Power Query 実務テンプレ | データ取込・更新系:ファイル名を列として追加

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

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

今回のテーマは「Power Query で取り込んだデータに、“元ファイル名”を列として追加する実務テンプレ」です。
フォルダ内の複数 CSV / Excel を一括取込するときに、

  • この行はどのファイルから来たのか
  • どの月のデータなのか(ファイル名に年月が入っている)

を後から集計やチェックに使えるようにしておく——これが狙いです。
一度型を作っておけば、どの案件でもほぼコピペで使い回せます。


なぜ「ファイル名を列にする」と強いのか

実務でよくある困りごと

フォルダ一括取込をすると、最終的には「全部まとめて1つのテーブル」になります。
便利な反面、こんなことが起きがちです。

  • どの行がどのファイル由来か分からない
  • 一部のファイルだけおかしいのに、どれか特定できない
  • 月別・店舗別などを「ファイル名から判定したい」のに、情報が消えている

ここで効いてくるのが「ファイル名を列として持たせておく」という一手です。
ファイル名に「年月」「店舗名」「担当者名」などが含まれていれば、それをそのまま分析軸にできます。

追加するタイミングの基本

ファイル名を列に追加するタイミングは、

  • フォルダからファイル一覧を取った直後
  • まだ「ファイルごとに1行」の状態のとき

が一番扱いやすいです。
その列は、後でテーブルを展開・結合しても一緒に増えていくので、最終的な明細行にもちゃんと残ります。


例題1:フォルダ内 CSV 一括取込+ファイル名列追加

全体の流れのイメージ

想定する状況はこうです。

  • C:\Data\DailyCsv フォルダに、毎日 sales_2024-10-01.csv のようなファイルが増えていく
  • すべて同じ列構成
  • すべてを一括取込して、さらに「元ファイル名」も列として持たせたい

このときの M コードのテンプレを、最初から最後まで通しで見てみます。

実務テンプレ M コード(CSV 版)

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

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

    // 3) 元ファイル名を列として追加
    WithFileName =
        Table.AddColumn(
            OnlyCsv,
            "元ファイル名",
            each [Name],
            type text
        ),

    // 4) 必要ならフォルダパスも列として追加(任意)
    WithPath =
        Table.AddColumn(
            WithFileName,
            "元フォルダパス",
            each [Folder Path],
            type text
        ),

    // 5) Content 列を CSV としてテーブル化
    AddedCsvTable =
        Table.AddColumn(
            WithPath,
            "CsvTable",
            each
                Csv.Document(
                    [Content],
                    [
                        Delimiter = ",",
                        Encoding = 65001,
                        QuoteStyle = QuoteStyle.Csv
                    ]
                ),
            type table
        ),

    // 6) ヘッダー昇格
    WithHeader =
        Table.TransformColumns(
            AddedCsvTable,
            {
                "CsvTable",
                each
                    Table.PromoteHeaders(
                        _,
                        [PromoteAllScalars = true]
                    ),
                type table
            }
        ),

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

    // 8) CsvTable を展開して、全ファイル分を縦に結合
    Combined =
        Table.ExpandTableColumn(
            WithHeader,
            "CsvTable",
            ColNames,
            ColNames
        )
in
    Combined
Power Query

ここでのポイントは「3) で追加した『元ファイル名』列が、8) の展開後もちゃんと残る」ということです。
最終的な Combined テーブルには、明細列(例:日付・金額など)に加えて、「元ファイル名」「元フォルダパス」が並びます。

これにより、

  • ピボットで「行:元ファイル名、値:件数」で、どのファイルに何行入っているか確認
  • 「元ファイル名」から年月部分だけ抜き出して「対象年月」列を作る

といった分析が簡単にできます。


例題2:フォルダ内 Excel 一括取込+ファイル名列追加

想定する状況

今度は、フォルダ内の複数 Excel ブックから、1枚目のシートだけを読み込んで結合するケースを考えます。
ここでも「元ファイル名」を列として持たせておくと、店舗別・月別などの分析に使えます。

実務テンプレ M コード(Excel 版)

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

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

    // 3) 元ファイル名を列として追加
    WithFileName =
        Table.AddColumn(
            OnlyXlsx,
            "元ファイル名",
            each [Name],
            type text
        ),

    // 4) 各ブックの1枚目シートを読み込む
    WithSheetTable =
        Table.AddColumn(
            WithFileName,
            "SheetData",
            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
        ),

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

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

この Combined テーブルにも、「元ファイル名」列が残ります。
たとえば、ファイル名が 売上_東京_2024-10.xlsx のような形式なら、そこから「店舗名」「年月」を抜き出して列を増やすこともできます。


重要ポイントの深掘り

Table.AddColumn で「既存列をそのままコピーする」感覚

ファイル名列を追加するときに使っているのが Table.AddColumn です。

WithFileName =
    Table.AddColumn(
        OnlyCsv,
        "元ファイル名",
        each [Name],
        type text
    )
Power Query

ここでやっていることは、「OnlyCsv テーブルに『元ファイル名』という新しい列を追加し、その値として各行の Name 列の値をそのまま入れる」というだけです。
each [Name] は「この行の Name 列」という意味です。

この「既存列をコピーして新しい列にする」パターンは、ファイル名だけでなく、

  • フォルダパス([Folder Path])
  • 更新日([Date modified])

などにもそのまま使えます。

ファイル名から「年月」などを切り出す応用

実務では、ファイル名に意味を持たせていることが多いです。

  • sales_2024-10-01.csv
  • 売上_東京_2024-10.xlsx

こういう場合、「元ファイル名」列をそのまま使うだけでなく、そこから一部を切り出して新しい列を作ると、さらに便利になります。

たとえば、sales_2024-10-01.csv から「2024-10」を抜き出す例です。

WithMonth =
    Table.AddColumn(
        WithFileName,
        "対象年月",
        each Text.Middle([元ファイル名], 7, 7),
        type text
    )
Power Query

Text.Middle(テキスト, 開始位置, 文字数) は、「指定位置から指定文字数だけ切り出す」関数です。
開始位置は 1 文字目が 0 ではなく 0 から数える点に注意してください(M 言語は 0 始まり)。

こうしておけば、最終テーブルで「行:対象年月、値:金額」のような集計が簡単にできます。


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

「ファイル名を列として追加」は、フォルダ一括取込とセットで使うと威力を発揮します。

  • フォルダからファイル一覧を取る(Folder.Files)
  • その段階で Name や Folder Path を新しい列としてコピーしておく
  • その後、Content を展開しても、その列は明細行まで引き継がれる

という“型”さえ覚えておけば、どんな案件でもほぼ同じ書き方で使えます。

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