InternetExplorer のHTML要素にValueを設定するFunctionを考えてみる。
ページ要素の分析とか対象の要素に合わせたカスタマイズをページ毎に考えるのがめんどいから、これ一つあればとりあえず値の設定はできそーだろってやつを作ってみる。textarea、input、select要素への値の設定を1つのFunctionでできるように関数を組んでみました。
まずは、ざっと考えたコードを紹介。
'■ 特定キーを含むタグにValueをセットする。 '■ ie : 取得済みIEオブジェクト '■ keyArgs : Valueをセットしたい対象タグに含まれるキーワードを配列で指定する。 '■ Value : 設定したいValue値 Sub SetValueToIE(ie, keyArgs, val) Dim aryElm, ans, Elm Set aryElm = CreateObject("System.Collections.ArrayList") Set aryElm = CollectElementsFromKeywords(ie.document, keyArgs, aryElm) If aryElm.Count = 0 Then ans = MsgBox("指定のキーワードではHTML要素を見つけられませんでした。" & vbNewLine & "・キャンセル ⇒ スクリプトを強制終了", vbOKCancel, "vbscript - IE要素検索に失敗") If ans = vbCancel Then MsgBox "スクリプトを終了します。", vbInformation, "vbscript - ユーザ介入強制終了" WScript.Quit End If ElseIf aryElm.Count = 1 Then If LCase(aryElm(0).TagName) = "textarea" Then aryElm(0).innerText = val Else aryElm(0).value = val End If Else ans = MsgBox("指定のキーワードで" & aryElm.Count & "個の要素を見つかりました。" & vbNewLine & "・Yes ⇒ 全ての要素に値を適用" & vbNewLine & "・No ⇒ 値を設定せずスキップ" & vbNewLine & "・キャンセル ⇒ スクリプトを強制終了", vbYesNoCancel, "vbscript - IE要素検索で多数Hit") Select Case ans Case vbYes For Each Elm In aryElm If Elm.TagName = "textarea" Then Elm.innerText = val Else Elm.value = val End If Next Case vbCancel MsgBox "スクリプトを終了します。", vbInformation, "vbscript - ユーザ介入強制終了" WScript.Quit End Select End If End Sub '■ 子フレームも含め、IE内のすべてのDocumentから指定キーワードで要素検索 Function CollectElementsFromKeywords(doc, keyArgs, aryElm) Dim url, ifrm, i Set aryElm = SerchElementsFromKeywords(doc, keyArgs, aryElm) On Error Resume Next Set ifrm = doc.frames For i = 0 To ifrm.Length -1 If Err.Number = 0 Then Set aryElm = CollectElementsFromKeywords(ifrm(i).document, keyArgs, aryElm) End If Next On Error GoTo 0 Set CollectElementsFromKeywords = aryElm End Function '■ 指定キーワードリストが含まれるタグをコレクションに追加して返す。 Function SerchElementsFromKeywords(doc, keyArgs, aryElm) Dim Elm, txtTag, keyMatch, Tags ' 入力系のタグを検査 SrchTags = Array("textarea", "input", "select", "button", "option", "a", "div") For Each SrchTag In SrchTags For Each Elm In doc.getElementsByTagName(SrchTag) txtTag = Replace(Elm.OuterHtml, Elm.InnerHtml, "") ' 1つでも含まれないキーワードがあったらFalseにする。 keyMatch = True For Each Arg In keyArgs If InStr(txtTag, Arg) = 0 Then keyMatch = False End If Next If keyMatch Then aryElm.Add Elm End If Next Next Set SerchElementsFromKeywords = aryElm End Function '■ vbsで指定タイトル・URLの起動中IEのオブジェクトを取得 https://yizm.work/sample_code/vbscript/vbs-getie-object/ Function getObjIE(Key) Dim KeyWord, ie, Reg Set ie = Nothing Set Reg = CreateObject("VBScript.RegExp") Reg.Pattern = ".*" & Key & ".*" On Error Resume Next For Each obj In CreateObject("Shell.Application").Windows If TypeName(obj.Document) = "HTMLDocument" Then If Reg.Test(obj.LocationName) Or Reg.Test(obj.LocationURL) Then Set ie = obj End If End If Next On Error GoTo 0 Set Reg = Nothing If ie Is Nothing Then MsgBox "指定のieが見つかりませんでした。" Else Set getObjIE = ie End If End Function
以下の3つの関数を作ってます。
- Sub SetValueToIE(ie, keyArgs, val)
- Function CollectElementsFromKeywords(doc, keyArgs, aryElm)
- Function SerchElementsFromKeywords(doc, keyArgs, aryElm)
やろうとしてることのメインはSetValueToIEで、ieにはCreateObjectで作ったieか、getObjIEで取得したieをセット。keyArgsには配列で値を設定したい要素のタグに含まれるキーワードを複数入れる。valには設定したい値を入れる。
ieのHTML要素はiframeタグで区切られて一発で取得できない可能性があるから、 CollectElementsFromKeywords関数を使って再帰的にiframe要素のdocumentも検索する。
で、検索対象にしたdocumentに対してSerchElementsFromKeywords関数で指定キーワードを全て含む入力系要素がないかを検査してエレメント参照を全部 取得してくるという作り。入力系要素としては、"textarea", "input", "select", "button"を対象にしている。(buttonが含まれているのは、この機能を使いまわしてClickイベント送る機能とか作る為。)
入力中のキーワードでの要素の誤検出を防ぐ為、OuterHTMLからInnerTextを置換で削除してからキーワード検査する。
で、取得したエレメントがtextareaだったらInnerText、それ以外だったらValueにvalを設定。複数検出されてたらダイアログ出して全部に設定するかキャンセルするか確認する・・・みたいな。
Set ie = getObjIE("yizm.work") SetValueToIE ie, Array("textarea", "comment", "required"), "わんすけ"