【エクセルVBAでIE操作】ブラウザの読み込み待ちをしないとダメなのです


待つ犬

みなさん、こんにちは!
テンポよくブログ更新していますタカハシ(@ntakahashi0505)です。

初心者向けエクセルVBAでIEを操作するシリーズの第3回目です。

前回はこちらの記事で

【エクセルVBAでIE操作】HTMLタグと要素そしてドキュメントの取得
初心者向けエクセルVBAでIEを操作するシリーズの第2回目です。今回はHTMLタグと要素について簡単に説明をしつつIEで開いたページのHTMLドキュメントを取得する方法についてお伝えします。

HTMLタグと要素についての説明とHTMLドキュメントの取得についてのお話をしました。

ですが、実際に動かしてみたらエラーが出た…という明らかに中途半端なところで終わらしてしまってごめんなさい。

今回はIEの読み込み待ちの処理を入れることで、そのエラーをバッチリ解決していきますよ。

この処理はVBAでIEを扱う限りはほとんどの場合で必要となる処理ですので、ぜひ覚えて頂ければと思います。

前回のおさらい

前回のプログラムはこちらでした。

HTMLドキュメントを格納するhtmlDocというオブジェクト変数を用意して、IEで開いたJR東日本さんのサイトのトップページのHTMLドキュメントをセット。

そして取得したHTMLドキュメントのTitleつまりWEBページのタイトルをイミディエイトウィンドウに表示する、という内容でした。

しかし、実行してみると

オートメーションエラー

こんなエラー画面が出てしまいました。

特定できません、って…

でも安心して下さい。原因はわかっています。

HTMLドキュメントの取得の際に発生するエラーの原因

このエラーの原因を解明していきます。

まずこの命令でIEが指定したURLのページを読み込んでくるのですが、どんなに通信環境がよいところでも少し読み込むまでに時間がかかりますよね?

IEは一生懸命読み込みをしているのですが、VBAはお構いなしに次の命令を実行しに行ってしまいます。

先ほどのエラー画面で「デバッグ」をクリックしてみると

エラーの発生箇所

この黄色の箇所でエラーになっていることがわかります。

ここですね。

何が問題かと言いますとIEがページを読み込み切っていないところで、そのHTMLドキュメントを取得しにいっているのでエラーになっているのです。

要は「存在していないHTMLドキュメントをセットしろ」という命令をしてしまっているということなんです。

無いものはセットできないよ~、てなわけです。

これを避けるために、IEが読み込みが完了したことを確認してから次の処理に移るようにするという対策をとります。

IEブラウザの読み込み待ちの処理

IEのページ読み込みが完了することを待つ処理はこのように書きます。

条件が2つありまして、このどちらかの条件が満たされている間はDoEventsをして、という処理です。

それぞれ説明をしていきますね。

BusyでIEが忙しいかどうかを判断

IEオブジェクト.Busy

BusyはIEオブジェクトが忙しければTrue、そうでなければFalseを返します。

忙しいですか?と聞いて、忙しいよと回答されている間はDoEventsすることになります。一生懸命読み込みをしている間は当然Busyになっているということですね。

readyStateでIEが準備完了かどうかを判断

IEオブジェクト.readyState < READYSTATE_COMPLETE

readyStateはIEオブジェクトの準備状態を数値で返します。準備完了を表す数値は4で、準備が完了していない間は4未満の数値が返ります。

一方でREADYSTATE_COMPLETEはなんだか難しく見えますが、ただの定数で4を表しています。

ですから、IEの準備状態が完了つまり4になるまでDoEventsをするということになります。

DoEventsでOSに処理を渡す

DoEventsはOSに処理を渡す命令です。

は?って感じですが、少し説明をしますね。

VBAはループ処理をしている間は、OSにすら処理を渡さずに一生懸命ループをします。つまり他のアプリケーションなどがループが終わるまで全て待ち状態になります。

DoEvents

この命令があるタイミングでVBAは一旦OSに対して「待ってる処理ある?」とお伺いを立てにいき、OSの処理を優先してあげるという行動を取ります。

これがないとブラウザでページが表示されるまでの間、画面が固まったような状態になってしまいますので、このDoEventsを入れているということです。

この説明をさらに詳しく知りたい場合はこちらの記事もご覧頂ければと思います。

ゼロからはじめるVBA - その他の関数編 (1) システムで待っている処理を行うため
今回説明する組み込み関数は数値関数、文字列関数、日付関数以外でよく使用される関数です。ループ処理中にシステムで待っている処理を行うための関数(DoEvents)、いままでの例題でよく使用していたデータ表示関数(MsgBox)、セル操作で使用される関数をVBAで使用する方法などについて説明したいと思います。

IEの読み込み待ち処理を入れて実行

以上、IEの読み込み待ち処理について説明をしてきましたが、これを応用してあれこれやることはあまりないと思いますので、このDo~Loopに関してはnavigateでURLでページを開く処理の次に定型で入れたらよいです。

読み込み待ちを入れたプログラムはこちらです。

これを実行すると、イミディエイトウィンドウには

HTMLドキュメントのタイトルを表示

と表示されます。

バッチリですね!

まとめ

このようにエクセルVBAでIEを操作する際には、IEがちゃんと読み込み完了からHTMLドキュメントを取得する必要があります。

これはほとんどの場合で必要になりますので、定型文的にいつも入れるようにするのが良いです。

さて、次回以降いよいよ本格的に取得したHTMLドキュメントから色々な情報を抽出していく方法についてお伝えしていきますね。

まず手始めに、こちらの記事でページ内のリンク先URLをゴソっと取得する方法です。

