Skip to content

WebView2モードでできること ​

Pipe・WebSocket が「外部のブラウザプロセス」を相手にするのに対し、WebView2 モードは Excel自身のUserFormに埋め込んだブラウザを制御します。デバッグポート--remote-debugging-portも匿名パイプ--remote-debugging-pipeも使いません。

  • Excel の UserForm に本物の WebView2 を埋め込み、リッチな画面(React / Vue / SPA など)を表示しつつ、同じタブを CDP で操作したい場合
  • 社内ツールとして、1枚の xlsm だけで「ブラウザ埋め込みUI」を配布したい場合

いわゆる、IE時代のWebBrowserコントロールを、Edge時代によみがえらせることが可能になります🥳

詳しい経緯・実装の考え方は 設計思想について を参照してください。

基本的な接続方法 ​

いちばん簡単なのは、同梱の WebView2Form を使う方法です。

vb
'***************************************************************************************************
'                                ■■■ Hello World ■■■
'***************************************************************************************************
'* 機能  :WebView2を起動します。基本的な呼び出しフローです
'---------------------------------------------------------------------------------------------------
'* 注意事項:・`ICoreWebView2Settings`等の一部設定は、ページ遷移前のみ有効です
'            ・`ICoreWebView2EnvironmentOptions`の設定は、WebView2プロセス起動前のみ有効です
'***************************************************************************************************
Sub WebView2OnExcelUserForm()
    With WebView2Form
        '1. 起動前設定を施す(任意)
        .ThisWebView2.EnvironmentOptions.Set_AllowSingleSignOnUsingOSPrimaryAccount = False  'シングルサインオンの切り替え

        '2. WebView2プロセスを起動
        .StartCDPModeWebView2

        '3. 遷移前の事前設定を施す(任意)
        .ThisWebView2.DevToolsEnabled = False       'DevToolsウィンドウ起動禁止
        .ThisWebView2.ContextMenuEnabled = False    '右クリック禁止
        .ThisWebView2.StatusBarEnabled = False      '左下に出るステータステキストを表示しない

        '3. CDPとして、ページ遷移
        'シングルサインオンを無効:Microsoftアカウントの紹介
        'シングルサインオンを有効:あなたのPCでログイン中のMicrosoftアカウント設定ページに自動遷移
        .ThisCDPContext.navigate "https://account.microsoft.com/"

        '4. フォームを表示
        '※UserFormを閉じるまで、ブロッキングされます
        .show
    End With
End Sub

同梱デモ: Demo_WebView2.WebView2OnExcelUserForm

内部では、WebView2Form.StartCDPModeWebView2 が CDPCoreViaWebView2.OpenWebView2AndConnectCDP を呼んでWebView2のEnvironment/Controller/ICoreWebView2を生成し、ReattachOptions.Set_WebView2Mode と CDPBrowser.reattach を通じて、Pipe版・Port版とまったく同じCDPスタックに接続します。埋め込んでしまえば、getElementByQuery や jsEval など、これまでのガイドで説明してきた操作がそのまま使えます。

このデモには、WebView2モードならではの基本操作が3つ詰め込まれています。

初期化に失敗したとき

WebView2Loader.dll が見つからない、Environment / Controller の生成に失敗した、などの場合は、StartCDPModeWebView2 は VBA エラーで停止します(False を返すのではありません)。エラーで止めたくない場合は、呼び出し側で On Error を使ってください。

設定できるタイミングは2種類

  • 起動前(StartCDPModeWebView2より前):EnvironmentOptions経由の設定(例: Set_AllowSingleSignOnUsingOSPrimaryAccount)。Environment生成時にしか読まれないため、あとから変更しても反映されません
  • 遷移前(StartCDPModeWebView2のあと・navigateより前):ICoreWebView2Settings系のプロパティ(例: DevToolsEnabled / ContextMenuEnabled)。ページ単位の設定なので、次のページ遷移までに済ませておく必要があります

Set_AllowSingleSignOnUsingOSPrimaryAccount の値によって、同じhttps://account.microsoft.com/への遷移結果が変わります。False(シングルサインオン無効)ならMicrosoftアカウントの紹介ページが、True(有効)ならWindowsに現在サインイン中のMicrosoftアカウントの設定ページへ自動的に遷移します。実行前後で切り替えて挙動の違いを確かめてみてください。

