Power Query 実務テンプレ | データ取込・更新系:Excel特定シート名指定取込

Excel
スポンサーリンク

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

今回のテーマは「Excelブックの中から、特定のシート名だけを Power Query で安定して取り込む実務テンプレ」です。
たとえば「毎月『集計』シートだけを読みたい」「別ブックの『SheetSales』だけをデータソースにしたい」といった場面を想定します。

キーワードは Excel.Workbook と「Name(または Item)+ Kind でシートを特定する」という考え方です。ここを押さえれば、あとはパターン化できます。


基本の仕組み:Excel.Workbook で「カタログ化」してから選ぶ

ブック全体を一覧にしてから、目的のシートを1行だけ抜き出す

Power Query は、Excel ブックを読むときに Excel.Workbook という関数を使います。

let
    Source = Excel.Workbook(
        File.Contents("C:\Data\SalesData.xlsx"),
        true,
        true
    )
in
    Source

Excel.Workbook は、そのブックに含まれる「シート」「テーブル」「名前付き範囲」などを、1行ずつ並べた“カタログ表”を返します。 適材適所

この表には、少なくとも次のような列があります。

Name(または Item)…シート名やテーブル名
Kind …「Sheet」「Table」などの種類
Data …そのシートやテーブルの中身(テーブル型)

特定シート名を指定する、というのは「このカタログ表の中から、Name=“欲しいシート名” かつ Kind=“Sheet” の行を1つだけ選び、その行の Data を取り出す」という操作に言い換えられます。


単一ブックから「特定シート名」だけを取るテンプレ

一番ストレートな M コード

たとえば、C:\Data\SalesData.xlsx の中の「SheetSales」というシートだけを取り込みたいとします。

その場合の M コードは、次のような形になります。

let
    // 1) ブック全体を読み込む
    XlFile = File.Contents("C:\Data\SalesData.xlsx"),
    Source = Excel.Workbook(XlFile, true, true),

    // 2) Name と Kind で「SheetSales」シートを特定
    SheetSalesRow = Source{[Name = "SheetSales", Kind = "Sheet"]},

    // 3) その行の Data 列(中身のテーブル)を取り出す
    SheetSalesTable = SheetSalesRow[Data],

    // 4) 必要なら先頭行をヘッダーに昇格
    Promoted = Table.PromoteHeaders(
        SheetSalesTable,
        [PromoteAllScalars = true]
    )
in
    Promoted

ここで一番大事なのは、この1行です。

SheetSalesRow = Source{[Name = "SheetSales", Kind = "Sheet"]},

これは「Source テーブルの中から、Name が ‘SheetSales’ で Kind が ‘Sheet’ の行を1つだけ取り出す」という意味です。
{…} の中に「行を特定する条件レコード」を書くことで、その行を直接インデックス指定できます。

その行の Data 列を取り出したものが、シートの中身そのもの(テーブル)です。


フォルダ内の複数ブックから「同じシート名」だけをまとめて取る

実務でよくあるシナリオ

現場でよくあるのは、「毎月のブックがフォルダにたまっていて、その中の『集計』シートだけを全部縦に結合したい」というパターンです。
どのブックにも「集計」というシートがあり、列構成も同じ、という前提です。

フォルダ+特定シート名の実務テンプレ

次のコードは、C:\Data\MonthlyBooks フォルダ内のすべての .xlsx について、「SheetSales」シートだけを読み込み、最後に全部まとめて1つのテーブルにするテンプレです。

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

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

    // 3) 各ファイルから「SheetSales」シートを読み込むカスタム列を追加
    AddedTables = Table.AddColumn(
        Filtered,
        "SheetSales",
        each
            let
                XlFile = [Content],
                WB = Excel.Workbook(XlFile, true, true),
                TargetRow = WB{[Name = "SheetSales", Kind = "Sheet"]},
                TargetTable = TargetRow[Data],
                Promoted = Table.PromoteHeaders(
                    TargetTable,
                    [PromoteAllScalars = true]
                )
            in
                Promoted
    ),

    // 4) そのカスタム列を展開して、全ブック分を縦に結合
    SampleTable = AddedTables[SheetSales]{0},
    ColumnNames = Table.ColumnNames(SampleTable),
    Expanded = Table.ExpandTableColumn(
        AddedTables,
        "SheetSales",
        ColumnNames,
        ColumnNames
    )
in
    Expanded

やっていることを言葉で整理すると、こうなります。

フォルダからファイル一覧を取る。
各行(各ファイル)について、「Excel.Workbook → Name/Kind でシートを特定 → Data を取り出す → ヘッダー昇格」という処理を実行し、その結果を SheetSales 列に入れる。
最後に SheetSales 列を展開して、全ブック分を縦に結合する。

ポイントは、「特定シート名を指定するロジックを、Table.AddColumn の中に閉じ込めている」ことです。これにより、フォルダにファイルを追加するだけで、同じ処理が自動で全ファイルに適用されます。


重要ポイントの深掘り

Name / Item と Kind をセットで使う理由

Excel.Workbook の結果には、シートだけでなくテーブルや名前付き範囲も含まれます。
同じ Name を持つ別種のオブジェクトが存在する可能性もあるため、「Name だけ」で行を特定するのは少し危険です。

そこで、実務テンプレとしては

Name(または Item)=「欲しいシート名」
Kind = “Sheet”

という2条件で行を特定するのが定番パターンになります。
これなら、「同名のテーブル」などに引っかかるリスクを避けられます。

シート名をセルやパラメータで可変にする発展形

もう一歩進めると、「シート名を固定文字列ではなく、セルに入力した値から取る」ということもできます。

たとえば、別クエリで「シート名」を1セルだけ持つテーブルを作り、それをドリルダウンしてテキスト値として取得しておきます(SheetNameParam など)。
あとは、先ほどの行特定部分をこう書き換えるだけです。

TargetRow = WB{[Name = SheetNameParam, Kind = "Sheet"]},

こうしておけば、「シート名が変わったらセルの値だけ変える」という運用にできます。
M コードを直接触る頻度を減らしたい現場では、かなり有効なパターンです。


実務での使い分けイメージ

特定シート名指定は、「シート名がきちんとルール化されている」現場で特に強いです。
たとえば、どのブックにも必ず「集計」「明細」「SheetSales」といった決まった名前のシートがあり、そこだけをデータソースにしたい場合です。

一方で、「シート名が人によってバラバラ」「でも1枚目にだけデータがある」という現場では、前に話した「1枚目固定取込」の方が壊れにくくなります。
つまり、「シート名が安定しているなら名前指定」「シート名が揺れるなら順番指定」という切り分けで考えると、設計がスッキリします。

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