マクロの記録から徐々に脱却していくと、いくつかの壁にぶつかります。
色々パターンはあるかと思いますが、結局は、”記録したマクロは実用性が低い”ということなんですね。
なので、この記事では、その”実用性”を上げるための、繰り返し処理をご案内したいと思います。
1.まずは、Ifを覚える
マクロにおける繰り返し処理を、ネットや本で調べると、以下の二つが代表的なものとしてヒットすると思います。
※「Go to」もありますが、厳密に言うと繰り返し処理ではないので割愛します。
作業手順としては、以下の通りです。
※「Go to」もありますが、厳密に言うと繰り返し処理ではないので割愛します。
- For ~ Next
- 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を使うことで条件分岐ができますので、
これを使って、繰り返し処理を進めていきたいと思います。
分岐処理というと少々難しいように聞こえますが、文面を見てみると、非常に簡単です。
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列にコピペする作業を自動化してみたいと思います。作業手順としては、以下の通りです。
- A1セルを選択する
- 選択したセルに、何か値が入っていれば、右隣のセルに値をコピーする
何も値が入っていなければ、何もしない - 一つ下のセルを選択する
- 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
Else
End If
End Sub
〜〜〜ここまで〜〜〜
ここで、条件分岐の「If」が出てきます。
この記述が何を言っているかというと、
もし(If)、今選択されているセル(ActiveCell)の値(Value)が、
空欄ではない(<> "")場合(Then)、
今選択されているセルの一つ右のセル(ActiveCell.Offset(0, 1))の値(Value)は、
今選択されているセル(ActiveCell)の値(Value)にする。
それ以外の場合(Else)、何もしない。
今選択されているセルの一つ右のセル(ActiveCell.Offset(0, 1))の値(Value)は、
今選択されているセル(ActiveCell)の値(Value)にする。
それ以外の場合(Else)、何もしない。
といった、具合です。
勘の良い方はお気づきかと思いますが、
空欄ではない→<> "" となるため、空欄の場合→= "" になります。
等号/不等号は、算数・数学の表示と一緒というわけです。
3.一つ下のセルを選択する
3.一つ下のセルを選択する
〜〜〜ここから〜〜〜
Sub test()
Range("A1").Select
If ActiveCell.Value <> "" Then
ActiveCell.Offset(0, 1).Value = ActiveCell.Value
ActiveCell.Offset(1).Select
ActiveCell.Offset(1).Select
Else
End If
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で記載した条件以外の場合は、この繰り返し処理を抜けることになります。
この繰り返し処理を抜けるタイミングを、正しく設置しないと、
無限ループに入ってしまいますので、必ず設置するようにしてください。
正しく設置できているかは、ステップイン機能を使って、
問題なく繰り返し処理を抜けているかどうかを確認します。
マクロの教則本でも、割りと早い項で登場する繰り返し処理ですが、
教則本は、それよりも前に、基本的なマクロのルールなんかも出てきて、
実践までの期間が長い印象だったので、速攻使えるように本稿を書きました。
今回ご案内した内容を応用し、マクロの記録と継ぎ接ぎするだけでも、
それなりなツールは作れますので、ご参考いただければ幸いです。
マクロでできることシリーズ的に、細かい記述や、パーツとして使えそうなものも
適宜投稿していこうと思いますので、ご興味がある方は是非、これからもよろしくお願いいたします。
それではまた
一つ前の作業でも、既に出てきていますが、「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.まとめ
前回の内容から、一気に進んで、繰り返し処理のご案内をいたしました。マクロの教則本でも、割りと早い項で登場する繰り返し処理ですが、
教則本は、それよりも前に、基本的なマクロのルールなんかも出てきて、
実践までの期間が長い印象だったので、速攻使えるように本稿を書きました。
今回ご案内した内容を応用し、マクロの記録と継ぎ接ぎするだけでも、
それなりなツールは作れますので、ご参考いただければ幸いです。
マクロでできることシリーズ的に、細かい記述や、パーツとして使えそうなものも
適宜投稿していこうと思いますので、ご興味がある方は是非、これからもよろしくお願いいたします。
それではまた
コメント
コメントを投稿