Excel単独で「真のWebView2」を完全制御する
さぁ、ここが本当の目的。
Excelだけで、しかもPowershellのような外部source依存もなしで、真WebView2をUserformに。
ついに辿り着きました。これが本プロジェクトの真の目的であり、到達点です。
外部プロセス(PowerShellなど)に頼らず、Excel VBAのメモリ空間上だけで WebView2 を直接起動・制御します。
v3.0.0でネイティブ実装済み
以前このページは「理論上は可能だが本キット未実装、詳しくは他プロジェクトへ」という紹介記事でした。v3.0.0で、この技法を本キット自身に CDPCoreViaWebView2.cls / WebView2Thunks.bas(v3.0.0時点ではCDPWebView2Thunks.bas、v3.1.0で改名) / WebView2Form.frm として本実装しています。接続後は、Pipe / WebSocket と同じ CDPContext / CDPElement の API でそのまま操作できます。実際の使い方はこのページの後半を参照してください。
ふはははははは!!!Excel VBAのユーザーフォーム上でWebView2を動作させて、イベントを検知することに成功したぞ pic.twitter.com/lwDDCylQYq
— たーぼー(インコ) (@fenblen_puyo) March 14, 2026
一見するとLv.1(Edge埋め込み)と似ていますが、タスクマネージャーを見ればその違いは一目瞭然です。

▲ Excel.exe の配下に直接 WebView2 プロセスが生成されています
禁断の魔導:VBAによるCOM直接制御の仕組み
なぜ、これまでこれが不可能だと思われていたのか。それは WebView2 が IUnknown ベース という、VBAにとっては非常に「扱いづらい」設計になっているからです。
INFO
通常、VBAで Object として扱えるものは IDispatch という「親切な案内板」を持っています。しかし、WebView2にはそれがありません。
1. DispCallFunc による関数の強行突破
「オブジェクト.メソッド」という通常の呼び出しができないため、Windows APIの DispCallFunc を使用します。
これは、メモリ上の「関数の住所(vtableのインデックス)」を直接指定して実行する、いわば VBA界の狙撃術です。
2. vtable 偽造:自作のCOMオブジェクトを作る
WebView2は、処理が終わると「終わったよ!」とコールバック(通知)を返してきます。この通知を受け取るには「WebView2が理解できる形式のオブジェクト」である必要があります。
VBAの AddressOf で取得した関数のポインタを構造体に詰め込み、メモリ上に「COMオブジェクトのフリをしたデータ」を構築(vtable偽造)することで、WebView2からの通信を直接受け止めます。
処理のリレー(非同期通信)
VBAが制御を投げる → WebView2が処理 → 偽造オブジェクト経由でVBAのハンドラを叩く → VBAが次の指示を出す……という、極めて高度な連携によって動作しています。
実装のエッセンス
vtable構築の核心部分
' COM vtable 偽造オブジェクトの定義
Private Type VtblObj
pVTable As LongPtr
End Type
' 4つのエントリ(QI, AddRef, Release, Invoke)を持つvtable
Private Type VtblData4
fn(0 To 3) As LongPtr
End Type
' 実行時にVBA標準モジュールのメソッドを AddressOf で登録
Private Sub BuildVtables()
Dim envFn() As LongPtr
WV2_FillFunctionPointers envFn
m_EnvHandlerVT.fn(0) = envFn(0) ' QueryInterface
m_EnvHandlerVT.fn(1) = envFn(1) ' AddRef
m_EnvHandlerVT.fn(2) = envFn(2) ' Release
m_EnvHandlerVT.fn(3) = envFn(3) ' Invoke (本命のコールバック)
' これがWebView2側に渡す「偽オブジェクト」のポインタになる
m_EnvHandlerThis.pVTable = VarPtr(m_EnvHandlerVT.fn(0))
End Sub正直に申し上げて、これは VBAの限界を突破した「ハック」 に近いです。
しかし、この手法をマスターすれば、TLBや外部DLLに一切頼ることなく、最新のブラウザエンジンをExcelのUserFormに完全に支配下に置くことができます。
移植元
この機械語サンク・vtable呼び出し・SAFEARRAYメモリプリミティブの心臓部は、WebView2-For-Excel-VBA(Wv2Thunks.bas)のロジックを、バイト列やオフセット値を一切変更せずそのまま移植したものです。本キット向けに追加したのは、CDP用のハンドラ種別(CallDevToolsProtocolMethodForSessionAsync / DevToolsProtocolEventReceivedEventHandler のIID登録含む)と、v3.1.0で追加した拡張機能対応(EnvironmentOptionsエミュレーション)用のget_/put_ハンドラ群です。
本キットでの使い方
WebView2Form.frm の StartCDPModeWebView2 を呼ぶだけで、初期化からCDP接続まで完了します。
Sub WebView2OnExcelUserForm()
'1. UserForm側のWebView2の初期化を済ませる
With WebView2Form
.StartCDPModeWebView2
'2. あとはいつも通りの CDPContext / CDPElement 操作
.ThisCDPContext.navigate "https://github.com/Eschamali/StarterWebScrapingKit"
'3. フォームを表示
.show
End With
End Sub同梱デモ: Demo_WebView2.WebView2OnExcelUserForm
内部では CDPCoreViaWebView2.OpenWebView2AndConnectCDP がWebView2のEnvironment/Controller/ICoreWebView2を生成し、ReattachOptions.Set_WebView2Mode と CDPBrowser.reattach を通じて、Pipe版・Port版とまったく同じCDPスタックに接続します。つまり、いったん埋め込んでしまえば、getElementByQuery や jsEval など、これまでのガイドで説明してきた操作がそのまま使えます。
自前のUserFormに組み込む場合のAPI詳細(OpenWebView2AndConnectCDPの引数、イベント購読、リサイズ等)は WebView2モードでできること にまとめています。
リセットに注意(静止ブレークポイント自体は問題なし)
全てのCOMコールバックは機械語サンクを経由します。同期メソッドの呼び出し中そのものでブレークする、あるいは静止ブレイク中にCDPイベント/コマンド完了が届くと、クラッシュの可能性があります。そのいずれの状態でも、VBEでリセット操作をすると、ほぼ確実にExcelがクラッシュします。普通のVBAコード行で静止しているだけなら問題ありません。デバッグ時、リセットする前にはイミディエイトウィンドウからUnsubscribeAllCdpEventsで購読解除しておいてください(ただし、これは内部トラッキング用の自動購読分も解除するため、デバッグ後は再接続が必要です)。詳細な条件分けは設計思想についてを参照してください。
WARNING
より低レベルな仕組みの探求の覚悟があるなら、移植元のリポジトリも覗いてみてください:
WebView2-For-Excel-VBA (GitHub)
最後に、このロマンな技術テクニックを公開、教えてくれた「たーぼー(インコ)」さんに感謝します。
次へ
- WebView2モードでできること — API詳細
- WebView2モードの設計思想について
- WebView2、登場秘話 — この実装が生まれた経緯
- 総括:3つの手法の比較
- PowerShell 経由
- はじめに