【エクセルVBAでIE操作】ページ内のリンク先URLを全部取得する
初心者向けエクセルVBAでIEを操作するシリーズの第4回目です。今回はLinksとFor Each~Nextという繰り返し処理を用いてページ内のリンク先URLを全て取得する方法についてお伝えします。

合わせてご覧くださいね!

連載目次:エクセルVBAでIEを操作してWEBスクレイピング

IEを操作してWEBページのデータを取得して、エクセルのデータとして取り込む、つまりWEBスクレイピングをエクセルVBAで実現します。各種WEBページを課題として様々なデータの取得の仕方を解説していきたいと思います。
  1. 【エクセルVBAでIE操作】10分で終わるセッティングとWEBページの閲覧確認
  2. 【エクセルVBAでIE操作】HTMLタグと要素そしてドキュメントの取得
  3. 【エクセルVBAでIE操作】ブラウザの読み込み待ちをしないとダメなのです
  4. 【エクセルVBAでIE操作】ページ内のリンク先URLを全部取得する
  5. 【エクセルVBAでIE操作】ディスクリプションなどの要素をname属性でGetする
  6. 【エクセルVBAでIE操作】hタグなどの要素をタグ名でGetする
  7. 【エクセルVBAでIE操作】WEBページのテーブル要素を自動で取得する方法
  8. 【エクセルVBAでIE操作】IEで検索窓にキーワードを入力して送信する方法
  9. 【エクセルVBAでIE操作】ページをクロールしてブログの記事一覧を取得する方法
  10. 【エクセルVBAでIE操作】ブログの記事一覧ページから公開日とカテゴリを取得する
  11. 【エクセルVBAでIE操作】ページャーを最後のページまでどんどんリンクする
  12. 【エクセルVBAでIE操作】ユーザー名とパスワードを入力してログインをする

連載目次:データ一覧から請求書を自動で作る

お仕事において特定のデータ一覧から必要な情報を抽出するということは頻繁にありうると思います。ここではデータ一覧から請求書を作るということを目標に、実務で使えるスキルをまっすぐに身に着けることを目的としています。
  1. 【初心者向けエクセルVBA】データ一覧から請求書を自動で作る
  2. 【初心者向けエクセルVBA】ワークシートをオブジェクト名で取り扱う方法
  3. 【初心者向けエクセルVBA】For~Next文で簡潔にプログラムを書く
  4. 【初心者向けエクセルVBA】行の数をカウントする&不要な行を隠す
  5. 【初心者向けエクセルVBA】文字列の連結&Format関数での書式変更
  6. 【初心者向けエクセルVBA】セル範囲を一気にまとめてコピーする方法
  7. 【初心者向けエクセルVBA】ワークシートのデータのある範囲だけをピッタリ取得する方法
  8. 【初心者向けエクセルVBA】セル範囲の平行移動をする方法・リサイズをする方法
  9. 【初心者向けエクセルVBA】日付データから年・月・日を取り出す
  10. 【初心者向けエクセルVBA】If~Thenを使った条件分岐の超入門
  11. 【初心者向けエクセルVBA】For~Next文でセル範囲を一行ずつ移動させる
  12. 【初心者向けエクセルVBA】セル範囲のクリア~ClearContentsメソッドとClearメソッド
  13. 【初心者向けエクセルVBA】ワークシート・セルを選択する方法の色々について
  14. 【初心者向けエクセルVBA】入力ダイアログを表示するInputBoxメソッドの使い方
  15. 【初心者向けエクセルVBA】日付データから月末日と翌月末日を自動算出する
  16. 【初心者向けエクセルVBA】ワークシートをコピーする方法とそのシート名を変更する方法
  17. 【初心者向けエクセルVBA】オブジェクトを変数にセットして取り扱う方法
  18. 【初心者向けエクセルVBA】Openメソッドで新たなブックを開く方法
  19. 【初心者向けエクセルVBA】現在マクロを書いているブックのフォルダパスを取得する
  20. 【初心者向けエクセルVBA】開いたブックとそのワークシートをオブジェクト変数にセットする
  21. 【初心者向けエクセルVBA】ワークブックを別名で保存して閉じる方法
  22. 【初心者向けエクセルVBA】取引先別に請求書を作成するマクロを作る

The following two tabs change content below.
株式会社プランノーツ代表、コミュニティ「ノンプロ研」主宰。1976年こどもの日生まれ。東京板橋区在住。「ITで日本の『働く』の価値を上げる!」をテーマに、VBA&GASの開発、講師、執筆などをしております。→詳しいプロフィールはコチラ ★ご依頼・ご相談はお気軽にどうぞ!→お問い合わせはコチラ ★フォロー頂ければ嬉しいです。

コメント

  1. ryo より:

    実務でEXCELVBAからIEを操作する開発をやっている者です。私は当初IEの読み込みをいかに完全に待つことができるのか、方法を見つけ出すのに本当に苦労しました。いろんなサイトで紹介されている方法でもうまくいかず、もういくつか追加する必要があることに気づきました。

    まずは、objIE.Documentの読み込みが完了しているか、そしてさらにobjIE内の全要素数が数秒後の要素数と同じになるのか、までチェックしないと私の経験上では順調に次の処理に進むことができませんでした。

    しかしこれでも常時正常に動くかは不安です。API Sleepも使いつつなんとか動かすことができている状況です。

    以上、情報共有でした。

    • ryoさん

      コメントありがとうございます!
      参考になります!

      objIE内の全要素数が数秒後の要素数と同じになるのか

      なるほどですね…うまく動作しないときには、この方法も有効ですね。活用させていただきますね!