[三流君] −−> [プログラマー業務の愚痴] −−> [バックナンバー一覧]
−−> No.205 負荷テストの重要性 IEのOpen Closeを繰り返すと落ちる

負荷テストの重要性 IEのOpen Closeを繰り返すと落ちる

負荷テストをしないで、サンプルが完成した・・・と、読者に渡したら、
読者様の環境で動かないでエラーが発生、そんな負荷テストは重要ですよ・・なんてお話です。



本文(発行内容)

ここから、本文です。軽く読み流してくださいね・・・

バグの連絡を読者様よりいただく

VBAでIEを操作して、リンクを取り出す、そんなサンプルを作成して、読者へ送りました。
成果物: IE操作 リンク取りだし処理。競馬の結果ページのURLを取り出したい
すると、下記の返信(結果)がメールで送られてきた。

>実行してみました
>1. 年,月 ボタン 入力入りはうまくいきましたが
>
>2. 2006〜2009のボタンのほうは、エラーになります
>  実行エラー 424
>  オブジェクトが必要です
>
>'IEの起動
>    Dim objIE As Object '変数を定義します。
>    Set objIE = CreateObject("InternetExplorer.Application") 'オブジェクトを
>作成します。
>>Set objIE = CreateObject("InternetExplorer.Application")
>このところで止まっています 

状況確認

途中で止まってしまう、、、って、ことで、まずは状況確認、エラーを出してみます。※負荷テストしてみます。
IEを開いて閉じて、を単純に
CreateObject("InternetExplorer.Application") と .Quit 繰り返しているから メモリの解放やタイミングかなぁ?
負荷テストを行わないで、自分の贅沢な環境で動いたから、、、
or テストプログラムは小さくて、実データが付いていないから、たまたま動いた、
そんな感じだと予想して、
1.他のアプリれーション、メールソフトなどを立ち上げて、実際の操作に近い状況を作る。
2.だけだとつまらないので、さらに高負荷のメディアプレーヤーなど動画の再生ソフトも起動。
この状態で、作成したVBAのプログラムを走らせ、動作確認をしてみます。
※負荷をかけてチェックってヤツですね。。。

不可チェックの動画のリンク001: http://www.youtube.com/watch?v=79yN1DHx8R8

すると、IE操作処理が オートメーションエラーで止まってしまいました。
自分のPC上、贅沢な環境でも再現できました。。。

対策を立てる、プログラムを修正する

私のPCでは動くのに、自分の環境では動くのに、会社では動くのに、、
悪いのはアナタのPCだ、悪いのは客先のPCだ、
と、念仏のように100回唱えても事態は好転しないので、負荷をかけない作りへ変更します。
※環境のせいにしちゃイケナイよねぇ、、、
※※よく聞く言葉で、私のPCでは動きます、そちらの環境が悪いのでは?なんて会話してないですか?
※※※まぁ、実際に環境の違い、、ってこともあるんだけど、クリーンな贅沢なPC上でしたか動作しないプログラムを作った私にも今回は責任があるのかなぁ、、、また、サンプルプログラムは小さいので動いたけど、実際の大規模なデータ処理に組み込んだら突然動かなくなった、そんな結合後の不具合があったりするのも事実だけど。。。

そんな、環境話は置いといて、現状のプログラムがOPEN Closeを繰り返す、下記のような作りになってます。
メインルーチンから子供のサブルーチンを呼んで処理を繰り返す(年月を渡す)
--子サブルーチンでは、年月を受け取り、IEを開きリンクを探し、探したリンクを孫サブルーチンに渡す、IEを閉じる
----孫サブルーチンでは、URLを受け取り、別のIE 2個目を開き、リンク抜き出し処理をする、別のIE 2個目を閉じる
そんな作りになってます。って書くよりも、ソースを見た方がハヤイよね。
百聞は一見に〜

詳細は抜いてありますが、こんな感じの1つのメイン、2つのサブルーチンです。
メインルーチン
Sub main_all()

    Dim mm As Integer

    '2006年
    For mm = 1 To 12
        Call yyyy_mm(2006, mm)  '月別の取得関数
    Next mm
    
    '2007年
    For mm = 1 To 12
        Call yyyy_mm(2007, mm)  '月別の取得関数
    Next mm
    
    '2008年
    For mm = 1 To 12
        Call yyyy_mm(2008, mm)  '月別の取得関数
    Next mm

    '2009年
    For mm = 1 To 12
        Call yyyy_mm(2009, mm)  '月別の取得関数
    Next mm

