【Excel】TinySeleniumVBA(Chromium版Edge)を使用したWebアプリ操作

# はじめに
これは、[Visual Basic Advent Calendar 2021](https://qiita.com/advent-calendar/2021/vb)の22日目の記事となります。

Microsoftから2022年6月にInternet Explorer 11デスクトップアプリケーションのサポートが終了されるとの発表がありました。

https://forest.watch.impress.co.jp/docs/news/1325704.html

# IEサポート終了による影響
https://social.msdn.microsoft.com/Forums/ja-JP/c0765a67-b8ba-40dc-ac52-aac7be9f1d6a/ie123981246912509125401248812364202224180626376152608512395320662?forum=vbajp

https://www.ka-net.org/blog/?p=13592

~~サポート終了により、IEオートメーション系のマクロが使えなくなります。~~

```vb
Set objIE = CreateObject("InternetExplorer.Application")
Or
Set objIE = New InternetExplorer
```

【2022/03/28追記】
オートメーションでの IE11 起動も Edge にリダイレクトされるという仕様は撤回されました。
よって、引き続き IE を使い続ける事もできます。

https://qiita.com/yaju/items/4490af9f8b7962db59a3

# TinySeleniumVBAの紹介
うえぞうさん([uezochan](https://twitter.com/uezochan))がWebDriverを使ってブラウザー操作を行うSeleniumクライアント「TinySeleniumVBA」を公開されています。

https://github.com/uezo/TinySeleniumVBA

https://qiita.com/uezo/items/66e20b064ffd5f239b9a

## TinySeleniumVBAの機能追加版(SeleniumVBA)の紹介
Tinyとは小さいの意味で、最低限の機能のみになっています。
単純な要件であれば基本的に問題ないのですが、凝り出すと機能が足りなくて困ってしまう。
オープンソースですからフォークされて機能追加されたリポジトリがあります。

https://github.com/GCuser99/SeleniumVBA

## WebDriverの自動更新
WebDriverと現在ブラウザのバージョンが違うと下記エラーメッセージが出ます。
ユーザーにWebDriverを手動更新してもらうことになります。
例 This version of MSEdgeDriver only supports MSEdge version 96
Current browser version is 101.0.121.053 with binary path
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14053/c45201ac-fb51-fb31-8af2-c1921247af94.png)

WebDriverを自動更新させるモジュールが下記サイトにあります。

https://qiita.com/yamato1413/items/4b982aee46f28358fd39

機能追加版(SeleniumVBA)には、WebDriverを自動更新用クラス「WebDriverManager.cls」が用意されています。

https://github.com/GCuser99/SeleniumVBA/blob/main/src/WebDriverManager.cls

## Mac対応版
https://qiita.com/yaju/items/caa29af1c133cd8c02e1

## IEMode対応
Issueに改良方法を記載してあります。32bit版IEドライバーの方が動作が軽いとのこと

https://github.com/uezo/TinySeleniumVBA/issues/70

機能追加版(SeleniumVBA)には、dev版としてIEモードが組み込まれています。まだ少し問題点もあり、discussionsが用意されています。

https://github.com/GCuser99/SeleniumVBA/discussions/10

# TinySeleniumVBAの導入
## Microsoft Scripting Runtime を参照
ツール＞参照設定から Microsoft Scripting Runtime に参照を通してください
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14053/33bc6e08-6e58-0ce7-f649-d21485f7fe64.png)

## モジュールをプロジェクトに追加
TinySeleniumVBAの最新版をダウンロードする。 

https://github.com/uezo/TinySeleniumVBA/releases

WebDriver.cls、WebElement.cls、JsonConverter.basをプロジェクトに追加してください。
※プロジェクトに追加する前に注意事項を先にお読みください
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14053/75e76f2a-45c3-55db-3212-f622e59eec2f.png)

### 注意事項
WebDriver.cls、WebElement.cls、JsonConverter.basは、githubに公開する関係と思われるが、改行コードが`Lf`になっています。
そのままではクラスモジュール(WebDriver.cls、WebElement.cls)が標準モジュールにインポートされてしまいます。
その状態で実行すると、「VERSION 1.0 CLASS」のところでコンパイルエラーになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14053/03259477-10bd-54c8-1152-3508203d004f.png)
サクラエディタなどを使用して、改行コードを`CRLF`として保存し直しなおしてください。

【2022/03/22追記】
>ヘッドレスモードなど設定がしやすくなったv0.1.2をリリースしました。プロジェクトへのインポートがうまくいかない問題にも対応済みです。ドラッグ&ドロップでインポートできます。お試しくださいませ

v0.1.2以降であれば、ドラッグ&ドロップでそのままインポートできるようになっていました。
現時点の最新版v0.1.3で確認しました。

## WebDriverのダウンロード
WebDriverをダウンロードしてください（ブラウザのメジャーバージョンと同じもの）

* Edge: https://developer.microsoft.com/ja-jp/microsoft-edge/tools/webdriver/
* Chrome: https://chromedriver.chromium.org/downloads

自分のPC 64bit、Office 365 32bitという環境で、PCに合わせてEdge64bit版をダウンロードしました。
C:¥Tools¥edgedriver_win64フォルダ配下に格納しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14053/2b4e0b48-bfdd-8aed-dda5-520bef85b62e.png)

