ド級素人が始めるVBA①(反復処理)

どうも、のっちゃんです。

最近VBAなるものに手を出し始めました。
しかし私は法学部出身ということで、全くと言っていいほどプログラミングの経験がありません。

そこで自分の失敗談を備忘録としてまとめておくとともに、私のようなド素人でもVBAの一端が掴めるようになって欲しいと思います。


今日のテーマ

今日のテーマは「反復処理」です。反復処理とは大雑把に言えば「同じ操作を連続する」操作です。

調べてみたところ、反復操作は大きく2種類に分けられるようです。
そこでそれぞれの操作とコード、練習してみてのフィードバックを記載してみます。

1. For-Next

For-Nextは以下のような構造です。

変数定義
 For 変数 = 下限 to 上限(step 変数の公差)
  反復したい動作
 Next 変数

実際に書いてみました。ちなみに
お題:B1,B3,B5セルに"Hello World"を入力せよ

Sub HelloWorld()
 Dim i As Integer
  For i = 51 To 55 Step 2
   Cells(i, 2) = "Hello World"
  Next

実際にエクセルで実行するとこのようになりました。

少し解説してみます。
最初のdim i as integerが「変数定義」にあたります。dim ◯で「◯を変数として定義します」という意味があり、後ろの「as integer」が変数の種類(整数なのか小数なのか、はたまた文字列なのか)を定義します。ここでは「iは整数の範囲で変化します」と定義しているわけです。

ちなみに変数の種類と対応する型でよく使いそうなものは次の7種類っぽいですね。
integer
・-32,768 ~ 32,767までの整数。ビジネスで使うには範囲が狭い。
long
・-2,147,483,648 ~ 2,147,483,647までの整数。これも22億ちょっとなので、売上高などを計算するのには不向き。
currency
・-922,337,203,685,477.5808 ~ 922,337,203,685,477.00までの数値。これなら売上高などでも使えそう。
single
・-3.402823E38 ~ -1.401298E-45(負の値)、1.401298E-45 ~ 3.402823E38(正の値)を扱える。表記が難しいが、ざっと±0.000000000000000000000000000000000000000000001~±300000000000000000000000000000000000000までの数字が扱えるっぽい。こんなに幅のある数字を使うことが人生で何回あるだろうか。
string
・文字列。最大で20億文字まで扱えるそうだが、果たして20億文字も文字をそもそも使うのだろうか?
date
・西暦100年1月1日から、西暦9999年12月31日までの日付と時間を扱える。ちなみに西暦100年はだいたい卑弥呼が記録に登場する140年前くらいで、ローマ帝国が繁栄していた時代です。
variant
・全種類に対応する。一応variantを使うと処理が遅くなるというデメリットがあるそうだが、現在のPCのスペックなら殆ど差がないとのこと。ちなみに変数型の指定をしない場合は自動でvariantになる。

次にFor i = 1 to 5 step 2です。
◯to●という部分が「◯から●までの範囲でiを動かします」ということを意味し、step 2 という部分で「2つ飛びでiが動きます」というルールを指定します。
そのためこの部分でiの変域を指定する、ということになるわけです。

そしてnext i の部分ですが、これはnextだけでも問題ありません。しかし変数を複数使う場合は、どの処理がどの部分まででループするかをわかりやすくするために、変数まで書くことが多いそうです。

2. Do-Loop

もう一つがDo-Loopです。
Do-Loopで反復する範囲を指定する場合はwhile、もしくはuntilを用いて範囲指定を行う必要があります。
whileは「〜〜という条件を満たす間はループを継続する」ということを意味するのに対し、untilは「〜〜という条件を満たすまでループを継続する」ということを意味します。

これだけだと何が何だかわからないと思いますので、まず構造を書いてみたいと思います。

(Whileの場合)
変数定義
 変数の初期値
 Do while 変数+条件
  反復したい操作
  次のループに行くための変数操作
 Loop

(untilの場合)
変数定義
 変数の初期値
 Do until 変数+条件
  反復したい操作
  次のループに行くための変数操作
 Loop

For-Nextとの大きな違いは「変数の変域を直接指定するかどうか」だと思います。
For-Nextは初めの段階で「iをAからBまで動かす」という指定をします。しかしDo-Loopはまず変数の初期値を指定し、ループを終了する条件を指定し、最後に次のループに行くために変数をいくつ動かすかを指定します。

これも実際にコードを書いてみました。お題は先程のものと同じです。

(whileの場合)
Sub helloworld()
 Dim i As Integer
  i = 1
  Do While i <= 5
   Cells(i, 2) = "hello world"
   i = i + 2
  Loop
End Sub

(untilの場合)
Sub helloworld()
 Dim i As Integer
  i = 1
  Do Until i > 5
   Cells(i, 2) = "hello world"
   i = i + 2
  Loop
End Sub

書いてみて気づいたのですが、untilとwhileでは微妙にループ終了の条件が違いますね。
whileの場合は「”iが5以下である”という条件を満たしている間」ループするので、do while i <= 5になります。
一方untilは「"iが5より大きい"という条件が満たされるまで」ループをするので、do until i > 5という表記が正しいです(ちなみに私自身は一度=を入れ忘れてB5セルに文字が出力されず「?」となりました)。
(結果は上記と同じなので省略します)

こうしてみると、For-Nextの方がコードとしてはスッキリしますね。一方Do-Loopの場合はどこまでの処理がループしているのかがわかりやすい印象です。またFor-Nextは繰り返しの「回数」が記載されているのに対し、Do-Loopは繰り返しの「条件」が記載されています。

では実際どのように使い分けをするかですが、いくつか調べた結果を一言で言えば「繰り返しの回数が決まっているかどうか」のようです。
For-Nextは繰り返しの回数を定義している(For i = ◯ to ●)ので、追加データの処理にはやや不向きです。しかしDo-Loopの場合は繰り返し回数を定義しておらず、繰り返す条件を定義しているため、追加データがあっても処理が容易です。逆に繰り返す回数が決まっている場合はFor-Nextの方がコードも短くバグも起きにくいため、こちらを採用した方が良さそうです。

あとはuntiとwhileの使い分けですが、素人目線ではどっちでも良さそうだと思わなくもないです。強いて言えばuntilは「終了条件」を指し、whileは「反復条件」を指しているので、ここで使い分けをする可能性があります。

まとめ

ということで、今回は2つの反復処理について学びました。実際に書いてみて気付くことも多いので、やはり手を動かして勉強すべきだなぁと、しみじみ感じた次第です。

この記事が気に入ったらサポートをしてみませんか?