表示上ページが移動しているにも関わらず、移動後のページエレメントが読めない
未読分:6件
昨日以降(0) 2日前以降(0) 3日前以降(0) 4日前以降(0) 5日前以降(0)
近田 伸矢, 植木 悠二, 上田 寛
IEのデータ収集&自動操作のプログラミング本はこの1冊だけ!IEの起動やポップアップウィンドウ、表示を制御する基本的なコードはもちろん、テキストボックスやラジオボタン、表、ハイパーリンクなどのHTML部品を制御する方法など、自動操作に欠かせないノウハウを丁寧に解説。
Message#6 2017年6月6日(火)11時17分 From: 初心者 | 返事 削除 変更 |
NMCのメッセージ(#5)への返事 アドバイスありがとうございます。 教えていただいたコードを追加したところ、うまくいくようになりました。 ”ログインボタンによるページ移動”だけでなく、他の”URLリンクによるページ移動”も同様に正常に行くようになりました。 ページ移動の時間待ちの問題かなっと思いステップ実行で移動後のページが表示されてから、エレメントを読んでみても移動後のエレメントがget出来なかったので困っていましたが、”見えているもの=最新ウインド”ではないということなのでしょうか? 本当にありがとうございました。大変助かりました。 > プログラムをよく見ると私の指摘は全くピント外れでした。 > buttonクリックなのですね。 > そうであれば、クリック後の最新ウインドを取得する以下ではどうですか。 > > 'ここまで略 > 'ログインボタンを選択、管理一覧ページへ移動 > Call tagClick(objIE, "button", "ログイン") > 'ここでobjIEを喪失していると想像 > Sleep 2000 '十分な待機時間(例えば2秒)を確保(APIのSleep関数) > Set objIE = 最新画面 '最新のオブジェクトを取得する > If objIE Is Nothing Then MsgBox "異常発生": Exit Sub '念のため > Call ieCheck(objIE) '念のため > For Each objLink In objIE.document.Links > '以下略 > > Function 最新画面() As Object > Dim objShell As Object, n As Long > Set objShell = CreateObject("Shell.Application") > For n = objShell.Windows.Count To 1 Step -1 '最新のウインドから探す > If TypeName(objShell.Windows(n - 1).document) = "HTMLDocument" Then > Set 最新画面 = objShell.Windows(n - 1) '最新のHTMLDocumentを取得 > Exit For > End If > Next n > 'Debug.Print 最新画面.document.Title > Set objShell = Nothing > End Function |
Message#5 2017年6月4日(日)10時27分 From: NMC | 返事 削除 変更 |
プログラムをよく見ると私の指摘は全くピント外れでした。 buttonクリックなのですね。 そうであれば、クリック後の最新ウインドを取得する以下ではどうですか。 'ここまで略 'ログインボタンを選択、管理一覧ページへ移動 Call tagClick(objIE, "button", "ログイン") 'ここでobjIEを喪失していると想像 Sleep 2000 '十分な待機時間(例えば2秒)を確保(APIのSleep関数) Set objIE = 最新画面 '最新のオブジェクトを取得する If objIE Is Nothing Then MsgBox "異常発生": Exit Sub '念のため Call ieCheck(objIE) '念のため For Each objLink In objIE.document.Links '以下略 Function 最新画面() As Object Dim objShell As Object, n As Long Set objShell = CreateObject("Shell.Application") For n = objShell.Windows.Count To 1 Step -1 '最新のウインドから探す If TypeName(objShell.Windows(n - 1).document) = "HTMLDocument" Then Set 最新画面 = objShell.Windows(n - 1) '最新のHTMLDocumentを取得 Exit For End If Next n 'Debug.Print 最新画面.document.Title Set objShell = Nothing End Function |
Message#4 2017年6月1日(木)09時37分 From: 初心者 | 返事 削除 変更 |
NMC様 早々にアドバイスいただき、ありがとうございます。 早速、ログインボタンを選択、管理一覧ページへ移動の前に、Call Link修正(objIE)を追加して実行してみましたが、結果は同じでした。 実は、ログインのところで以下の様に Call ieViewを入れログイン移動後のページを再度 表示させる文を入れると、同じページがもう1個開きますが何故か動作します。 'ログインボタンを選択、管理一覧ページへ移動 Call tagClick(objIE, "button", "ログイン") Call ieView(objIE, "情報管理ページURL") また、ログインボタンによるページ移動だけでなく、URLリンクによるページ移動も同様に Call ieView(objIE, "移動後のページURL")を追加しないと移動前のエレメントを読んでいる様で正常に動作しません。Call ieView(objIE, "移動後のページURL")を追加すると何故か動作しているようです。 この状況が解決の糸口になりませんでしょうか? 引続き、よろしくアドバイスお願いいたします。 NMCのメッセージ(#3)への返事 > 初心者のメッセージ(#1)への返事 > HTMLの<A>タグには、target属性があり、target="_blank"では別画面になるので、objIEがクリック後の別画面を取得できないのではないでしょうか。 > http://www.htmq.com/html/a.shtml > > そのような場合に備えて、私は、クリック前に、target="_blank"の全てを、Target = "_top"かTarget = "_self"に書き換えています。 > > Call Link修正(objIE)'★ > 'ログインボタンを選択、管理一覧ページへ移動 > Call tagClick(objIE, "button", "ログイン") > > ★追加では駄目ですか? > > Function Link修正(ByRef objIE As Object) > Dim objDoc As Object, i As Long, k As Long > Set objDoc = objIE.Document > For i = 0 To objDoc.Links.Length - 1 > 'Debug.Print i & "---" & objDoc.Links(i).href 'Target > If objDoc.Links(i).Target = "_blank" Then > objDoc.Links(i).Target = "_top" '"_self" > k = k + 1 > End If > Next i > Debug.Print k & "箇所のリンクを修正" > End Function |
Message#3 2017年5月31日(水)16時07分 From: NMC | 返事 削除 変更 |
初心者のメッセージ(#1)への返事 HTMLの<A>タグには、target属性があり、target="_blank"では別画面になるので、objIEがクリック後の別画面を取得できないのではないでしょうか。 http://www.htmq.com/html/a.shtml そのような場合に備えて、私は、クリック前に、target="_blank"の全てを、Target = "_top"かTarget = "_self"に書き換えています。 Call Link修正(objIE)'★ 'ログインボタンを選択、管理一覧ページへ移動 Call tagClick(objIE, "button", "ログイン") ★追加では駄目ですか? Function Link修正(ByRef objIE As Object) Dim objDoc As Object, i As Long, k As Long Set objDoc = objIE.Document For i = 0 To objDoc.Links.Length - 1 'Debug.Print i & "---" & objDoc.Links(i).href 'Target If objDoc.Links(i).Target = "_blank" Then objDoc.Links(i).Target = "_top" '"_self" k = k + 1 End If Next i Debug.Print k & "箇所のリンクを修正" End Function |
Message#2 2017年5月31日(水)16時05分 From: NMC | 返事 削除 変更 |
初心者のメッセージ(#1)への返事 操作ミスしました |
Message#1 2017年5月30日(火)13時57分 From: 初心者 | 返事 削除 変更 |
IE制御の初心者ですが、下記の通り基本的なところで困っています。 @ログインページからID、パスワードを入力し、ログインボタンをクリックして、”管理一覧ページ”へ移動 Aその後、”管理一覧ページ”にあるリンクURLをクリックし、”情報管理ページ”に移動 させたく、この”VBAのIE制御”で教えてもらったコードで以下の通り記述しています。 ところが、”管理一覧ページ”に表示が移動しているにも関わらず、”情報管理ページ”へのリンクURLを見つけられない。ステップモードで”管理一覧ページ”に表示が変わったあとにステップで進めたが、見つけられなかった。そのため、ここで全エレメントを読んでみたところ、表示が”管理一覧ページ”になっているにもかかわらず、エレメント自体は移動前の”ログインページ”のものだった。 ページ移動前に読み込んでいるのかとも疑ったが、 Call tagClickのサブルーチン内にWebページ完全読込待機処理サブルーチン「ieCheck」も入れてあるので、問題ないのではと考えています。 どうすれば移動後のエレメントが読めるのか、アドバイスをお願いします。出来れば修正するコード自体を具体的にお教えいただけると助かります。 よろしくお願いいたします。 ーーーー以下、コードーーーーーー Sub sample() 'メイン処理 Dim objIE As InternetExplorer Dim objLink As Object 'InternetExplorerでログインページを起動 Call ieView(objIE, "http://www.XXXXXXXX") '<---- ログインURL 'ログインIDをテキストボックスに入力 objIE.document.getElementsByName("login_id")(0).Value = "XXXX" '<---- ログインID 'パスワードボックスに値を入力 objIE.document.getElementsByName("login_pw")(0).Value = "XXXX” '<---- パスワード 'ログインボタンを選択、管理一覧ページへ移動 Call tagClick(objIE, "button", "ログイン") For Each objLink In objIE.document.Links If InStr(objLink.outerHTML, "情報管理") > 0 Then objLink.Click Call ieCheck(objIE) Exit For End If Next (このあとの処理省略) ーー以下、サブルーチンーーーーーーーーーーーーー '@指定URLを表示するサブルーチン「ieView」 Sub ieView(objIE As InternetExplorer, _ urlName As String, _ Optional viewFlg As Boolean = True) 'IE(InternetExplorer)のオブジェクトを作成する Set objIE = CreateObject("InternetExplorer.Application") 'IE(InternetExplorer)を表示・非表示 objIE.Visible = viewFlg '指定したURLのページを表示する objIE.navigate urlName 'IEが完全表示されるまで待機 Call ieCheck(objIE) End Sub ーーーーーーーーーーー 'AWebページ完全読込待機処理サブルーチン「ieCheck」 Sub ieCheck(objIE As InternetExplorer) Dim timeOut As Date timeOut = Now + TimeSerial(0, 0, 20) Do While objIE.Busy = True Or objIE.readyState <> 4 DoEvents If Now > timeOut Then objIE.Refresh timeOut = Now + TimeSerial(0, 0, 20) End If Loop timeOut = Now + TimeSerial(0, 0, 20) Do While objIE.document.readyState <> "complete" DoEvents If Now > timeOut Then objIE.Refresh timeOut = Now + TimeSerial(0, 0, 20) End If Loop End Sub ーーーーーーーーーーーーー Sub tagClick(objIE As InternetExplorer, _ tagName As String, _ tagStr As String) 'Bボタンクリックするサブルーチン Dim objTag As Object 'タグをクリック For Each objTag In objIE.document.getElementsByTagName(tagName) If InStr(objTag.outerHTML, tagStr) > 0 Then objTag.Click Call ieCheck(objIE) Exit For End If Next End Sub |
昨日以降 2日前以降 3日前以降 4日前以降 5日前以降