End Sub

子サブルーチン'年と月を受け取り、開催日・場所単位で処理する。
Sub yyyy_mm(yyyy As Integer, mm As Integer)

'IEの起動※と、ここで開き、
    Dim objIE As Object '変数を定義します。
    Set objIE = CreateObject("InternetExplorer.Application") 'オブジェクトを作成します。
    objIE.Visible = True      '可視、Trueで見えるようにします。

'リンク情報を取り出すとなんだかんだ処理して、
    Dim i As Integer  'ループの変数
    For i = 0 To objIE.Document.Links.Length - 1
        'なんだかんだ処理して、開催日のページを渡す。※孫ルーチンを呼ぶ
        Call get_racelist(objIE.Document.Links(i).Href) 'リンク先
    Next i

'IEを閉じる閉じます。
    objIE.Quit
    Set objIE = Nothing

End Sub

孫サブルーチンここでも、サブルーチンないでIEを開いて、閉じてます。
'開催日のURLを受け取り 例)http://keiba.yahoo.co.jp/scores/2009/01/01/05/racelist.html '1R-12RまでのURLを セルに書き出す
Sub get_racelist(strURL As String)

'IEの起動
    Dim objIE As Object
    Set objIE = CreateObject("InternetExplorer.Application") 'オブジェクトを作成します。
    objIE.Visible = True      '可視、Trueで見えるようにします。

'IEを開いて、なんだかんだ処理して、IEを閉じる。。。

'IEを閉じる
    objIE.Quit
    Set objIE = Nothing

End Sub

上記処理だと、IEの作成(OPEN) CreateObject と IEの破棄.Quit(Close)を繰り返すので、
対策として、単純に、OPENをメイン処理で1回、CLOSEをメイン処理で1回、呼ぶ、

メインルーチンでから使用するIEを2つ開いてから、子供のサブルーチンを呼んで処理を繰り返す(年月を渡す)
--子サブルーチンでは、年月を受け取り、既に開かれたIEを使い、処理を行ない孫サブルーチンに渡す
----孫サブルーチンでは、URLを受け取り、開かれた2個目のIEを使い、リンク抜き出し処理をする、
戻ったメインルーチンで使用済みのIE2つを閉じる。
そんな単純な逃げ方に変更してみました。

試行錯誤の動画002: http://www.youtube.com/watch?v=GfJdM77MYGs

で、完成したのが、こんな感じです。
Option Explicit

Dim SET_YLINE As Integer 'グローバル変数に行数を保存
Dim objIE2 As Object
Dim objIE As Object

Sub main_all()

    'シート6を選択
    Sheets("Sheet6").Select
    Range("A1").Select

    SET_YLINE = 2  'A2から書きたいので、グローバル変数を初期化
    
    Call ie_open
    
    Dim mm As Integer
    
    '2006年
    For mm = 1 To 12
        Call yyyy_mm(2006, mm)  '月別の取得関数
    Next mm
    
    '2007年
    For mm = 1 To 12
        Call yyyy_mm(2007, mm)  '月別の取得関数
    Next mm
    
    '2008年
    For mm = 1 To 12
        Call yyyy_mm(2008, mm)  '月別の取得関数
    Next mm

    '2009年
    For mm = 1 To 12
        Call yyyy_mm(2009, mm)  '月別の取得関数
    Next mm

    ie_close

End Sub

Sub main_tan()

    Dim strYYYY As String
    Dim strMM As String
    
    Dim mm As Integer
    Dim yyyy As Integer

    '入力
    strYYYY = InputBox("調べたい年を西暦で入力", "年", "2009")
    strMM = InputBox("調べたい月を1-12で入力", "月", "1")
    
    '数値変換
    yyyy = CInt(strYYYY)
    mm = CInt(strMM)

    'シート6を選択
    Sheets("Sheet6").Select
    Range("A1").Select

    Call ie_open

    SET_YLINE = 2  'A2から書きたいので、グローバル変数を初期化
    Call yyyy_mm(2009, mm)  '月別の取得関数

    Call ie_close

