[三流君] −−> [VBAで楽しく] −−> [バックナンバー一覧]
−−> No.072 オブジェクトのループはFor Each In でループさせる

オブジェクトのループはFor Each In でループさせる

メルマガ発行内容

<オブジェクトのループはFor Each In でループさせる>

こんにちは、三流プログラマーKen3です。 今回は、 オブジェクトやコレクションのループは、 いつものカウンタ添字じゃなく、 For Each In でループさせるです。

/* * 1.今回のキッカケ */

In message "リンク クリック", しょうもさん wrote... >[ VBAで楽しくプログラミング No.071 ] 2003/05/06 火曜日 より > >> 読者からの要望は、広告自動クリックソフトだったけど > >その名の通り、Clickメソッドが使えますよ。 >今回も、IHTMLElementオブジェクトを操っています。 >「Microsoft HTML Object Library」参照設定です。 > >'----------- > Dim objElement As IHTMLElement > Dim strTempText As String > > For Each objElement In objIE.Document.all.tags(tagName:="a") > strTempText = objElement.getAttribute _ > (strAttributeName:="href") > Debug.Print strTempText > If InStr(strTempText, "top10") Then > objElement.Click > Exit For > End If > Next >'----------- --- と、サンプルプログラムを読者より送ってもらった。 ありがたいなぁ。 人によってプログラムって書き方いろいろなんだけど、 私の悪いクセで、 For Each XXXX In XXXXX のループを避ける傾向がある。。。 今回は、これについて、少々自分にお灸をすえる意味で発行します。 ※一部の読者に人気かあるIE使った不正なクリック処理は、  また今度ね。興味あるひとは直接メールで送ってね(爆)

/* * 2.いろいろあるけど、自分にあった方法で、できればOKかなぁ。 */

ループ処理って、よく聞くのが、 1〜10までのループ For n=1 To 10 Call 処理(BOX(n)) Next n なんて感じですよね。 これは、カウンタ変数nを使用して配列の変数を使う場合、 よくみかけるパターンですよね、配列のn番目を参照するって感じで。 オブジェクトやコレクションも配列になっているので、 オブジェクトのn番目を参照して、処理を行うって書き方ができます。 ちょっと前に作った、リンクを書き出す処理 [No.71 IE操作 リンク先を取出す .Document.links(i).href] http://www.ken3.org/backno/backno_vba15.html#71 では、 'リンク数分まわす For i = 1 To objIE.Document.links.Length Cells(nYLINE, "A") = "'" & objIE.Document.links(i).outerText Cells(nYLINE, "B") = "'" & objIE.Document.links(i).href Cells(nYLINE, "C") = "'" & objIE.Document.links(i).outerHTML nYLINE = nYLINE + 1 'セット位置を+1する Next i と、 カウンタ変数iを1からobjIE.Document.links.Lengthの数回してました。 チョット、イメージ沸きにくいなぁ。 えっと、シートの名前を全て表示するには、 まずは、シートの数が必要、、 Debug.Print ActiveWorkbook.Sheets.Count と、アクティブなブックのシートのカウントは?とプロパティを参照。 で、私のいつものパターンだと、
Sub Ken3_TAKO()
  Dim n As Integer カウンター変数のnを定義、
  For n = 1 To ActiveWorkbook.Sheets.Count
    Debug.Print n & "番目のシート名は" & ActiveWorkbook.Sheets(n).Name
  Next n
End Sub
ループ、1からシート数分までループ、 Sheets(n)と添え字でn番目のシート参照、 .Nameプロパティでシート名の表示。 オブジェクトの数を押さえて、ループでまわす。 みなさんがよくネットや上級者、ヘルプのサンプルで見かけるのはコッチ。
Sub HELP_SAMPLE()
    Dim objSHEET As Object
    For Each objSHEET In ActiveWorkbook.Sheets
        Debug.Print "シート名は" & objSHEET.Name
    Next
End Sub
彼女へのアプローチの方法が三流君と違って、 私の方法は、女の子が何人いるか、チラッと.Countを見て横目で確認、 一番目の女の子から順に名前を聞き出す.Nameを見る。2番目に〜 For Each INのアプローチは、 ActiveWorkbook.Sheetsから一人ずつ僕の前に来てね 目の前に立った人(objSHEET)の名前は、 はい、次の人、 目の前に立った人(objSHEET)の名前は はい、次の人、 って感じでオブジェクト変数が入れ替わっていくループかなぁ。 なんか余計、キレがなかった(笑) 感覚だけわかってくれれば、OKかなぁ。 いろいろあるけど、自分にあった方法で、できればOKかなぁ *個人的には、カウンタ使ってループで書くほうが好きかなぁ。

/* * 3.ですが、これは、マズイでしょう。。。 */

関数作成のリクエストが来ました。 まず仕様を聞き出すか。 内容は、 渡された、Range範囲の値を1つ1つ調べ、 1000以下は背景を黄色にしてください。 ってことは、
Sub Main()
   Call CHK_1000(Range("B2:F4"))
End Sub
Sub CHK_1000(Target As Range)
   判定処理
