[[20121219153357]] 『vbaで操作』(あや) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『vbaで操作』(あや)

 XP Excel2003 IE6 

 vbaでweb操作をしております。

 人が作ったWebページに
 vbaから検索文字を入力し
 検索ボタンを押して
 結果を出すようにしております。

 検索ボタンを押した直後、画面がついてきていないので

 Do While ObjIE.readystate <> 4
   Do While ObjIE.Busy = True
   Loop
 Loop
 を入れて、待っています。

 これで待つのは待てておりますが、
 検索後の結果のページにあるリンクが、
 クリック出来ない状態になるときがあります。

   クリック出来ない状態は…
   青字に下線にはなっているのですが、
   マウスを持っていくと『I』になってテキストに合わせるのと
   同じ状態。
   クリックしても反応なし、です。

 コードはこんな感じです(省略してる部分はあります)
 ----------------------------------------------------
  StrCODE = Range("B3")

 '検索ボタンを押す
  ObjIE.navigate "javascript:clickSearchBtn(**********);"

  '待つ
   Do While ObjIE.readystate <> 4
       Do While ObjIE.Busy = True
       Loop
   Loop

    '検索後結果画面のコードをクリック
    For Each Obj In ObjIE.Document.getElementsByTagName("a")
        If Obj.innertext = StrCODE  Then
            Obj.Click
            Exit For
        End If
    Next
 -------------------------------------------------------

 重めのページなんで、リンク先まで読み込むのが待てずに
 Loopが抜けている感じなのかな?とか思うのですが
 ほとんど知識がないので、予想もあやふやです…

 1行デバッグで進めていくと、必要なリンクにたどり着けています。

 しかし、最後まで一気にすると、上記の『I』になってWeb画面が途中で止まります。

 説明不足かとは思いますが、何か教えて頂けると助かります。


 ReadyState がComplete(4)でも Busy が True の状態がありえるので
    Do While ObjIE.readystate <> 4 Or ObjIE.Busy = True
       DoEvents
    Loop
 のようにしてどうでしょうか。
 それでもうまくいかない場合は(ありえるので)、より細かい条件判定が必要に
 なるかと思います。
http://d.hatena.ne.jp/language_and_engineering/20100410/p1
 (Mook)


 Mookさんありがとうございます。

 教えて頂いた
 Do While ObjIE.readystate <> 4 Or ObjIE.Busy = True
      DoEvents
  Loop
 でも画面更新が待てていませんでした。

 URLを見て、前提知識のところを読ませてもらったのですが
 (まだあやふやな感じです)
 WSHの使える環境が必要なのかな?といったことに気がついたところです。

 WSHがダウンロードできない環境のため
 手詰まりになってしまいました…

 ほおり投げるつもりはないのですが、
 ひとまずの現状報告にさせてもらいます。

 新しい知識を調べながらなのもあって
 いろいろ質問が変化してまうかとは思いますが
 またなにかご助言いただければ助かります。

 (あや)


 WSH といっているのは Windows の VBS/JScript のことで XP 以降であれば標準で
 使用できます。

 VBS は文法的には VBA と同じく VB ですが、メモ帳などで作成できるテキスト
 ファイルです。
 VBSはマクロでもほぼ(例外はあり)そのまま利用できますが、例示のサイトの
 例は JScript(ほぼ JavaScript)で記載されているので、文法を VB に変更して
 あげる必要があります。

 今回対象となっている WebSite はフレームを利用しているのでしょうか。
 まじめにやるといろいろ対策が必要ですが、端折ってステータス監視の後に
 3秒(フレームの中がこの時間内に読み込み完了するならば)くらいの Sleep
 を置いたらどうでしょうか。
 (Mook)

 '// 標準モジュールの先頭に追記
 Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
     :
 Sub Sample()
     :
    Do While ObjIE.readystate <> 4 Or ObjIE.Busy = True
        DoEvents
    Loop
    Sleep 3000 '// 時間は調整してください。 1000(ms) = 1 秒
     :
 End Sub


 まともな回答でなくてすみませんが、

 (1) 手で検索操作した場合、平均何秒くらいで読み込みが完了するのでしょうか?
    その秒数は、強制的にSleepかなんかで待ったみたら如何ですか?(その後、チェック用ループに突入する)
  
 (2)ループを抜けるのが早すぎた場合、ここの部分に来る訳ですが、

 >    For Each Obj In ObjIE.Document.getElementsByTagName("a")
 >        If Obj.innertext = StrCODE  Then
 >            Obj.Click
 >            Exit For
 >        End If
 >    Next
 >

 ここで、If文の条件がTrueになることがあるのでしょうか?
 もしならないのなら、もう一度チェック用ループに戻るように塩梅したら如何ですか?
 (それでも上手く行かず、無限ループになると厄介なので、TIMEOUTする条件は入れた方がいいと思いますけど)

 (半平太) 2012/12/20(Thu) 12:31

 Mookさん 半平太さん
 ありがとうございます

 >今回対象となっている WebSite はフレームを利用しているのでしょうか。
 フレームは使ってないのです

 WSHについてもっと勉強したいのですが、今後の課題として
 ひとまず。

 検索ボタン後
 Msgboxを出して
 画面更新の確認ができたら、
 OKを押して進めるといった方法で
 流れを作っていましたが…
 なんか不満な感じで…^^;

 画面更新に10秒〜20秒ほどかかったりするので
 20秒 Sleepも試したのですが、
 確実ではないのと、遅すぎるので…

 とかなんとか試行錯誤していて、
 旧ページに無くて、新ページにあるリンク先の文字を
 指定してあるか無いかで判断してみる

 Label検索結果待ち:
        If ObjIE.Document.Links(9).outerText <> "検索後ページ" Then
            Sleep 1000
            GoTo Label検索結果待ち
        End If

 という、怒られそうなGotoを使って
 必要な動きが得られました。

 とりあえずいいかなぁ………
 もし検索後ページという文字が無かった場合、
 エラー処理をしないといけませんね。

 ひとまずの報告とさせて頂きます。
 また教えてくださいm(_ _)m

 (あや)

 解決済みですので蛇足ですが、

 試行錯誤して動くようになったというのはそれはそれで、素晴らしいことなのですが
 中身を把握できずに終わってしまうというのが、ちょっと危うい感じがしました。

 断片的な上記の記述だけを見ると
 ObjIE.Document.Links(9).outerText
 は必ずしも目的の場所を特定するのに十分な記述方法ではなさそうです。

 想定するページが恒久的に変わらないとしても、後からこの変更をしようとした
 他の人には、何をしているかわからないコードですよね。
 それを心配する必要がないとしても、「1年後のコードは他人のコード」というのが
 私の信条です(最近は1年どころか1か月後ですが・・・)。

 期待する位置を明確に特定する指定のしかた、というのを修得されると Web の制御
 は幅が広がりますし、イメージしやすくなると思います。
 (Mook)