End Sub

'年と月を受け取り、開催日・場所単位で処理する。
Sub yyyy_mm(yyyy As Integer, mm As Integer)

    Dim strURL As String    '受け取った引数からURLを作成
    '例)http://keiba.yahoo.co.jp/schedule/2009/08/
    strURL = "http://keiba.yahoo.co.jp/schedule/" & yyyy & "/" & Right("0" & mm, 2) & "/"
    

'処理したいページを表示します。
    objIE.Navigate strURL  '.Navigate メソッドで競馬の開催日を表示する。

'ページの表示完了を待ちます。
    While objIE.ReadyState <> 4 Or objIE.Busy = True '.ReadyState <> 4の間まわる。
        DoEvents  '重いので嫌いな人居るけど。
    Wend

'リンク情報を取り出す
    Dim i As Integer  'ループの変数
    For i = 0 To objIE.Document.Links.Length - 1
        If Right(objIE.Document.Links(i).InnerText, 1) = "日" Then
            '開催日のページを渡す。
            Cells(SET_YLINE, "B") = objIE.Document.Links(i).InnerText
            Call get_racelist(objIE.Document.Links(i).Href) 'リンク先
            Debug.Print objIE.Document.Links(i).InnerText '内側のテキスト
        End If
    Next i

End Sub

'開催日のURLを受け取り 例)http://keiba.yahoo.co.jp/scores/2009/01/01/05/racelist.html '1R-12RまでのURLを セルに書き出す
Sub get_racelist(strURL As String)


'処理したいページを表示します。
    Dim strWORK As String '変数を定義します。
    strWORK = Replace(strURL, "racelist.html", "") '後ろのURLをカット
    strWORK = strWORK & "01/result.html" 'これで1RのURL作成
    '↑作った1Rを書き込む
    Cells(SET_YLINE, "A") = strWORK  '結果を書き込む
    SET_YLINE = SET_YLINE + 1

    objIE2.Navigate strWORK  '.Navigate メソッドで1Rに飛ぶ
    DoEvents

'ページの表示完了を待ちます。
    While objIE2.ReadyState <> 4 Or objIE2.Busy = True '.ReadyState <> 4の間まわる。
        DoEvents  '重いので嫌いな人居るけど。
    Wend

'リンク情報を取り出す
    Dim i As Integer  'ループの変数
    For i = 0 To objIE2.Document.Links.Length - 1
        If Right(objIE2.Document.Links(i).InnerText, 1) = "R" Then
            '結果の書き込み
            Cells(SET_YLINE, "A") = objIE2.Document.Links(i).Href   '結果を書き込む
            Cells(SET_YLINE, "B") = objIE2.Document.Links(i).InnerText
            SET_YLINE = SET_YLINE + 1
            Debug.Print objIE2.Document.Links(i).Href      'リンク先
        End If
    Next i



End Sub

Sub ie_open()

'IE1の起動
    Set objIE = CreateObject("InternetExplorer.Application") 'オブジェクトを作成します。
    objIE.Visible = True      '可視、Trueで見えるようにします。
    DoEvents
    
'表示位置(左上の座標)とサイズ(高さ・幅)を調整する
    objIE.FullScreen = False '※Trueのモードだとびっくりするよ
    objIE.Top = 100      '左上 上位置
    objIE.Left = 100     '左上 左位置
    objIE.Width = 800    '横幅
    objIE.Height = 600   '高さ
    DoEvents

'IE2の起動
    Set objIE2 = CreateObject("InternetExplorer.Application") 'オブジェクトを作成します。
    objIE2.Visible = True      '可視、Trueで見えるようにします。
    DoEvents
    
'表示位置(左上の座標)とサイズ(高さ・幅)を調整する
    objIE2.FullScreen = False '※Trueのモードだとびっくりするよ
    objIE2.Top = 150      '左上 上位置
    objIE2.Left = 150     '左上 左位置
    objIE2.Width = 800    '横幅
    objIE2.Height = 600   '高さ
    DoEvents

End Sub

Sub ie_close()