ThisWebView2 / ThisCDPContext は、UserForm への埋め込みやreattachなど、以降のページ・デモで繰り返し出てくる基本の呼び出し方です。フォーム経由でWebView2固有の設定(ThisWebView2)とCDP操作(ThisCDPContext)の両方に、同じWithブロックからアクセスできます。

ExcelでもAccessでも同じコードで動きます

Accessのフォームは、デザイン時にFrameコントロールを静的に配置する方式に対応していません。そのため、同梱のWebView2Formは、フォーム起動時にWebView2の貼り付け先となるFrameを動的に生成しています(Me.Controls.Add "Forms.Frame.1", ...)。また、貼り付け先を省略した場合のウィンドウハンドルも、Excel(Application.Hwnd)かAccess(Application.hWndAccessApp)かを自動で判別します。

自前のUserFormに組み込む場合 ​

CDPCoreViaWebView2 を直接使えば、自作のUserFormにも組み込めます。

vb
Public Sub OpenWebView2AndConnectCDP(caps As BrowserCapabilities, Optional AttachHwnd As LongPtr)
引数意味
caps起動時のオプションをまとめた BrowserCapabilities。WebView2 のユーザーデータフォルダ名は Set_UserDataDirName で指定します。ドライブ付きの絶対パス(例: C:\Data\MyProfile)を渡すと、そのパスがユーザーデータの保存先になります
AttachHwndWebView2 を貼り付けるウィンドウハンドル。省略時は Excel/Access 自身のハンドル(Application.Hwnd/hWndAccessApp)を使用

戻り値はありません。WebView2 自体が無いなど、初期化に失敗した場合は VBA エラーで停止します。

vb
' Frame自体はhWndを公開していないため、`[_GethWnd]`(MSFormsの内部プロパティ)で取得します
BrowserCapabilities.Set_UserDataDirName = "MyUser"

Dim wv2 As CDPCoreViaWebView2
Set wv2 = New CDPCoreViaWebView2
wv2.OpenWebView2AndConnectCDP BrowserCapabilities, Me.WebView2Frame.[_GethWnd]

' WebView2 を制御経路として指定して、CDPBrowser として受け取る
ReattachOptions.Set_WebView2Mode(wv2) = "MyUser"

Dim b As New CDPBrowser
b.reattach ReattachOptions

Dim t As CDPContext
Set t = b.getTab(setMain:=True)
t.navigate "https://example.com"

注意

  • 既存の接続がある場合は、OpenWebView2AndConnectCDP の再呼び出しで切断・再接続されます
  • CDPBrowser.newTab(Target.createTarget)自体はWebView2モードでも使えますが、WebView2は1インスタンス=1ページのため、新規タブはUserForm内には埋め込まれず独立した新規ウィンドウとして開きます。タブ(ウィンドウ)をまたいだCDPコマンドのやり取りはCallDevToolsProtocolMethodForSessionが担うため、複数のCDPContextを並行操作すること自体は可能です(詳細は設計思想について)

表示・イベント購読 ​

メンバー役割
Resize(Width, Height, Optional Top, Optional Left)WebView2の表示サイズ・位置を変更
Visible(Let)表示/非表示の切り替え
DevToolsEnabled(Let)右クリックの「検証」等、開発者ツールの有効/無効
ContextMenuEnabled(Let)右クリックメニューの有効/無効
SubscribeCdpEvent(EventName) As Boolean指定したCDPイベント名を個別に購読開始
UnsubscribeCdpEvent(EventName) As Boolean指定したCDPイベント名の購読を解除
UnsubscribeAllCdpEvents() As Long購読中の全イベントを一括解除(解除件数を返す)
SubscribeCdpEventCount(Get)購読中のイベント数
isAvailability(Get)WebView2(ICoreWebView2)が生きているか
vb
' Page.loadEventFired を購読してから遷移する例
wv2.SubscribeCdpEvent "Page.loadEventFired"
t.navigate "https://example.com"
' ... TakeEvents ループ等で受信 ...
wv2.UnsubscribeAllCdpEvents

WebSocket/Pipeとの違い

Pipe / WebSocket は「ドメインをenableすれば、そのドメインの全イベントが自動で流れてくる」モデルですが、WebView2はGetDevToolsProtocolEventReceiverの仕様上、イベント名ごとの個別購読が必要です。一括購読の概念はWebView2側に無いため未対応です(一括解除のみUnsubscribeAllCdpEventsとして提供)。Page.enableだけしてもPage.javascriptDialogOpening等は一切届かず、後続の受信待ちループが無限待機になるので注意してください。

