【Excel/VBA】繰り返し処理をやってみる

マクロの記録から徐々に脱却していくと、いくつかの壁にぶつかります。
色々パターンはあるかと思いますが、結局は、”記録したマクロは実用性が低い”ということなんですね。

なので、この記事では、その”実用性”を上げるための、繰り返し処理をご案内したいと思います。

1.まずは、Ifを覚える

マクロにおける繰り返し処理を、ネットや本で調べると、以下の二つが代表的なものとしてヒットすると思います。
※「Go to」もありますが、厳密に言うと繰り返し処理ではないので割愛します。
  1. For ~ Next
  2. Do ~ Loop
いずれの方法も正しいのですが、個人的には、まず始めに「If」を使った分岐処理を覚えましょう。

分岐処理というと少々難しいように聞こえますが、文面を見てみると、非常に簡単です。

Ex1)
A1が「あいうえお」という値の場合、B1に「あいうえお」を入力する
〜〜〜ここから〜〜〜
Sub あいうえお()

    If Range("A1").Value = "あいうえお" Then
        Range("B1").Value = "あいうえお"
    End If

End Sub
〜〜〜ここまで〜〜〜

堅苦しく書くと、
If 条件式 Then
実施される作業
End If
と、なるのですが、和訳するほうがわかりやすいと思うので、以下のようにしてみたいと思います。

もし(If)、A1(Range("A1"))セルの値(Value)が、あいうえお(= "あいうえお")だった場合(Then)、
B1(Range("B1"))セルの値(Value)は、あいうえお(= "あいうえお")とする。
分岐処理を終える(End If)。

いかがでしょうか。

Ex2)
A1が「あいうえお」という値の場合、B1に「あいうえお」を入力する。
それ以外の場合、B1に「あいうえおじゃない」と入力する。
〜〜〜ここから〜〜〜
Sub あいうえお()

    If Range("A1").Value = "あいうえお" Then
        Range("B1").Value = "あいうえお"
    Else
        Range("B1").Value = "あいうえおじゃない"
    End If

End Sub
〜〜〜ここまで〜〜〜

Elseは、「それ以外」を意味します。
これを追記することにより、条件以外の場合について、別の作業を割り当てることができます。

もし(If)、A1(Range("A1"))セルの値(Value)が、あいうえお(= "あいうえお")だった場合(Then)、
B1(Range("B1"))セルの値(Value)は、あいうえお(= "あいうえお")とする。
それ以外(Else)の場合、
B1(Range("B1"))セルの値(Value)は、あいうえお(= "あいうえおじゃない")とする。
分岐処理を終える(End If)。

なお、Elseの後に”Then”は不要です。

Ex3)
A1が「あいうえお」という値の場合、B1に「あいうえお」を入力する。
A1が「かきくけこ」という値の場合、B1に「かきくけこ」を入力する。
それ以外の場合、B1に「あいうえおじゃない」と入力する。
〜〜〜ここから〜〜〜
Sub あいうえお()

    If Range("A1").Value = "あいうえお" Then
        Range("B1").Value = "あいうえお"
    ElseIf Range("A1").Value = "かきくけこ" Then
        Range("B1").Value = "かきくけこ"
    Else
        Range("B1").Value = "あいうえおじゃない"
    End If

End Sub
〜〜〜ここまで〜〜〜

ElseIfを使うことで、条件を増やすことができます。

もし(If)、A1(Range("A1"))セルの値(Value)が、あいうえお(= "あいうえお")だった場合(Then)、
B1(Range("B1"))セルの値(Value)は、あいうえお(= "あいうえお")とする。
もし(ElseIf)、A1(Range("A1"))セルの値(Value)が、かきくけこ(= "かきくけこ")だった場合(Then)、
B1(Range("B1"))セルの値(Value)は、かきくけこ(= "かきくけこ")とする。
それ以外(Else)の場合、
B1(Range("B1"))セルの値(Value)は、あいうえお(= "あいうえおじゃない")とする。
分岐処理を終える(End If)。

わかりやすいと思った和訳なんですが、文章が長くなると少々わかりにくいですね。
精進いたします。

このように、Ifを使うことで条件分岐ができますので、
これを使って、繰り返し処理を進めていきたいと思います。

2.Do~Loopで繰り返しを行う

たとえば、A列にある値を、B列にコピペする作業を自動化してみたいと思います。








作業手順としては、以下の通りです。
  1. A1セルを選択する
  2. 選択したセルに、何か値が入っていれば、右隣のセルに値をコピーする
    何も値が入っていなければ、何もしない
  3. 一つ下のセルを選択する
  4. 2に戻る

一つずつ、実際の記述と合わせて、解説していきたいと思います。
※新しく記述が増えた所を、赤い文字で表記します。

1.A1セルを選択する

〜〜〜ここから〜〜〜
Sub test()

    Range("A1").Select

End Sub
〜〜〜ここまで〜〜〜

