ExcelVBAでIEを操作しています。
VBAより、あるWebページのボタンをクリックすると、自動で新しいタブが追加されます。
クリックボタンのある元のページのタブもそのまま残っています。
この新しいタブのIEオブジェクトを取得したいのですが、できません。
コードの一部を以下に載せます。
' 検索ボタンをクリック objIE.document.getElementById("btnSearch").Click ' 新規タブのIEオブジェクトを取得 Call getIE("XXX", wkObjIE) '"XXX"はタイトル(固定値)が入ります。wkObjIEはアウトプットです (中略) Public Function getIE(title As String, objIE As InternetExplorer) Set sh = CreateObject("Shell.Application") 'ShellWindowから1つずつ取得して処理 For Each win In sh.Windows 'ドキュメントタイトル取得失敗を無視(処理継続) On Error Resume Next document_title = "" document_title = win.document.title On Error GoTo 0 'タイトルバーにfunction引数の"title"が含まれるかチェック If InStr(document_title, title) > 0 Then Set objIE = win Exit For End If Next getIE = 1 End Function
具体的には、こちらのサイト「https://www.books-sanseido.co.jp/」 のメニュー「本を探す」にて、検索BOXに「9784295000396」を入力後、検索BOXの隣のボタンをクリックする操作を行い、これにより追加されるタブのオブジェクトを取得しようとしています。
環境は WindowsServer 2012R2、Excel2016、IEのバージョンは11です。
ウォッチウィンドウで上記コードのsh.Windowsを確認しても、元ページタブはあるのですが、新規タブが見つかりません。
一方で、別PCのWindows7の環境では、同一プログラムで問題なく新規タブのIEオブジェクトを取得できます。
Excel、IEのバージョンは上記と同じです。
試しに、デバッグ実行中に手動で元のページのタブを閉じて、新しいタブだけを残した状態にしたのですが、相変わらずsh.Windowsに当該タブが見つかりません。
ネットで調べても情報が見つからず、行き詰まっています。
原因・対応策などを教えていただけますでしょうか。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/11/29 05:01
2018/11/29 05:41
2018/11/29 05:58

回答6件
0
ベストアンサー
がんばってウィンドウハンドルを探すのも良いのですが…。
むしろ対象 Form タグの target="_blank" を書き換えて同じタブで開くようにしてしまうのはダメなのでしょうか?
クローリング先へのセッション数も抑えられますし…。
投稿2019/01/02 19:31
総合スコア456
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

0
本投稿が今直面している問題に、大変参考になりました。
VBスクリプトを使って、Automation AnywhereのRPAで同様の問題に直面しています。
Windows7,WIndows8.1,Windows10では正常にウインドウのタイトルを検出できるのですが、Windows2012R2では、手動でサブウインドウを開かないとウインドウタイトルを検出できませんでした。
RPAロボットでサブページを開く場合と手動でサブページを開く場合で、マシン上のウンドウタイトルの見え方が違うようです。
IEかシステムのなんらかのセキュリティ設定変更、もしくは、VBスクリプトのコード変更で回避できるものなのかAutomation Anywhereのコミュニティで問い合わせしています。
何かわかりましたら情報を共有させていただきたいと思います。
投稿2019/07/05 01:04
総合スコア16
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

0
dam9806 さん
改めて、初めのソースコードを読み取ってみました。
これは、勘ですが、オブジェクトの指定さえ間違いなければ、取得できると思います。
document_title = win.document.title
ここで、タイトルを取得しているようですが、取得しようとする対象オブジェクトが"Internet Explorer"です。このオブジェクトでは、タイトルは取得できません。
ここから、HTMLのオブジェクトを作成して、そこからタイトルを取得するのが良いと思います。
またサンプルですが、下の様に実行すれば、ウィンドウを全部調査しますので、間違いなく取得できると思います。
VBA
1Sub test03() 2 Dim IE As InternetExplorer 3 Dim Doc As HTMLDocument 4 Dim sh As Object 5 Dim win As Object 6 7 Set sh = CreateObject("Shell.Application") 8 For Each win In sh.Windows 9 If win.Name = "Internet Explorer" Then 10 Set IE = win 11 IE.navigate IE.LocationURL 12 IE.Visible = True 13 Do While IE.Busy = True Or IE.readyState < READYSTATE_COMPLETE 14 DoEvents 15 Loop 16 Set Doc = IE.document 17 Debug.Print IE.LocationURL, Doc.Title 18 End If 19 Next 20 Set win = Nothing 21 Set sh = Nothing 22 Set Doc = Nothing 23 Set IE = nothoing 24End Sub
また、ホームページの作成方法(コード)によって、やり方を変更することが重要だと思います。
私も人に教える立場ではありませんが、Excelからインターネットを操作するとき、対象のホームページのコードを読む様にしています。
サンプルのコードは、下図のようになっており、
form method="post" action="アドレス"
で、他の実行ファイルにデータを送っており、検査した結果は、新たに取得しないとできない仕様になっているように読み取れます。
今回の様に、対象のオブジェクトを表示する方法も3種類もあり、他にも方法がありそうです。
参考までに、今回回答しました。
投稿2018/12/24 04:44
総合スコア344
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