v3.2.0での変更:接続時に必須イベントを自動購読

接続成功時、Target.detachedFromTarget等のタブ生存確認、Runtime.executionContext*、Page.frameStartedLoading/domContentEventFired/loadEventFired(WaitEventsによる読み込み待機に必要)を、ライブラリが内部で自動購読するようになりました。Page.javascriptDialogOpening等、この一覧に無いイベントは、これまで通りSubscribeCdpEventで自分で購読してください。UnsubscribeAllCdpEventsを呼ぶと、この自動購読分も含めて全て解除される点に注意してください(後述)。

同梱デモ(v3.1.1〜): Demo_WebView2.RunTestAlertDemo — Demo_CDP.TestAlertのWebView2移植版で、alert / 空alert / promptの3種類のJavaScriptダイアログを実際に発生させ、SubscribeCdpEvent "Page.javascriptDialogOpening"で捕まえて自動応答する一連の流れを、SubscribeCdpEventを呼ぶ場合と呼ばない場合を比較しながら確認できます。

デバッグ中のクラッシュに注意

  • 安全: .navigate等の同期メソッドが完了し、普通のVBAコード行でブレーク/ステップ実行が静止している状態。この状態のままコールバックを後で受け取っても、通常はクラッシュしません
  • 危険: 同期メソッドの呼び出し中そのものでブレークする、または静止ブレイク中に購読中のCDPイベントや保留中のコマンド完了通知が実際に届くと、機械語サンク経由でVBAへ再入しようとしてクラッシュする可能性があります
  • 最も危険: 上記いずれの状態でも、VBEでリセット処理を行うのはほぼ確実にクラッシュします

どうしてもリセットが必要な場合は、まず安全な静止状態まで処理を進め、イミディエイトウィンドウからUnsubscribeAllCdpEventsを実行して購読を解除してから行ってください。ただし、これは前述の自動購読分(WaitEvents用のイベント等)も道連れで解除するため、デバッグ後は再接続するか、必要なイベントを再購読してください。

拡張機能のインストール(v3.1.0〜) ​

CDPのExtensionsドメイン(Extensions.loadUnpacked等)は、WebView2経路だけMethod not availableで弾かれます。そのため、拡張機能まわりだけはCDPを介さない専用APIを使います。

実際に拡張機能をインストールし、UserForm内のWebView2上で動作している様子

▲ AddBrowserExtension でインストールした拡張機能(画像は「Shadowban Scanner」)が、UserForm に埋め込んだ WebView2 上で実際にポップアップを開いて動作している様子

vb
Public Function AddBrowserExtension(extensionFolderPath As String) As String   ' 戻り値: インストールした拡張機能のID(失敗時は空文字)
Public Function GetBrowserExtensionIds() As Collection                         ' 各要素はDictionary(キー:"ID"/"Name"/"IsEnabled")
Public Function RemoveBrowserExtension(extensionId As String) As Boolean
vb
With WebView2Form
    '1. 接続前に、拡張機能を有効化しておく(★必須)
    .ThisWebView2.EnvironmentOptions.Set_AreBrowserExtensionsEnabled = True

    '2. WebView2を起動
    .StartCDPModeWebView2
    .show vbModeless

    '3. インストール
    Dim InstallID As String
    InstallID = .ThisWebView2.AddBrowserExtension("C:\path\to\unpacked-extension")
    If LenB(InstallID) = 0 Then MsgBox "拡張機能のインストールに失敗しました": Exit Sub

    '4. 一覧確認
    Dim ext As Variant
    For Each ext In .ThisWebView2.GetBrowserExtensionIds
        Debug.Print ext("ID"), ext("Name"), ext("IsEnabled")
    Next

    '5. アンインストール
    .ThisWebView2.RemoveBrowserExtension InstallID
End With

同梱デモ: Demo_WebView2.UseExtensionsViaWebView2API

必ず接続前に有効化する

AreBrowserExtensionsEnabled は Environment 生成時にしか読まれない設定です。OpenWebView2AndConnectCDP(StartCDPModeWebView2)を呼んだあとに Set_AreBrowserExtensionsEnabled = True にしても反映されません。次節のEnvironmentOptionsと合わせて、接続前に設定してください。未設定のままインストールを試みるとERROR_NOT_SUPPORTEDで失敗します。

