はじめに
Power Query(パワークエリ)でデータ取込の仕組みを作ったものの、「更新ボタンを毎回手動で押すのが面倒」「特定のクエリだけを自動で更新したい」と感じたことはありませんか。
この記事では、ExcelVBAからPower Queryを操作する方法を解説します。Workbook.Queriesコレクションでクエリの一覧を取得する方法、特定のクエリだけを更新する方法、全クエリを一括更新して完了を待つ方法、そしてクエリのM言語定義を確認・書き換える方法まで、実務で使えるコードを紹介します。
Power QueryとVBAの関係
Power QueryをVBAから扱う際に登場するオブジェクトは主に2つあります。
Workbook.Queries(WorkbookQuery):クエリの名前やM言語の定義(Formula)を扱うオブジェクト。クエリの一覧取得や定義の確認・書き換えに使うWorkbook.Connections(WorkbookConnection):クエリの実行結果をシートやデータモデルに取り込むための接続オブジェクト。実際の「更新」処理はこちらの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.QueriesとWorkbook.Connectionsを使うことで、Power Queryのクエリ一覧取得・個別更新・一括更新・定義の書き換えまで自動化できます。定期的なデータ取込を伴う集計ブックであれば、更新処理をマクロ化しておくことで、更新忘れや操作ミスを防ぐことができます。


コメント