トップ > Excelマクロ > 2-6 当番表の作成(Mod関数他)
【今回できるようになること】
・Subプロシージャの中から別のSubプロシージャを呼び出す
・同じセルに対する処理をまとめる
・余りを計算する
こんにちはー!!
今回は、当番表を作るときに使われる「Mod関数」に加え、
前回扱った「Subプロシージャ」や、新たに学ぶ「Withステートメント」を使って、
コードをスッキリさせるテクニックを学びます!
それではやっていきましょう!
今回は、下のような2週間分の当番表をマクロで作ることを目指します!
プログラムの流れとしては、A列を上から順番にチェックしていき、
日数が3の倍数+1なら太郎、花子、健太の順にB,C,D列を埋め、
日数が3の倍数+2なら花子、健太、太郎の順、
日数が3の倍数なら健太、太郎、花子の順にB,C,D列を埋める。
となります!
それでは、VBEを開いて標準モジュールを追加し、メモ帳みたいなものの「Option Explicit」以下に、下のコードを書いてみましょう!
ちなみに、AをBで割ったときの余りを求めたいときは「A Mod B」と表記します!
今回は、(日 Mod 3)が1か2か0かをIf関数で調べることで、処理を分けています。
はい。長すぎてもう書きたくないですね(^^;)
このコードでも目標の当番表は問題なく作成されるのですが、
もっとスッキリと書くことを目指しましょう。
ちなみに今回は、「お手伝い」「日」「最終行判定」など、プロシージャ名や変数を全角日本語表記にしてみました。
いかがでしょうか??
筆者としては、変数が全角日本語なのは何やら気持ち悪いのですが、
もしこちらの方が分かりやすいという方がいれば、
VBAは全角日本語でも問題なく定義できるので取り入れてみてください!
それでは早速コードを改善していきます!
まず注目すべきは、なんといってもIf構文の中身です。
同じような4行のかたまりが幅を利かせていて、
重要なIf構文の入れ子構造(ネスト)を俯瞰しにくくしています。
まずは、最初に出てくる「太郎」に関する4行を、別のプロシージャにしてしまいましょう!
下のように、新たに「Sub 太郎 ()」プロシージャを作成してください。
そして、その4行があった場所に「Sub 太郎()」を呼び出すコードを「Call プロシージャ名」の形で書きます。
あれだけ長かった4行が、たった1行にまとめられました。
このように、ある機能を持つコードのまとまりを別プロシージャにまとめることで、
スッキリと理解しやすいコードを書くことができます。
同じように、花子と健太も別プロシージャにまとめましょう!
ここで「Else If (日 Mod 3) = 2 Then」の下に、また花子の4行が出てきましたね。
よく見ると、
さっきは「Cells(Selection.Value, 3)」だった部分が、
今回は、「Cells(Selection.Value, 2)」になっているというだけの違いです。
たった1文字の違いだけで、もう一度新たにSubプロシージャを作るのは面倒です。
そこで、先ほど作った「Sub 花子()」を、次のように改良しましょう。
これは、()の中に変数「列」を定義することで、
Sub花子を呼び出すときにセルの列を指定できるようにしています。
このように、呼び出すプロシージャに渡して処理に組み込む数のことを、「引数」と言います。
引数のあるプロシージャを呼び出すときは、「Call プロシージャ名(引数の値)」の形でコードを書きます。
それでは、残ったコードも全て別プロシージャ化してしまいましょう!
行数はあまり変わりませんが、
メインのプロシージャ「お手伝い」の下に、部品のプロシージャ「太郎」「花子」「健太」があるという、
構造が理解しやすいコードになったのではないかと思います。
それでは最後に、太郎、花子、健太のプロシージャにおいて、
「Cells(Selection.Value, 列)」が4連続になっていることを改善して終わりにしましょう!
コードを下のように書き換えてください!
このように、Withステートメントを使うことで、同じセルに対する処理をまとめることができます。
長くなりましたが、最後まで読んでいただきありがとうございました!
【今回のまとめ】
・Subプロシージャは「Call プロシージャ名」で呼び出す
・引数のあるSubプロシージャは「Call プロシージャ名(引数の値)」で呼び出す
・同じセルに対する処理は、Withステートメントでまとめられる
・AをBで割ったときの余りは、「A Mod B」で表す