0
dam9806 様
申し訳ございません、質問の意図を読み間違えました。
「https://www.books-sanseido.co.jp/」のサイトのソースコードの検索の所を見ると、なんとなくではございますが、検索用のアドレスに検索値を渡して、自動的に結果が表示されています。自分も色々試した結果、検索結果のオブジェクトを取得する方法は、かなり難しいです。
そこで、直接検索用のアドレスを指定する方法なら、検索結果のオブジェクトを取得できました。
サンプルコードではございますが、参考にしてください。
このコードで、検索結果をデバックプリントで出力しています。
尚、実行するには、参照設定が必要です。
mshtml.tlb (Microsoft HTML Object Library)
ieframe.dll (Microsoft Internet Controls)
VBA
1Sub test02() 2 3 Dim IE As InternetExplorer 4 Dim Doc As HTMLDocument 5 Dim objTag As IHTMLElement 6 Dim strURL As String 7 Dim MOJI As String 8 9 10 MOJI = "9784295000396" 11 12 13 strURL = "https://www.books-sanseido.jp/booksearch/BookSearchExec.action" 14 Set IE = CreateObject("Internetexplorer.Application") 15 IE.navigate strURL 16 IE.Visible = True 17 18 Do While IE.Busy = True Or IE.readyState < READYSTATE_COMPLETE 19 DoEvents 20 Loop 21 22 Set Doc = IE.document 23 24 For Each objTag In Doc.getElementsByTagName("input") 25 If InStr(objTag.outerHTML, "キーワード") > 0 Then 26 Doc.querySelector("input[type=text]").Value = MOJI 27 Doc.querySelector("input[type=submit]").Click 28 Exit For 29 End If 30 Next 31 32 Do Until Doc.readyState = "complete" 33 DoEvents 34 Loop 35 36 37 Debug.Print Doc.Title 38 Debug.Print Doc.Url 39 40 Dim i As Long 41 For i = 1 To Doc.getElementsByClassName("results_mes").Length 42 Debug.Print Doc.getElementsByClassName("results_mes").Item(, i).textContent 43 Next i 44 45 Set Doc = Nothing 46 Set IE = Nothing 47 48End Sub
投稿2018/12/24 02:21
総合スコア344
0
「https://www.books-sanseido.co.jp/」のサイトのソースコードを見ると、Inputタグによる操作をする必要があります。
これであれば、検索結果のウィンドウが表示されると思います。
VBA
1Sub test01() 2 3 Dim IE As InternetExplorer 4 Dim Doc As HTMLDocument 5 Dim objTag As IHTMLElement 6 Dim strURL As String 7 Dim MOJI As String 8 9 10 MOJI = "9784295000396" 11 12 13 strURL = "https://www.books-sanseido.co.jp/" 14 Set IE = CreateObject("Internetexplorer.Application") 15 IE.navigate strURL 16 IE.Visible = True 17 18 Do While IE.Busy = True Or IE.readyState < READYSTATE_COMPLETE 19 DoEvents 20 Loop 21 22 Set Doc = IE.document 23 24 For Each objTag In Doc.getElementsByTagName("input") 25 26 Debug.Print objTag.outerHTML 27 If InStr(objTag.outerHTML, "キーワード") > 0 Then 28 Doc.querySelector("input[type=text]").Value = MOJI 29 Doc.querySelector("input[type=submit]").Click 30 Exit For 31 End If 32 Next 33 34 Do Until Doc.readyState = "complete" 35 DoEvents 36 Loop 37 38 Set Doc = Nothing 39 Set IE = Nothing 40 41End Sub
尚、実行するには、参照設定が必要です。
mshtml.tlb (Microsoft HTML Object Library)
ieframe.dll (Microsoft Internet Controls)
上手く、構造化すれば便利なマクロが完成すると思います。
頑張って下さい。
投稿2018/12/22 04:35
総合スコア344
0
同じExcel2016、IE11で挙動が異なるのは、OSのbit数の違いかも
しれません。
Windows7 32bit
WindowsServer 2012R2 64bit
下記サイトが参考なると思いましたが、実行させるために
64bit用のAPI関数を準備する必要があります。
https://www.ka-net.org/blog/?p=7697
まずは、上記サイトにある、以下の関数を参考にして、
新規タブのIEオブジェクトを取得できないでしょうか。
Private Function GetActiveIE(ByVal url As String) As Object
'URLを指定して起動中のIE取得
(後略)
私は試しておりませんが、やってみる価値はあると思います。
<追記>
WindowsのAPI関数を64bitと32bitのどちらでも呼び出しできる記述を
以下に示します。ただし、よく理解しないままにAPI関数を使うことは
お勧めしません。
VBA
1'API関数 2#If VBA7 And Win64 Then 3 Private Declare PtrSafe Function FindWindowEx Lib "User32" Alias "FindWindowExA" ( _ 4 ByVal hWndParent As LongPtr, _ 5 ByVal hWndChildAfter As Long, _ 6 ByVal lpszClass As String, _ 7 ByVal lpszWindow As String) As LongPtr 8 Private Declare PtrSafe Function ShowWindow Lib "User32" ( _ 9 ByVal hWnd As Long, _ 10 ByVal nCmdShow As Long) As LongPtr 11 'FindWindowExの戻り値を入れる変数 12 Dim hNavBar As LongPtr 13#Else 14 Private Declare Function FindWindowEx Lib "User32" Alias "FindWindowExA" ( _ 15 ByVal hWndParent As Long, _ 16 ByVal hWndChildAfter As Long, _ 17 ByVal lpszClass As String, _ 18 ByVal lpszWindow As String) As Long 19 Private Declare Function ShowWindow Lib "User32" ( _ 20 ByVal hWnd As Long, _ 21 ByVal nCmdShow As Long) As Long 22 'FindWindowExの戻り値を入れる変数 23 Dim hNavBar As Long 24#End If
投稿2018/12/08 02:33
編集2018/12/08 05:47総合スコア1065
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。