Frame の先に何を見るか？

# 今更 Frame タグを VBA で扱う
**(2023/1/19追記)**
重要な事を書くのを忘れていました。
この内容は Internet Explorer 上の Frame を VBA から操作する内容です。
今となっては時代遅れの内容です。
## なぜ今、Frameタグをネタにするのか？
**「なぜ山に登るのか？」** の問いの答えが **「そこに山があるから」** であるならば、
**「なぜ今は非推奨のFrameを扱うのか？」** の問いの答えは **「そこにFrameがあるから」** なのです。
お客様[^1]指定のシステムだから、しょうがない。
[^1]:信じられない事に、~~通○インフラ関係の会社~~ なんですよ？
## VBA で Frame を含む Webページを扱う場合の、今までのやり方
HTML が、まだ Frame を推奨していた頃、VBA から Frame エレメント内の HTML を扱う方法は、以下の様な感じでした。
```vb:frame 内のエレメントを扱う
Public Sub Main_Sub()
    Dim objIE As Object
    Dim objEleSet As Object
    Dim objEle As Object
    Dim strTmp As String
    
    'IEを起ち上げ、フレームサンプル用ページを開く
    Set objIE = CreateObject("InternetExplorer.Application")
    objIE.Visible = True
    objIE.navigate "file:///D:/test/html/frame.html"
    'frameエレメントを取得
    Set objEleSet = objIE.document.getElementsByTagName("frame")
    '1つ目のframeを取得
    Set objEle = objEleSet(0)
    'フレーム内にあるdivに記載された文字を取得
    Set objEleSet = objEle.document.getElementsByTagName("div")
    strTmp = objEleSet(0).innerText
    
End Sub
```
`[frameエレメントを格納した変数].document` がフレーム内の[HTMLドキュメント]となり、あとは普通に DOM でコントロールできたわけです。
しかし、今現在(2/23/1/18)この方法は通用しません。
前述のコードで言うと、`objEle.document` が `objIE.document` と等しくなってしまうのです。
そのため、`objEle.document` でエラーが出ず、上記だと `strTmp = objEleSet(0).innerText` でエラーが出ます。
## VBA で Frame を含む Webページを扱う場合の、今現在のやり方
2通りのやり方があります。
1つは、「参照設定」で **「Microsoft HTML Object Library」** を参照して対処する方法。
もう1つは、**JavaScript** を使う方法。
### 「Microsoft HTML Object Library」を参照して対処する方法
「参照設定」で「Microsoft HTML Object Library」を参照し、下記の様にコードを記載します。
```vb:frame 内のエレメントを扱う(Microsoft HTML Object Library を参照する方法)
Public Sub Main_Sub()
    Dim objIE As Object
    Dim objEleSet As Object
    Dim objEle As Object
    Dim objDoc As HTMLDocument
    Dim strTmp As String
    
    'IEを起ち上げ、フレームサンプル用ページを開く
    Set objIE = CreateObject("InternetExplorer.Application")
    objIE.Visible = True
    objIE.navigate "file:///D:/test/html/frame.html"
    'frameエレメントを取得
    Set objEleSet = objIE.document.getElementsByTagName("frame")
    '1つ目のframeを取得
    Set objEle = objEleSet(0)
    'フレーム内にあるdivに記載された文字を取得
    Set objDoc = objEle
    Set objEleSet = objDoc.getElementsByTagName("div")
    strTmp = objEleSet(0).innerText
    
End Sub
```
`Dim objDoc As HTMLDocument` で宣言した変数に、`Set objEle = objEleSet(0)` で取得した frame エレメントを、`Set objDoc = objEle` で代入するだけ。
たったこれだけで、`objEle` がドキュメントオブジェクトに大変身、~~わけがわからないよ~~。
### JavaScript を使用して対処する方法
JavaScript で frame 内の document オブジェクトを取得する方法は、`[フレームエレメント].contentDocument` を使います。
そして、[こちら](https://qiita.com/tamarinn_x/items/d81f6324ce4aa3afef45#%E3%81%97%E3%81%8B%E3%81%97javascriptjscript%E3%81%AF%E5%8B%95%E3%81%8F)で示した通り、VBA の HTML オブジェクトには、殆どのJavaScript(JScript) のメソッドやプロパティが使えます。
```vb:frame 内のエレメントを扱う(JavaScript を使う方法)
Public Sub Main_Sub()
    Dim objIE As Object
    Dim objEleSet As Object
    Dim objEle As Object
    Dim objDoc As Object
    Dim strTmp As String
    
    'IEを起ち上げ、フレームサンプル用ページを開く
    Set objIE = CreateObject("InternetExplorer.Application")
    objIE.Visible = True
    objIE.navigate "file:///D:/test/html/frame.html"
    'frameエレメントを取得
    Set objEleSet = objIE.document.getElementsByTagName("frame")
    '1つ目のframeを取得
    Set objEle = objEleSet(0)
    'フレーム内にあるdivに記載された文字を取得
    Set objDoc = objEle.contentDocument
    Set objEleSet = objDoc.getElementsByTagName("div")
    strTmp = objEleSet(0).innerText
    
End Sub
```
`Dim objDoc As Object` でオブジェクト変数を宣言し、`Set objDoc = objEle.contentDocument` で frame 内のドキュメントオブジェクトを取得します。
## IE (IEモード) も Frame も過去の遺物なんですけどね
私の様に、無駄な事で時間を使わない様に情報としてまとめましたが、願わくばこれに「助かった！」と思うような、廃れていく情報に振り回される人が居ない様に願います。
IE (IEモード) や Frame がいまだに使われる現状を、先ず何とかしてほしいですよね。