VBAでプログラムを学習すると、ForとかWhileのループ処理が必ず出てきます。
大まかには三パターンですが、初心者は分かりやすいFor~Nextでスタートだ。
① For Next:処理を行う回数を指定して実行する
② Do Loop:処理を行う条件を指定して、それを満たす間は実行すう
③ For Each:指定した要素の数を数えられる間は、実行する
それで、このFor~Next文は、繰り返しを実数で説明するのががほとんどです。
まあ、実際にプログラミングを経験して来ると、これは実用的とは言えません。
むしろ、実用的なのは、For~Next文でも繰り返し回数が可変する事例だろう。例えば、ワークシートでデータの存在する最も下の行まで繰り返しを行うとか。
つまり、作成した表のデータに増減があった場合、どのように参照をするのか。
ネットで探した解説でも、両方をまとめて解説したサイトはあまりありません。
Sub Sample1()
Dim i As Long
For i = 1 To Cells(Rows.Count, 1).End(xlUp).Row
ここに1列目の最も下のセルの値まで各行で処理する記述
1行目から始めています。
Next i
End Sub
これを説明すると、上述の通りですが、これが汎用性の高いFor~Next文です。
次に、Do~Loopですが、これは敷居が高くて使いこなすのに時間が掛かるな。
まあ、条件指定が良くないと、無限ループと言う永久処理の地獄がスタートだ。
そういう時は、ESCキーを押して強制終了させたりしますがメリットは大きい。
なぜかと言うと、ループ処理の中でループ処理を改めて行うのに欠かせません。
特に、For~Next構文で、別のForNextを設定すると繰り返しでエラー発生だ。
特に構文が冗長になって、ループ処理内の記述が複雑になるほど起こりやすい。
プログラムを書いているうちに経験した方は多いと思いますが、そんな時はDo。
中の処理をDo~Loopさせれば、意外にすっきり動いてくれるという印象です。
特に特殊な条件付けは、Do~Loopに条件を付けずに回して、If文で抜ける手法。
Sub Sample1()
Dim i As Long, j as long, flg(10) As Boolean
Randomize
For i = 1 To 10
Do
j = Int((10 - 1 + 1) * Rnd + 1)
If flg(j) = False Then
flg(j) = True
Exit Do
End if
Loop
Cells(i, 1).Value = j
Next i
End Sub
これは、1~10までの乱数を重複しないで順番にセルに書き込むコードなんだ。
キモは、flg(10)という配列の中に、乱数生成の結果を流し込んで判定させます。
次に、If分の条件式で、溜まった配列の中に同じ値があれば、ループで再処理。
こうして、配列に無い数値なら、新しい配列の要素(True)と認識し抜けます。
これで、重複しない要素が確定してセルに表示しますが、乱数は良い事例です。
さらに、ループ処理は、Exit ForやExit Doで途中から抜けられるのもメリット。
最後に、For Eachは、同じ属性の要素をピックアップして処理に使うケースだ。
要素の数は分からないけれど、フォルダーの中にあるファイル群を処理したい。
そんな場合が好例でして、FileSystemObjectオブジェクトを使ったメソッドだ。
ドライブ・フォルダなども操作できるオブジェクトですが、参照設定が必要ね。
Sub Sample2()
Dim Fso As Object, Fldr As Object, Fle As Object, i As Integer
Set Fso = CreateObject("Scripting.FileSystemObject") ' インスタンス化
Set Fldr = Fso.GetFolder("C:\Users\" & _
Environ("USERNAME") & "\Documents\")
i = 1
For Each Fle In Fldr.Files
If Right(Fle.Name, 4) = ".txt" Then
Cells(i, 1).Value = Fle.Name 'txt ファイルを列挙
i = i + 1
End If
Next Fle
Set Fso = Nothing
Set Fldr = Nothing
End Sub
ドキュメントフォルダを取得して、その中のテキストファイル名を書き出すの。
そんなに難しいコードではありませんが、サンプルは参照設定なしにしました。
この方法でも動作しますので、お好きなやり方を選べますが、Environも重要。
これは、ブックを開いたPCのログインユーザー名を取得するので汎用性がある。
どのPCでもドキュメントやピクチャーのフォルダーパスを指定するのが簡単だ。
というわけで、ループ処理の三パターンは、使い道がある程度特化されている。
まあ、目的さえ分かっていれば、ループ処理の使い道が広がると思うし、プログラムによる業務改善にも幅ができてい来ると思いますので、是非、サンプルコードを参考にしてもらいたいと思うのでした。