【ExcelVBA・マクロ】VBAでPower Query(パワークエリ)を操作する方法|クエリの一覧取得・一括更新を自動化する【コピペOK】

ExcelVBA

はじめに

Power Query(パワークエリ)でデータ取込の仕組みを作ったものの、「更新ボタンを毎回手動で押すのが面倒」「特定のクエリだけを自動で更新したい」と感じたことはありませんか。

この記事では、ExcelVBAからPower Queryを操作する方法を解説します。Workbook.Queriesコレクションでクエリの一覧を取得する方法、特定のクエリだけを更新する方法、全クエリを一括更新して完了を待つ方法、そしてクエリのM言語定義を確認・書き換える方法まで、実務で使えるコードを紹介します。

スポンサーリンク
スポンサーリンク

Power QueryとVBAの関係

Power QueryをVBAから扱う際に登場するオブジェクトは主に2つあります。

  • Workbook.QueriesWorkbookQuery:クエリの名前やM言語の定義(Formula)を扱うオブジェクト。クエリの一覧取得や定義の確認・書き換えに使う
  • Workbook.ConnectionsWorkbookConnection:クエリの実行結果をシートやデータモデルに取り込むための接続オブジェクト。実際の「更新」処理はこちらのRefreshメソッドで行う

つまり、「クエリそのものの定義」と「クエリを実行して結果を更新する処理」は別のオブジェクトが担っている点がポイントです。どちらもExcel 2016以降であれば参照設定なしでそのまま使えます。

登録されているクエリの一覧を取得する

Option Explicit

Sub ListPowerQueries()

    Dim q As WorkbookQuery
    Dim msg As String

    If ThisWorkbook.Queries.Count = 0 Then
        MsgBox "このブックにはPower Queryのクエリがありません。", vbInformation
        Exit Sub
    End If

    For Each q In ThisWorkbook.Queries
        msg = msg & q.Name & vbCrLf
    Next q

    MsgBox "登録されているクエリ:" & vbCrLf & msg, vbInformation

End Sub

ThisWorkbook.Queriesをループするだけで、ブックに登録されている全クエリの名前を取得できます。

特定のクエリだけを更新する

クエリ名から対応する接続を探してRefreshを呼び出します。接続名は「クエリ – クエリ名」のような形式で自動生成されるため、InStrで部分一致検索するのが確実です。

Sub RefreshQueryByName(queryName As String)

    Dim conn As WorkbookConnection
    Dim found As Boolean

    found = False

    For Each conn In ThisWorkbook.Connections
        If InStr(conn.Name, queryName) > 0 Then
            conn.Refresh
            found = True
        End If
    Next conn

    If Not found Then
        MsgBox queryName & " に対応する接続が見つかりませんでした。", vbExclamation
    End If

End Sub

Sub RefreshSalesQuery()
    Call RefreshQueryByName("Sales_Data")
End Sub

RefreshQueryByNameを汎用プロシージャとして用意しておき、更新したいクエリ名を渡すだけで呼び出せるようにしています。

全クエリを一括更新する

すべてのクエリ・テーブル・ピボットテーブルをまとめて更新したい場合はRefreshAllを使います。ただしRefreshAllは既定でバックグラウンド更新(非同期)になるため、更新が終わる前に後続のコードが実行されてしまうことがあります。更新完了を待ってから次の処理に進みたい場合は、Application.CalculateUntilAsyncQueriesDoneを組み合わせます。

Sub RefreshAllQueriesAndWait()

    Application.StatusBar = "クエリを更新しています..."

    ThisWorkbook.RefreshAll
    Application.CalculateUntilAsyncQueriesDone

    Application.StatusBar = False
    MsgBox "全クエリの更新が完了しました。", vbInformation

End Sub

CalculateUntilAsyncQueriesDoneはExcel 2016以降で使えるメソッドで、非同期更新がすべて終わるまで処理を待機させます。これを入れないと「更新中なのにMsgBoxが先に表示される」といった不具合の原因になります。

クエリのM言語定義を確認・書き換える

WorkbookQueryオブジェクトのFormulaプロパティから、クエリの中身(M言語のコード)をテキストとして取得・変更できます。

Sub ShowQueryFormula()
    Dim q As WorkbookQuery
    Set q = ThisWorkbook.Queries("Sales_Data")
    Debug.Print q.Formula
End Sub

たとえば、クエリ内にハードコードされた年度(例:"2025")を書き換えて、年度が変わっても手動修正なしで運用したい場合は以下のようにします。

Sub UpdateQueryYearParameter()

    Dim q As WorkbookQuery
    Dim newFormula As String

    Set q = ThisWorkbook.Queries("Sales_Data")
    newFormula = Replace(q.Formula, "2025", "2026")

    If newFormula <> q.Formula Then
        q.Formula = newFormula
        MsgBox "クエリの定義を更新しました。", vbInformation
    Else
        MsgBox "置換対象の文字列が見つかりませんでした。", vbExclamation
    End If

End Sub

FormulaはM言語のテキストをそのまま返すため、単純な文字列置換で対応できる変更(年度・ファイルパス・シート名など)であればこの方法が手軽です。複雑な構造変更をする場合は、Power Queryエディタ側で編集する方が安全です。

注意点

  • 接続名(「クエリ – ○○」)は言語設定によって表記が異なる場合があります。ハードコードで完全一致させるより、InStrによる部分一致検索の方が安全です
  • Formulaプロパティを直接書き換える方法は、M言語の構文エラーがあってもVBA実行時にはチェックされず、実際にクエリが更新されるタイミングでエラーになります。書き換え後は必ずRefreshQueryByNameなどで動作確認してください
  • データモデル(Power Pivot)に読み込んでいるクエリは、シート上のテーブルではなくConnections経由でのみ更新されます。ワークシートにテーブルとして出力していない場合、ListObjectからは操作できない点に注意してください

まとめ

VBAからWorkbook.QueriesWorkbook.Connectionsを使うことで、Power Queryのクエリ一覧取得・個別更新・一括更新・定義の書き換えまで自動化できます。定期的なデータ取込を伴う集計ブックであれば、更新処理をマクロ化しておくことで、更新忘れや操作ミスを防ぐことができます。

スポンサーリンク
スポンサーリンク
ExcelVBA
シェアする
いがぴをフォローする

コメント

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