Edge で IEモードで開いているサイトをVBAで制御する(今までのIE制御ツールの流用)

# IE は滅びん！何度でも蘇るさ！
・・・と、ムスカ様のありがたいお言葉をお借りしました。下記のような情報もありますし・・・

https://ascii.jp/elem/000/004/056/4056944/

そうは言ってもその後すぐに崩壊したラピュタのように、IEもいずれ使われなくなるわけです。
しかし、イントラのシステムではリプレースが間に合わない、IE でしか動かない物も残る事が予想されます。
Edge が IE モードをサポートする以上、IE ベースの Web システムを制御したい、今まで IE を VBA で操っていたのを、そのまま使いたい、という要望があるでしょう。
# IEモードのサイトを制御するための、非常に有難い情報
もう、下記のサイトの情報が無ければ、何ともできないのです。

https://social.msdn.microsoft.com/Forums/ja-JP/c0765a67-b8ba-40dc-ac52-aac7be9f1d6a/ie123981246912509125401248812364202224180626376152608512395320662?forum=vbajp

本当にありがとうございます。
簡単に説明すると(ちょっと間違ってるかもしれませんが)、Edge のプロセスの子プロセスから、IEモードで動作している「Internet Explorer_Server」プロセスを探し、そのウインドウハンドルから HTMLDocument オブジェクトを取得する、と言うモノです。
# 具体的には、どうやるの？
## 起動方法
当たり前ですが、「Internet Explorer_Server」プロセスを取得するためには、IEモードでサイトを表示している必要があります。
IEモードで制御したい！と思っているという事は、IEモードでしか動かないサイトがあるわけでしょうから、それを表示します。
ここで注意が必要なのは、**IEモードで開くように設定したサイトでも、WebDriverを介して起動すると、非IEモードでサイトが開かれてしまう**という事です(msedgedriver.exe を使う場合)。
IE用のWebDriverを使えばよいのですが、それならその後の制御もWebDriverにすれば良いわけで、今までのVBAツールの流用、という方針から外れますし、起動の為だけにIE用WebDriverを使うのもどうかと思う訳です。
ではどうするか？
以下のコマンドで Edge を起動しましょう。
```:Edge 起動コマンド
start msedge IEモードで開くサイトのURL
```
```vb:Edge を引数のURLで起動させる
Public Sub Exec_Edge(Byref strURL As String)
    Const ProcessName = "msedge"
    Dim strCom As String
    Dim objWs As Object

    strCom = "cmd.exe /c start " & ProcessName & " " & strURL
    Set objWs = CreateObject("Wscript.Shell")
    objWs.Run strCom, 0, True
 
End Function
```
起動した後は、前述の方法で、「Internet Explorer_Server」プロセスを探し、そのウインドウハンドルから HTMLDocument オブジェクトを取得します。
## 今までの、IEでの手法
通常、IEアプリケーションオブジェクトを取得して、下記の様に指定のURLを開いたりするはずです。
```vb:IEアプリケーションを起ち上げる
Set objIE = CreateObject("InternetExplorer.Application") '又は Set objIE = New InternetExplorer
objIE.Visible = True 'IEを表示
objIE.navigate "開きたいサイトのURL"
```
そして、この後Documentオブジェクトに対して、色々操作をするはずです。
例えば、Googleの検索を行おうとすれば
```vb:Googleで検索する
'google検索項目(name=q)にセットする
objIE.Document.getElementsByName("q")(0).Value = "検索したい言葉"
```
みたいになるはずです。
## HTMLDocument を操作する場合
前述の
```vb:Googleで検索する
Set objIE = CreateObject("InternetExplorer.Application") '又は Set objIE = New InternetExplorer
'google検索項目(name=q)にセットする。
objIE.Document.getElementsByName("q")(0).Value = "検索したい言葉"
```
みたいな操作は、「Internet Explorer_Server」プロセスから取得した HTMLDocument オブジェクトを使用して置き換えられます。
すなわち
```vb:
Set objHTMLDoc = [Internet Explorer_Serverプロセスから取得したHTMLDocumentオブジェクト]
'google検索項目(name=q)にセットする
objHTMLDoc.getElementsByName("q")(0).Value = "検索したい言葉"
```
の様に、`objIE.Document`を、Internet Explorer_Serverプロセスから取得したHTMLDocumentオブジェクトの`objHTMLDoc`と置き換えてやれば、ほぼ今までの DOM 操作が可能です。
とても簡単ですね。
## IEアプリケーションオブジェクトは、無い
一方で、IEアプリケーションオブジェクトが無いため、
```vb:IEアプリケーションを起ち上げる
Set objIE = CreateObject("InternetExplorer.Application") '又は Set objIE = New InternetExplorer
objIE.Visible = True 'IEを表示
objIE.navigate "開きたいサイトのURL"
```
の`navigate`を使ったURLの遷移や
```vb:IE の処理待機
Set objIE = CreateObject("InternetExplorer.Application") '又は Set objIE = New InternetExplorer
Do While objIE.Busy = True Or objIE.ReadyState <> 4
    DoEvents
Loop
```
の様なIEのビジー待機が使えません。
## しかし、JavaScript(JScript)は動く
JavaScript が動くなら、
```vb:IEで指定のURLに遷移
Set objIE = CreateObject("InternetExplorer.Application") '又は Set objIE = New InternetExplorer
objIE.Visible = True 'IEを表示
objIE.navigate "開きたいサイトのURL"
```
は下記の様に置き換える事が出来ます。
```vb:IEで指定のURLに遷移 (JavaScript)
Set objHTMLDoc = [Internet Explorer_Serverプロセスから取得したHTMLDocumentオブジェクト]
Set objWindow = objHTMLDoc.ParentWindow
objWindow.location.href = "開きたいサイトのURL"
```
同様に、IEのビジー待機も
```vb:IE の処理待機
Set objIE = CreateObject("InternetExplorer.Application") '又は Set objIE = New InternetExplorer
Do While objIE.Busy = True Or objIE.ReadyState <> 4
    DoEvents
Loop
```
を下記に様に変更する事で対応可能です
```vb:IE の処理待機 (JavaScript)
Set objHTMLDoc = [Internet Explorer_Serverプロセスから取得したHTMLDocumentオブジェクト]
Do Until objHtmlDoc.readyState = "complete"
    DoEvents
Loop
```
# Edge を消す方法
|　何について調べますか？
| ┌────────────┐
|　|　お前を消す方法　　　　　　　｜
|　| 　　　　　　　　　　　　　 　　　　｜
| └────────────┘
|　[ オプション(O) ]　　　[ 検索(S) ]
|
｀──────────┐ ┌───
　　　　　　　　　　　, '´l,　　..| ./
　　　　　　　, -─-'- 、i_　　|/
　　 ＿_, '´　　　　　　　ヽ、
　　　',ー--　●　　　　　　　ヽ、
　　　 ｀"'ゝ、_　　　　　　　　　 ',
　　　　　　〈｀'ｰ;＝=ヽ、〈ｰ- 、 !
　　　　　　 ｀ｰ´　　　　ヽi｀ヽ iﾉ
　　　　　　　　　　　　　　　 ! /
　　　　　　　　　　　　　　r'´、ヽ
　　　　　　　　　　　　　　｀´ヽノ
実行前に、確実にIEを閉じておかないと、IEモードで立ち上がっているサイトが複数あると、目的のサイトの「Internet Explorer_Server」プロセスが取得できないとか、終了時に Edge を終わらせたいと言う時は、
```:Edge を終了させるコマンド
taskkill /IM msedge.exe /T /F
```
```vb:Edge を終了させる
Public Sub Close_Edge()
    Const ProcessName = "msedge.exe"
    Dim strCom As String
    Dim objWs As Object

    strCom = "taskkill /IM " & ProcessName & " /T /F"
    Set objWs = CreateObject("Wscript.Shell")
    objWs.Run strCom, 0, True
 
End Function
```
と強制的に終わらせると良いです。
# 7年間待ってやる
冒頭の情報から、7年後は怪しいですし、そも「Windows 10 が最後の Windows」って言ってたのに、しれっと「Windows 11」が出てくるから、7年持たないかもしれない。
ムスカ様も「3分間待ってやる」と言いつつ、3分待ちませんでしたし。
とにもかくにも社内外の情シスの方々、IE縛りの Web システムのリプレースは、早急によろしくお願い致します。