VBA編其ノ8 Do…Loop激闘編 中編
前回の続きです。
サンプルデータは前回のもの(sample_v07.xls)を今回も使います。
前回のマクロで増えた列は削除して、初期状態にしておいてください。
「捨てちゃったよ」という方は、もう一度其ノ7でダウンロードをお願いします。
…さて。 前回のマクロのことをちょっと思い出してもらいたいのですが、この↓部分。
Do Until Cells(i, 1).Value = ""
このマクロのループ処理の継続条件は、「1列目が空白セルにぶつかるまで」なんですよ。 だから、途中に空白があると処理が止まってしまうわけで。 けど、一番左はほんとうに空白なくみっちり埋まっているのか…? 表の一番左をみっちり埋めるということがルールとして徹底できていれば良いけど、ほんとうに、誰もがそうかと言うと、ちょっと微妙ですよね。 なので、一番左がきっちり埋まっているかを確認する工程、というか、ワンクッションがあると、よりよいマクロになるような気がします。 今回は、その辺りをいじっていきましょう。
if を使って条件分岐
ということで、一番左が空白なく埋まっているかどうかを確認するメッセージが出るよう、前回のマクロを改良してみました※1。 下↓のボックスをご覧ください。 コピーして、VBEに貼ることもできます。
マクロの途中にある「 '作業準備ができているかを確認します」は、コメントです。
VBAでは「 '(シングルクォーテーション)」の後ろにある文章をただのコメントとして、つまり「マクロと関係ないもの」として認識します。
だから、逆に言えば、作り手にとってのメモ書きとして利用できるわけですね。
コメントを残しておくと、マクロを作っている途中とか、一度作ったマクロを後で読み返したときなんかに、自分が何をしたかったのか把握しやすいので、積極的に、と言っても、あまりにコメントが多いとかえって読みづらくなるので、適度にコメントを書いておくと、良いかもしれません。
では、コメントの話はこのぐらいにして。
さっそくこのマクロを動かしてみましょう。
コイツを動かすと、最初にこんなふうに聞かれます※2。
ここで「OK」を押すと前回と同じ処理が動くわけですが、「キャンセル」だと…※3
こんなメッセージが出て、マクロは終了します。 税込計算は行われません。 つまり、最初のQにどう答えるかでその後に進む道が変わってくる、というワケです。
では、どういう仕組みで分岐するのか。
仕組みは2つのステップから成り立っています。
まず、この↓部分※4。
変数「junnbi」を用意し、そこにMsgBoxの回答を格納しています。 …おおっと、今回のメッセージボックス、これまでのとちょっと違いますね。 これまで触ってきたMsgBoxは「OK」しかなかったのに、今回のは「OK」と「キャンセル」の2つの選択肢があります。 これは、上の画面のとおり、MsgBox関数の第2引数に「vbOKCancel」を指定してやることで実現できます。 こんなふうに、MsgBox関数は、引数の指定の仕方によってカスタマイズできるんです。 だから、例えばここに「vbYesNo」を指定すると「はい」「いいえ」と表示されるし、「vbYesNoCancel」だと「はい」「いいえ」「キャンセル」の3つの選択肢から選ぶことができるようになります。 ちょっとまとめておきましょう。
第2引数 | 選択肢 | 戻り値 |
---|---|---|
vbOKOnly | 「OK」 | vbOK (1) |
vbOKCancel | 「OK」「キャンセル」 | vbOK (1) / vbCancel (2) |
vbYesNoCancel | 「はい」「いいえ」「キャンセル」 | vbYes (6) / vbNo (7) / vbCancel (2) |
vbYesNo | 「はい」「いいえ」 | vbYes (6) / vbNo (7) |
vbRetryCancel | 「再試行」「キャンセル」 | vbRetry (4) / vbCancel (2) |
また、今回はこれ以外にも設定を施しているので、ちょっとそれらについても見ておきましょう※5。
「vbQuestion」のところ、これがあることによって、クエスチョンマークのアイコンがメッセージの先頭に出現します。
「vbQuestion」の他にも、「vbExclamation」でビックリ!マークの注意アイコンを、「vbInformation」で情報メッセージアイコンを出現させたりすることができます。
また、第3引数に指定した文字列が、メッセージボックスのタイトルになります。
今回はメッセージボックスのタイトルを「作業準備確認」としました。
ここで、練習のために、カスタムしたMsgBoxをいじってみましょう。
下のようなマクロを書いてみました※6 ※7。
このマクロは1行で書けるものなのですが、長くなっちゃいそうなので改行してみました。
命令を途中で改行するには、半角スペース+_(アンダーバー)を使います。
また、このメッセージボックスには、前後の()かっこは必要ありません。
そういえば、ぼくらがはじめてMsgBoxを使ったとき(VBA編其ノ1)も、()かっこはナシでした。
かっこが必要になるのは、「はい」「いいえ」とか「OK」「キャンセル」みたいに、選択肢が2つあって、その答えを利用しなきゃいけないときです。
さっきの「vbOKCancel」を使ったマクロでは、「OK」「キャンセル」の答えを変数に格納しなきゃいけなかったので、かっこでくくっていました。
…まあ、この辺りは、おいおい慣れていっていただくとして。
話を※4に戻しましょう。 このマクロでは、「vbOKCancel」のMsgBoxをまず表示し、そこでユーザーが選んだ方の答えを変数「junnbi」に格納しています。 で、「OK」か「キャンセル」かで、道が分かれます。 この分かれ道を処理するのが、「 if 」です。 ちょっとこの、「 if 」の動きを見ていきましょう※8。
if文は、
if 条件式 then
~~~条件式を満たす場合の処理~~~
end if
というかたちになっています。
「 if 」と「 end if 」は、必ずセットです。
でね、さっきの「vbOKCancel」MsgBoxの戻り値は「vbOK」か「vbCancel」のどちらかなので、「vbOK」が選ばれたとき、つまり「junnbi = vbOK」が成立するときに、税込計算が発動するように、「 then 」に続けて処理を書きます。
また、場合によっては「 else 」を使って、条件を満たさないときの処理を書くこともできます。
今回はこのケース。
「else」っていうのは、「そうじゃないとき」くらいの意味です。
今回は、「junnbi = vbOK」じゃないとき、つまり「junnbi = vbCancel」のときに、税込計算はせずにただ単にメッセージを出す、という命令にしました。
if文についてもちょっと練習しておきましょうか。 ためしに、下↓のような表を作ってください※9。
マイルールを曲げて、セル(2, 2)から表を作ってみました。
まあ、他人が作る表まではなかなかコントロールできないですから、経験だと思ってこのままやっていきます。
さて、では、次のようなマクロを書いてみましょう※10。
「クラス」の値が「 1 」の場合は赤、そうじゃないときは青く色を塗るようにしてみました。 表がセル(2, 2)から始まっているので、ループは3行目から始まるようにし(i = 3)、ループ終了判定の基準列を2に設定(Do Until Cells(i, 2).Value = "")しています。 で、コイツを動かすと…※11
こうなります。
もういっちょいきましょう。
実は、elseのところは必須ではありません。
ナシでもいけます。
つまり、「条件に適合する場合」だけ処理する、というプロシージャも書けるんです(基礎編其ノ6も合わせて読んでみてください)。
試しに次のマクロを書いてみてください※12。
で、さっき塗られた色を消して、もう1回このマクロを動かすと…※13。 もう、おわかりですね。
「クラス」の値が「 1 」の場合のみ、赤く塗られます。
それ以外のときは何も起こらず、次のセルに進みます。
第2の道、第3の道…を追加したいときは、「elseIf」を使います※14 ※15。
「 1 」ならば赤く塗る、というのが第1の処理。
今回はそれに加えて、第2の処理として、「 2 」ならば青く色が塗られるようにしました。
このようにif文は、elseIfを使って、第1条件を満たさないときにさらにifを付け加えることができるんです。
ちょうど、ワークシート関数のif関数のネスト、あんな感じです。
だから、上のプロシージャの挙動は、まず「クラスが1であるか否か」を判定し、「否」だったとしても、次に「クラスが2であるか否か」を判定する、というふうになります。
もちろん、上の表中の「クラスが3のとき」とか「クラスが空白のとき」、つまり「 1 」「 2 」以外のときは、何もしません。
何も指定していないので、ね。
if文の練習はこのくらいにしておきましょうか。
使用頻度は高いので、これから少しずつ慣れていきましょう。
ということで、本筋に戻って。 ※8の図、および「税8パーセントその6()」を改めて読んでみてください。 構造はもう、理解できましたでしょうか。
if文を書き直す
…しかし、です。 この「税8パーセントその6()」、改めて読み返すと、ダサイんですよ。 「ダサイ」っていうのはアレね、「書き方が」ってことね。 というのもこのマクロ、メインの処理は税込計算なんだけど、メインの処理含めて全体がif節の中に入っちゃってるんですよ。 だけど、僕らがやりたいことって要するに、「キャンセル押したら何もしない」ってことなんだよね。 なので、次のように書き換えてみました※16。
「 exit sub 」は、「マクロを脱出します」という意味です。
今回は、if節のところを短くし、もし「junnbi = vbCancel」だったらメッセージを出しマクロを終了する、というふうにしています。
冒頭のバージョン(税8パーセントその6)だと「 if 」「 else 」「 end if 」が離れてるから、書いているときに「現在どの条件の支配下にあるのか」を把握しづらくなっちゃうんですよ。
それに対して、コッチのバージョンは、if節の部分が短いし、ifで何をしたいのかも明確になっている気がします。
こんなふうに、「 if 」と「 exit sub 」を組み合わせると、「特定の条件下では何もしない」ってのも実現できるワケです。
覚えておいてください。
ということで、今回はここまで。
次回もこの「税8パーセント」マクロをブラッシュアップしていきますので。