[[20121108090727]]

 この質問でWebBrawserを使ったコードを提示しました。結果、質問者の意図したコードではなかったのですが、
 この時のコードをIEに置き換えると、

 新規ブックにて、

 参照設定で「Microsoft Internet Controls」にチェックを入れます

 Thisworkbookのモジュールに

 '============================================================================
 Option Explicit
 Private Declare Function ShowWindow Lib "user32" (ByVal hwindow As Long, ByVal cmdshow As Long) As Long
 Private WithEvents ie As InternetExplorer
 Public 表示住所 As Variant
 Private evcnt As Long
 '============================================================================
 Sub map_disp()
    Dim idoc As Object
    Dim ele As Object
    Set ie = CreateObject("InternetExplorer.Application")
    With ie
       ShowWindow .Hwnd, 3
       .Visible = True
       .Navigate "http://www.google.co.jp/maps?ie=UTF-8&oe=UTF-8&hl=ja&tab=wl&q="
       Do While .Busy = True Or .readyState <> 4
          DoEvents
          Loop
       Set idoc = .Document
       On Error Resume Next
       With idoc
          .forms(0).all("q").Value = 表示住所
          .forms(0).all("q-sub").Click
          evcnt = 0
          Do While evcnt <= 6
             DoEvents
          Loop
          For Each ele In .getElementsByTagName("IMG")
             If ele.classname = "collapse-left3" Then
                ele.Click
                Exit For
             End If
          Next
       End With
       Set idoc = Nothing
       Set ie = Nothing
       On Error GoTo 0
    End With
 End Sub
 '============================================================================
 Private Sub ie_DocumentComplete(ByVal pDisp As Object, URL As Variant)
   evcnt = evcnt + 1
 End Sub
 '============================================================================
 Private Sub ie_DownloadComplete()
   evcnt = evcnt + 1
 End Sub

 標準モジュールに

 '==============================================================================
  Sub test()
    With ThisWorkbook
       .表示住所 = "東京都墨田区押上1"
       .map_disp
    End With
 End Sub

 上記のコードは、GoogleMAPを表示し、指定住所(ここでは、「東京都墨田区押上1」)
 の地図を表示後、パネルを隠すボタンをクリックして、地図を横いっぱいに表示する

 という操作を行っていますが、この パネルを隠すボタンが地図表示後、

 Do While .Busy = True Or .readyState <> 4
    DoEvents
 Loop

 上記のコードで待機しただけでは、ボタンクリックが出来ませんでした。

 そこで、DocumentCompleteイベントとDownloadCompleteイベントの発生回数を調べて
 イベント発生回数6を実験結果(何回か試行した結果6回発生後だとパネルを隠すボタンが有効になった)から
 求めて、発生回数になるまでループさせた例です。

 何かの参考になれば、幸いです

 ichinose@今日は、クリスマス♪


 Mookさんいつもご丁寧にありがとうございます。

 期待する位置を明確に特定する指定のしかた
 となりますと、仰ったWSHになってくるのでしょうか。

 私の打開策は、後から見てどうか、
 Webページ の変更があった場合どうか、といった場面もしかり
 今後の考え方にも
 ぜんぜんいい記述ではない感じはしています +д+

 また質問させてもらうと思いますので
 教えていただけると助かります。

 ichinoseさん、新しい知識をありがとうございます。
 WebBrawserってなんだろう?といったところから入ります

 落ち着いて調べていきたいと思います。
 また教えてください。

 (あや)

コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.