'IEを閉じる
    objIE.Quit
    DoEvents
    Set objIE = Nothing
    DoEvents
    
    objIE2.Quit
    DoEvents
    Set objIE2 = Nothing
    DoEvents

End Sub

負荷テストを行う、実行結果

プログラムの修正が終わったので、再び負荷をかけでテストしたのが、
下記の動画、負荷テストの実行結果です、、、と言っても最後まで、動画が撮れなかったけど。。。
途中、間を持たせるのに苦労したり、独り言で負荷テストについて語ってます。
ヒマだったら、見て、笑ってください。

リンク動画003: http://www.youtube.com/watch?v=5AmloDJbQ5Y


※途中、三流君の父親も登場するよ(笑)、貧乏酒屋のクーラーボックスが無くなった、そんなお話です。
※※で、最後はバッテリー切れで途中で動画が終了します・・・

終わりの挨拶

今回は、負荷テスト、そんな お話でした。
システムの負荷テストの話も面白いけど、人の人間力の負荷テストって話もあるよね。
人も自分の会社ではうまく行くのに、外に出向、他の会社で作業するとうまくいかない、、、
環境が変わり、負荷がかかるとうまく行かない、そんな場合が多かったりしますよね。
なかなか、人間の負荷ってのも難しいね、と、話を脱線させたところで、今回も逃げるようにサヨナラです。。。

※私、負荷に弱いですよ(外で負荷がかかった作業するとダメですねぇ・・・)
※※負荷を軽減してくれる できる社内の後輩に作業を頼めた頃がナツカシイデスネ、、、
※※※在宅一人は大変ですね。プログラム作成以外の負荷、特にお金がからんだ交渉事はニガテで、精神的負荷が多いですね。会社員時代は営業部門が見積もり交渉や相手からの値引き交渉などをしてもらってたので客先から圧力を感じなかったけど、一人個人事業主だと当たり前のように価格交渉圧力を自分で処理しないとイケナイし追加料金の交渉して相手からお金を引き出したり、プログラム・システム作成以外の負荷がかなりかかりますね。



ページフッター

ここまで、読んでいただきどうもです。ここから下は、三流君宛のメッセージ送信や 三流君のホームページの紹介・案内です
目的の情報が見つかったか?少々心配しつつ、、、※質問や感想は、気軽に送ってくださいね。

質問や要望など メッセージを送る(三流君に連絡する)

質問や要望など連絡方法でお互い確認が取りやすく、便利なのが掲示板なのですが、私の対応のまずさから不定期で荒れてしまい、掲示板は現在封鎖中です。(反省しなきゃ)
感想や質問・要望・苦情など 三流君へメッセージを送る。
時間的余裕のある要望・質問・苦情の場合は、下記のフォームからメッセージを送ることができます。
あなたのお名前(ニックネーム):さん
返信は?: 不用(HP更新を待つ) , E-mail→ アドレス:に返事をもらいたい



(感想や質問・要望 メッセージはHPで記事に載せることがあります。)


急ぎで連絡がほしい、そんな時は:[三流君連絡先アドレス]を見て連絡してください。

リンクや広告など

項目別に↓に本音?それとも建て前?的な記事をまとめました。お探しのジャンルを選択してください。
[ルーキー rookies]・・・ 新人さん達 初心者さんへ
[学ぶ study]・・・学習、技術の取得
[仕様書 doc]・・・仕様書・設計書関係の話
[共同作業 team]・・・チーム、グループ作業
[プログラムは心? spirit]・・・プログラマー 心・気質・魂

[掲示板デビューしようぜ bbs]・・・掲示板関係の話、質問者・回答者の気持ちほか
[昔はできた seo]・・・三流式の効果無しSEOとアフィリエイト
[仕事や作業、転職 job]・・・仕事や転職、評価、作業など
[その他 etc]・・・その他 分類外の記事

※↑文章の味付けが変わっていて、お口に合うかわかりませんが。。。
※※読んで、気分を悪くされたらスミマセン。

Blogとリンク:[三流君の作業日記]/ [愚痴(Bookmark)]/ [広告Blog(Bookmark)]



[三流君(TOP ken3.org へ戻る)] / [プログラマー業務の愚痴] / [バックナンバー 一覧]