---topics:ifステートメント、MsgBox関数、Exit Sub---

VBA編其ノ8 Do…Loop激闘編 中編

前回の続きです。
サンプルデータは前回のもの(sample_v07.xls)を今回も使います。 前回のマクロで増えた列は削除して、初期状態にしておいてください。 「捨てちゃったよ」という方は、もう一度其ノ7でダウンロードをお願いします。

…さて。 前回のマクロのことをちょっと思い出してもらいたいのですが、この↓部分。

Do Until Cells(i, 1).Value = ""

このマクロのループ処理の継続条件は、「1列目が空白セルにぶつかるまで」なんですよ。 だから、途中に空白があると処理が止まってしまうわけで。 けど、一番左はほんとうに空白なくみっちり埋まっているのか…? 表の一番左をみっちり埋めるということがルールとして徹底できていれば良いけど、ほんとうに、誰もがそうかと言うと、ちょっと微妙ですよね。 なので、一番左がきっちり埋まっているかを確認する工程、というか、ワンクッションがあると、よりよいマクロになるような気がします。 今回は、その辺りをいじっていきましょう。

if を使って条件分岐

ということで、一番左が空白なく埋まっているかどうかを確認するメッセージが出るよう、前回のマクロを改良してみました※1。 下↓のボックスをご覧ください。 コピーして、VBEに貼ることもできます。

「 '(シングルクォーテーション)」のうしろはコメントです
※1 「 '(シングルクォーテーション)」のうしろはコメントです

マクロの途中にある「 '作業準備ができているかを確認します」は、コメントです。 VBAでは「 '(シングルクォーテーション)」の後ろにある文章をただのコメントとして、つまり「マクロと関係ないもの」として認識します。 だから、逆に言えば、作り手にとってのメモ書きとして利用できるわけですね。 コメントを残しておくと、マクロを作っている途中とか、一度作ったマクロを後で読み返したときなんかに、自分が何をしたかったのか把握しやすいので、積極的に、と言っても、あまりにコメントが多いとかえって読みづらくなるので、適度にコメントを書いておくと、良いかもしれません。
では、コメントの話はこのぐらいにして。 さっそくこのマクロを動かしてみましょう。 コイツを動かすと、最初にこんなふうに聞かれます※2

最初に聞かれる
※2 最初に聞かれる

ここで「OK」を押すと前回と同じ処理が動くわけですが、「キャンセル」だと…※3

最初の質問に「キャンセル」だと、こうなる 処理はされない
※3 最初の質問に「キャンセル」だと、こうなる 処理はされない

こんなメッセージが出て、マクロは終了します。 税込計算は行われません。 つまり、最初のQにどう答えるかでその後に進む道が変わってくる、というワケです。

では、どういう仕組みで分岐するのか。
仕組みは2つのステップから成り立っています。 まず、この↓部分※4

最初のQの解説
※4 最初のQの解説

変数「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

クエスチョンマークがでる理由
※5 クエスチョンマークがでる理由

vbQuestion」のところ、これがあることによって、クエスチョンマークのアイコンがメッセージの先頭に出現します。 「vbQuestion」の他にも、「vbExclamation」でビックリ!マークの注意アイコンを、「vbInformation」で情報メッセージアイコンを出現させたりすることができます。 また、第3引数に指定した文字列が、メッセージボックスのタイトルになります。 今回はメッセージボックスのタイトルを「作業準備確認」としました。

ここで、練習のために、カスタムしたMsgBoxをいじってみましょう。 下のようなマクロを書いてみました※6 ※7

メッセージボックスの練習
※6 メッセージボックスの練習
こんな感じになる
※7 こんな感じになる

このマクロは1行で書けるものなのですが、長くなっちゃいそうなので改行してみました。 命令を途中で改行するには、半角スペース+_(アンダーバー)を使います。
また、このメッセージボックスには、前後の()かっこは必要ありません。 そういえば、ぼくらがはじめてMsgBoxを使ったとき(VBA編其ノ1)も、()かっこはナシでした。 かっこが必要になるのは、「はい」「いいえ」とか「OK」「キャンセル」みたいに、選択肢が2つあって、その答えを利用しなきゃいけないときです。 さっきの「vbOKCancel」を使ったマクロでは、「OK」「キャンセル」の答えを変数に格納しなきゃいけなかったので、かっこでくくっていました。 …まあ、この辺りは、おいおい慣れていっていただくとして。

話を※4に戻しましょう。 このマクロでは、「vbOKCancel」のMsgBoxをまず表示し、そこでユーザーが選んだ方の答えを変数「junnbi」に格納しています。 で、「OK」か「キャンセル」かで、道が分かれます。 この分かれ道を処理するのが、「 if 」です。 ちょっとこの、「 if 」の動きを見ていきましょう※8

ifステートメントの解説
※8 ifステートメントの解説

if文は、

if 条件式 then

~~~条件式を満たす場合の処理~~~

end if