# TinySeleniumVBAの修正(WebDriver Ver.128以降)
WebDriver Ver.128以降からデフォルトポート 9515をやめてランダムに変更されました。

https://chromium.googlesource.com/chromium/src/+/6f33d75f071e322c4a3e49b0a4ac2022e5b6cada

これにより、ポート指定をしていなかったTinySeleniumVBAでエラーが発生するようになりました。
下記の部分を修正してください。

```vb:WebDriver.cls
' Launch Edge Driver
Public Sub Edge(ByVal driverPath As String, Optional ByVal driverUrl As String = "http://localhost:9515")
    start driverPath & " --port=9515", driverUrl, "MicrosoftEdge"
End Sub

' Launch Chrome Driver
Public Sub Chrome(ByVal driverPath As String, Optional ByVal driverUrl As String = "http://localhost:9515")
    start driverPath & " --port=9515", driverUrl, "chrome"
End Sub
```

# TinySeleniumVBAのサンプル
TinySeleniumVBAに最初に入っている「Example.bas」ではグーグル検索で「"yomoda soba"」を検索するようになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14053/74cb6576-603e-bb85-4178-71923a8a66a4.png)
たまにエラーが出るときがありました。しかし、デバッグしていくとエラーが出ません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14053/6eb6aaa2-930d-1db7-edc6-554413c17974.png)

## Sleepの追加
たぶん処理が速すぎるのかと思い、Sleepを入れたところ安定するようになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14053/742ea0c8-cee7-f965-60ae-3825e698a662.png)

```vb:Example.bas
' ==========================================================================
' Example
' ==========================================================================
Option Explicit

Private Declare Sub sleep Lib "kernel32" Alias "Sleep" (ByVal ms As Long)

Public Sub main()
    ' Start WebDriver (Edge)
    Dim Driver As New WebDriver
    'Driver.Edge "path\to\msedgedriver.exe"
    Driver.Edge "C:\Tools\edgedriver_win64\msedgedriver.exe"

    ' Open browser
    Driver.OpenBrowser
    
    ' Navigate to Google
    Driver.Navigate "https://www.google.co.jp/?q=selenium"

    ' Get search textbox
    Dim searchInput
    Set searchInput = Driver.FindElement(By.Name, "q")
    
    ' Get value from textbox
    Debug.Print searchInput.GetValue
    
    ' Set value to textbox
    searchInput.SetValue "yomoda soba"
    
    ' 1秒待機
    sleep 1000

    ' Click search button
    Driver.FindElement(By.Name, "btnK").Click
    
    ' Refresh - you can use Execute with driver command even if the method is not provided
    Driver.Execute Driver.CMD_REFRESH
End Sub
```

# TinySeleniumVBAでWebアプリ操作
前記事でVB.NETにてWebView2コントロールを使用して、体脂肪率を計算するサイトで身長と体重をセットして体脂肪率を求めました。

https://qiita.com/yaju/items/2e2c7c421a8fa6e7c0a2

TinySeleniumVBAのサンプルでも同じようにしてみます。
Excelらしくセルに身長と体重をセットして、体脂肪率のセルに値をセットされるようにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14053/f7a6659d-53c8-1c9d-7320-0fb5aa37bc1b.png)
体脂肪率ボタンをクリックすると、[Keisan 生活や実務に役立つ計算サイト - 体脂肪率](https://keisan.casio.jp/exec/system/1161228728)のサイトが開きます。身長と体重をセットして自動で計算ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14053/9fb2bf18-123f-5fdc-e14d-c405245d7295.png)
体脂肪率の結果を取得して、体脂肪率セルに値をセットします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14053/a4893933-d526-d2d7-92e6-4dbcb11399d3.png)

## ソースコード
```vb:Example.bas
Option Explicit

Private Declare Sub sleep Lib "kernel32" Alias "Sleep" (ByVal ms As Long)

Public Sub main()
    ' Start WebDriver (Edge)
    Dim Driver As New WebDriver
    Driver.Edge "C:\Tools\edgedriver_win64\msedgedriver.exe"
    
    ' Open browser
    Driver.OpenBrowser
    
    ' BMI計算サイト
    Driver.Navigate "https://keisan.casio.jp/exec/system/1161228728"

    ' 身長をセット
    Dim height
    Set height = Driver.FindElement(By.ID, "var_身長")
    height.SetValue Cells(1, 2).value
    
    ' 体重をセット
    Dim weight
    Set weight = Driver.FindElement(By.ID, "var_体重")
    weight.SetValue Cells(2, 2).value
    
    ' ボタンクリック
    Driver.FindElement(By.ID, "executebtn").Click
    
    ' 1秒待機
    sleep 1000
    
    ' BMIをセット
    Dim bmi
    Set bmi = Driver.FindElement(By.ID, "ans1")
    Cells(3, 2).value = bmi.GetText

    ' Shutdown
    Driver.Shutdown
End Sub
```

# 最後に
現在リリースされている Windows 10 LTSC や Windows Server は IE11 アプリのサポート終了の対象外となるため、OSサポート終了の2029年が IE11の真の終焉となるようです。
EdgeのIEモードでWebページの操作は難しいようです。APIを駆使すればできるようですが、それなら素直にTinySeleniumVBAを使いましょう。

https://www.ka-net.org/blog/?p=13592