これは、確実にA1セルから作業を始めるためです。
Excelを開いた際は、最後に保存した状態が保たれるため、
場合によっては、A1セル以外の箇所が選択されており、作業が正しく行えないことを回避するためです。


2.選択したセルに、何か値が入っていれば、右隣のセルに値をコピーする
  それ以外の場合(何も値が入っていない)、何もしない

〜〜〜ここから〜〜〜
Sub test()

    Range("A1").Select

    If ActiveCell.Value <> "" Then
        ActiveCell.Offset(0, 1).Value = ActiveCell.Value
    Else
    End If

End Sub
〜〜〜ここまで〜〜〜

ここで、条件分岐の「If」が出てきます。
この記述が何を言っているかというと、

もし(If)、今選択されているセル(ActiveCell)の値(Value)が、
空欄ではない(<> "")場合(Then)、
今選択されているセルの一つ右のセル(ActiveCell.Offset(0, 1))の値(Value)は、
今選択されているセル(ActiveCell)の値(Value)にする。
それ以外の場合(Else)、何もしない。

といった、具合です。

勘の良い方はお気づきかと思いますが、
空欄ではない→<> "" となるため、空欄の場合→= "" になります。
等号/不等号は、算数・数学の表示と一緒というわけです。


3.一つ下のセルを選択する

〜〜〜ここから〜〜〜
Sub test()

    Range("A1").Select

    If ActiveCell.Value <> "" Then
        ActiveCell.Offset(0, 1).Value = ActiveCell.Value
        ActiveCell.Offset(1).Select
    Else
    End If

End Sub
〜〜〜ここまで〜〜〜

一つ前の作業でも、既に出てきていますが、「Offset」というものを解説します。
Offsetは、選択されているセル等、基準となる箇所から離れた場所を指定できます。
実際にその場所を選択することもできますし、ただ指定するだけというのも可能です。
Offset(行,列)という構成になっており、行/列の箇所に数字を入れます。(マイナスも可)

例えば、今A1セルが選択されていて、C2セルを選択したいと思った場合、
A1セルに対して、C2セルは、「1行下&2列右」に位置します。
Offset(1,2)となるわけです。
A1セルが既に選択されている場合は、そこを「ActiveCell」と表記できますので、

ActiveCell.Offset(1,2).Select

と、記述することで、C2セルの選択を実施できます。
使うことは無いと思いますが、VBEに書くと、以下の通りです。
〜〜〜ここから〜〜〜
Sub A1からC2に移動()

    ActiveCell.Offset(1, 2).Select

End Sub
〜〜〜ここまで〜〜〜

ちなみに、マイナス表記も可能なので、
ActiveCell.Offset(-1,2).Select
と、することによって、現在選択されているセルから、1行上の2列右のセルを選択します。
行にとって、プラスは下に向かい、マイナスは上に向かうということです。
列の場合は、プラスは右に向かい、マイナスは左に向かうことになります。

また、行だけ指定する場合は、列の部分は省略できます。
Offset(1,0) → Offset(1) 「,0」は不要
列だけ指定する場合は、省略不可ですので、ご注意ください。
Offset(0,1) → Offset(1) これは不可

4.2に戻る

〜〜〜ここから〜〜〜
Sub test()

    Range("A1").Select

    Do

        If ActiveCell.Value <> "" Then
            ActiveCell.Offset(0, 1).Value = ActiveCell.Value
            ActiveCell.Offset(1).Select
        Else
            Exit Do
        End If

    Loop

End Sub
〜〜〜ここまで〜〜〜

ここで、ついに繰り返し処理が入ってきます。

繰り返したい部分を、Do~Loopで囲みます。
そして、何より重要なのが、繰り返し処理を抜けるタイミングを設定することです。
今回の例の場合は、「選択されたセルが空白の場合」ですね。
※正確に言うと、「”選択されたセルが空白でない場合”以外」ですが、こんがらがるのでシンプルに書きました。

そのため、Elseで指定した箇所に、「Exit Do(Doの処理を終える)」を記載することで、
Ifで記載した条件以外の場合は、この繰り返し処理を抜けることになります。

この繰り返し処理を抜けるタイミングを、正しく設置しないと、
無限ループに入ってしまいますので、必ず設置するようにしてください。

正しく設置できているかは、ステップイン機能を使って、
問題なく繰り返し処理を抜けているかどうかを確認します。

3.まとめ

前回の内容から、一気に進んで、繰り返し処理のご案内をいたしました。
マクロの教則本でも、割りと早い項で登場する繰り返し処理ですが、
教則本は、それよりも前に、基本的なマクロのルールなんかも出てきて、
実践までの期間が長い印象だったので、速攻使えるように本稿を書きました。

今回ご案内した内容を応用し、マクロの記録と継ぎ接ぎするだけでも、
それなりなツールは作れますので、ご参考いただければ幸いです。

マクロでできることシリーズ的に、細かい記述や、パーツとして使えそうなものも
適宜投稿していこうと思いますので、ご興味がある方は是非、これからもよろしくお願いいたします。

それではまた

コメント