起動前オプションの設定(EnvironmentOptions、v3.1.0〜) ​

ICoreWebView2EnvironmentOptions(WebView2Loaderがネイティブに提供するはずのオプション)を、VBA側でエミュレーションしたクラスです。CDPCoreViaWebView2.EnvironmentOptions から取得し、ConnectCDPを呼ぶ前にチェーン的に設定します。

vb
Public Property Get EnvironmentOptions() As WebView2EnvOptions
プロパティ(すべてLet)意味
Set_AdditionalBrowserArgumentsブラウザプロセス起動時の追加コマンドライン引数
Set_LanguageUI言語
Set_TargetCompatibleBrowserVersion対象ブラウザバージョン(既定値あり。空文字にすると起動失敗)
Set_AllowSingleSignOnUsingOSPrimaryAccountWindowsサインイン中のアカウントでのシングルサインオン可否
Set_ExclusiveUserDataFolderAccessユーザーデータフォルダの排他アクセス
Set_IsCustomCrashReportingEnabledカスタムクラッシュレポートの有効化
Set_EnableTrackingPreventionトラッキング防止の有効化
Set_AreBrowserExtensionsEnabled拡張機能の使用可否(既定False)
Set_ChannelSearchKind探索するEdgeチャンネルの優先順位(WV2ChannelSearchKind)
Set_ReleaseChannels探索対象チャンネルのビットマスク(WV2ReleaseChannels)
Set_ScrollBarStyleスクロールバーの見た目(WV2ScrollBarStyle)
vb
With WebView2Form.ThisWebView2.EnvironmentOptions
    .Set_AllowSingleSignOnUsingOSPrimaryAccount = False
    .Set_AreBrowserExtensionsEnabled = True
End With

同梱デモ: Demo_WebView2.RunEnvironmentOptionsDemo

その他のインターフェースのプロパティ(v3.1.0〜、v3.1.1で追加分あり) ​

拡張機能対応のためにICoreWebView2 / ICoreWebView2Controller / ICoreWebView2Environment / ICoreWebView2Settings / ICoreWebView2Profileのvtableを組み上げたので、ついでにコールバック・イベントを伴わないスカラー値のプロパティは一通り公開しています。用途別に代表例を挙げます(全量はソースコードのコメント、またはDemo_WebView2内のRun○○FamilyDemo各プロシージャを参照)。

系統例用途
ICoreWebView2ControllerZoomFactor(Let)/ RasterizationScale(Let)/ SetBoundsAndZoomFactor / MoveFocus / SetDefaultBackgroundColor表示倍率・DPI・フォーカス・背景色
ICoreWebView2IsMuted(Let)/ IsDocumentPlayingAudio(Get)/ StatusBarText(Get)/ FaviconUri(Get)/ Source(Get)/ DocumentTitle(Get)/ CanGoBack(Get)/ CanGoForward(Get)/ BrowserProcessId(Get)/ IsSuspended(Get)/ ContainsFullScreenElement(Get)/ IsDefaultDownloadDialogOpen(Get)/ frameID(Get、v3.1.1〜)音声ミュート、再生中判定、ステータスバー、favicon、現在のURL/タイトル、履歴の有無、プロセスID、サスペンド状態等
ICoreWebView2EnvironmentuserDataFolder(Get)/ FailureReportFolderPath(Get)実際に使われているフォルダパスの確認
ICoreWebView2SettingsScriptEnabled / WebMessageEnabled / UserAgentOverride / GeneralAutofillEnabled(いずれもLet)JS実行・WebMessage・UA偽装・オートフィルの可否
ICoreWebView2ProfileProfileName(Get)/ IsInPrivateModeEnabled(Get)/ DefaultDownloadFolderPath(Let)/ PreferredTrackingPreventionLevel(Let)プロファイル情報、ダウンロード先、トラッキング防止レベル

あえて実装していないもの

「あくまでもCDP制御主体のツール」という線引きのため、次の3種類は対象外です。

  • 完了コールバックが必要なメソッド(ExecuteScriptAsync等)
  • WebView2ネイティブのイベント(NavigationCompleted等)— CDPのPage.*イベントで代替してください
  • 他のインターフェースへネストして依存するもの

関連 ​

Excel VBA × CDP / WebDriver BiDi