というかたちになっています。 「 if 」と「 end if 」は、必ずセットです。 でね、さっきの「vbOKCancel」MsgBoxの戻り値は「vbOK」か「vbCancel」のどちらかなので、「vbOK」が選ばれたとき、つまり「junnbi = vbOKが成立するときに、税込計算が発動するように、「 then 」に続けて処理を書きます。
また、場合によっては「 else 」を使って、条件を満たさないときの処理を書くこともできます。 今回はこのケース。 「else」っていうのは、「そうじゃないとき」くらいの意味です。 今回は、「junnbi = vbOK」じゃないとき、つまり「junnbi = vbCancelのときに、税込計算はせずにただ単にメッセージを出す、という命令にしました。

if文についてもちょっと練習しておきましょうか。 ためしに、下↓のような表を作ってください※9

練習台
※9 練習台

マイルールを曲げて、セル(2, 2)から表を作ってみました。 まあ、他人が作る表まではなかなかコントロールできないですから、経験だと思ってこのままやっていきます。
さて、では、次のようなマクロを書いてみましょう※10

if文の練習マクロ
※10 if文の練習マクロ

「クラス」の値が「 1 」の場合は赤、そうじゃないときは青く色を塗るようにしてみました。 表がセル(2, 2)から始まっているので、ループは3行目から始まるようにし(i = 3)、ループ終了判定の基準列を2に設定(Do Until Cells(i, 2).Value = "")しています。 で、コイツを動かすと…※11

「クラス」の値が「 1 」か否かによって、色が塗られる
※11 「クラス」の値が「 1 」か否かによって、色が塗られる

こうなります。

もういっちょいきましょう。 実は、elseのところは必須ではありません。 ナシでもいけます。 つまり、「条件に適合する場合」だけ処理する、というプロシージャも書けるんです(基礎編其ノ6も合わせて読んでみてください)。
試しに次のマクロを書いてみてください※12

else文ナシでもイケる
※12 else文ナシでもイケる

で、さっき塗られた色を消して、もう1回このマクロを動かすと…※13。 もう、おわかりですね。

もし「クラス」が「 1 」なら赤くなる それ以外は何も起こらない
※13 もし「クラス」が「 1 」なら赤くなる それ以外は何も起こらない

「クラス」の値が「 1 」の場合のみ、赤く塗られます。 それ以外のときは何も起こらず、次のセルに進みます。

第2の道、第3の道…を追加したいときは、「elseIf」を使います※14 ※15

第2の条件を追加
※14 第2の条件を追加
「 1 」なら赤 「 2 」なら青
※15 「 1 」なら赤 「 2 」なら青

「 1 」ならば赤く塗る、というのが第1の処理。 今回はそれに加えて、第2の処理として、「 2 」ならば青く色が塗られるようにしました。 このようにif文は、elseIfを使って、第1条件を満たさないときにさらにifを付け加えることができるんです。 ちょうど、ワークシート関数のif関数のネスト、あんな感じです。 だから、上のプロシージャの挙動は、まず「クラスが1であるか否か」を判定し、「否」だったとしても、次に「クラスが2であるか否か」を判定する、というふうになります。
もちろん、上の表中の「クラスが3のとき」とか「クラスが空白のとき」、つまり「 1 」「 2 」以外のときは、何もしません。 何も指定していないので、ね。

if文の練習はこのくらいにしておきましょうか。 使用頻度は高いので、これから少しずつ慣れていきましょう。

ということで、本筋に戻って。 ※8の図、および「税8パーセントその6()」を改めて読んでみてください。 構造はもう、理解できましたでしょうか。

if文を書き直す

…しかし、です。 この「税8パーセントその6()」、改めて読み返すと、ダサイんですよ。 「ダサイ」っていうのはアレね、「書き方が」ってことね。 というのもこのマクロ、メインの処理は税込計算なんだけど、メインの処理含めて全体がif節の中に入っちゃってるんですよ。 だけど、僕らがやりたいことって要するに、「キャンセル押したら何もしない」ってことなんだよね。 なので、次のように書き換えてみました※16

もしキャンセルだったらメッセージが出て終了、というif節に変えました
※16 もしキャンセルだったらメッセージが出て終了、というif節に変えました

exit sub 」は、「マクロを脱出します」という意味です。 今回は、if節のところを短くし、もし「junnbi = vbCancel」だったらメッセージを出しマクロを終了する、というふうにしています。 冒頭のバージョン(税8パーセントその6)だと「 if 」「 else 」「 end if 」が離れてるから、書いているときに「現在どの条件の支配下にあるのか」を把握しづらくなっちゃうんですよ。 それに対して、コッチのバージョンは、if節の部分が短いし、ifで何をしたいのかも明確になっている気がします。 こんなふうに、「 if 」と「 exit sub 」を組み合わせると、「特定の条件下では何もしない」ってのも実現できるワケです。 覚えておいてください。
ということで、今回はここまで。 次回もこの「税8パーセント」マクロをブラッシュアップしていきますので。

Copyright(C)森田表計算