End Sub
見たいな感じで、Rangeオブジェクトをもらって、 やり取りする関数にしますか。 さてと、事前調査で、背景を黄色は、、 HELP見るのダルイからマクロ記録にするか(みなさんはマネしないでね)
Sub Macro1()
    Range("B3:D6").Select
    With Selection.Interior
        .ColorIndex = 6
        .Pattern = xlSolid
    End With
    Range("H9").Select
End Sub
ここから、.ColorIndex = 6を頼りに、ヘルプを参照。 Range("B3:D6").Interior.ColorIndex = 0 Range("B3,D4,E5").Interior.ColorIndex = 6 と背景を変更可能を確認。
Sub CHK_1000(Target As Range)
   Target.Interior.ColorIndex = 0  'エリアの背景をクリア
   Dim n As Integer
   For n = 1 To Target.Count  'ターゲットのカウント分ループ
     If Target.Cells(n) < 1000 Then  'n番目の値のチェック
         Target.Cells(n).Interior.ColorIndex = 6 'n番目のセルを黄色にする
     End If
   Next n
End Sub
いつものパターンで、カウンタを使ってループさせて n番目のセルをチェック、1000以下のときはn番目のセルを黄色に。 call CHK_1000(Range("B2:F4")) 実行するか、よしOKじゃん。軽い軽い。 実行結果↓、まぁ動作してますが。。。 では、パラメータを変えて、テストを続けるか。 call CHK_1000(Range("B2:B4,D2:D4,F2:F4")) と、飛び飛びの範囲を設定してみるか。 あれ、動かないよ、B列の下を見に行ってるよ。 動作不良の実行結果↓、オイオイ、、、 実は、ここが落とし穴だったんですね。 Target.Cells(n)で参照しているのですが、 範囲をRange("B2:B4,D2:D4")みたいに指定されると動作不良をおこします。 そこで、1つ1つオブジェクトを取り出しループさせる For Eachに変更します。
Sub CHK_1000(Target As Range)
   Target.Interior.ColorIndex = 0  'エリアの背景をクリア
   Dim objRANGE As Range
   For Each objRANGE In Target  'オブジェクトを取り出しながらループ
     If objRANGE.Value < 1000 Then  '取り出したオブジェクトの値をチェック
         objRANGE.Interior.ColorIndex = 6 'セルを黄色にする
     End If
   Next
End Sub
と、Objectを1つ1つ取り出してチェック、色づけに変更して、 call CHK_1000(Range("B2:B4,D2:D4,F2:F4")) を実行して、飛び飛びのセルのチェックを行う。 やっとできたかぁ(正常終了) ふぅ〜 どっちでもイイヤって場合とFor Eachじゃないとダメなパターンがあるんだなぁ。 みなさんはハマったことありますか?

/* * 4.おわりの挨拶 */

今回は、 オブジェクト、コレクションのループのお話でした。 拾い読みして、 1つでも何かの参考となれば幸いです。 Excel/Access大好き、三流プログラマーKen3でした。 ※評価は↓で投票してね。感想は掲示板かメールでくださいね。


ページフッター

ここまで、読んでいただきどうもです。ここから下は、三流君のホームページの紹介・案内です
目的の情報が見つかったか?少々心配しつつ、、、

種類別のリンク や 広告など

気になったジャンル↓を選択してください。

人気記事(来場者が多いTOP3):
[VBAでIE,WebBrowserを操作]・・・VBAでIE,WebBrowserを操作する サンプルです
[Access から Excel 連携 CreateObject("Excel.Application")]・・・AccessからExcelを操作したりデータの書き出しなどです
[VBAでOutlookの操作 CreateObject("Outlook.Application" )]・・・VBAからOutlookを使い、メール関係を処理するサンプルです
↑上記3つみたいなCreateObjectで他のアプリケーションを操作するサンプルが人気です。

Excel関係:
[Excel UserFormを操作する]・・・エクセルでユーザーフォームを作成して入力などを行ってます
[ExcelからAccessを操作する]・・・ExcelからAccessのマクロを起動してみました、
[Excel関係 関数、その他]・・・その他Excel関係です

Access関係:
[Access UserForm/サブフォーム 操作]・・・アクセスでフォームを使ったサンプルです
[Access レポート操作]・・・レポートを操作してみました
[Access クエリーやその他関数]・・・あまりまとまってませんが、スポット的な単体関数の解説です

その他:VBAの共通関数やテキストファイルの操作など
[VBAでテキストファイル(TextFile)の操作]・・・普通のテキストファイルを使ったサンプルです
[VBA 標準関数関係とその他解説]・・・その他、グダグタ解説してます

開発時の操作: [F1を押してHELPを見る]/ [Debug.Print と イミディエイトウインドウ]/ [実行時エラーでデバッグ]/ [ウォッチ式とSTOP]/ [参照設定を行う]

仕様書(設計書?) XXXX書類: [基本設計書や要求仕様書]/ [テスト仕様書 テストデータ]/ [バグ票]/ [関数仕様書]/ [流れは 入力・処理・出力]

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

Blogとリンク:[三流君の作業日記]/ [VBAやASPのサンプルコード]/ 広告-[通販人気商品の足跡]



[三流君(TOP ken3.org へ戻る)] / [VBA系TOPへ] / [VBA系バックナンバー目次へ移動]