Excel VBAで場合分けしたデータ数をカウントする方法をわかりやすく解説
マクロ(VBA)には色々な機能がありますが、物流のシミュレーションで使う機能は僅かです。
折角時間をかけて膨大な量のExcel VBAの解説本やマニュアルを読んでも、そのほとんどは物流シミュレーションには必要のない機能です。
今回は最短距離で物流シミュレーションができるようになるために、よく使う処理機能だけに絞って解説する後半編です。
物流シミュレーションにおいて頻繁に使う繰り返し処理、算術計算、場合分けのうち、繰り返し処理と算術計算のやり方については、前回の前編で解説しました。
【参考】
物流シミュレーションに必要な機能はたったこれだけ!最短距離でExcel VBAを理解【算術計算】
今回は場合分け(If~Then~Else)について解説していきます。
偶数と奇数に分けてカウントする
MOD関数で偶数と奇数を判断する
今回も前回に続いて、次の売上データを使います。
今回は、売上が偶数の日と奇数の日がそれぞれ何日あるかを計算します。
偶数と奇数を分けるには、2で割ると余りが0になる数字が偶数、余りが1になる数字が奇数と考えます。
エクセル関数ですとMOD関数で余りを求めることができます。
例えばあるセルに”=MOD(5,2)”と入力してEnterキーを押すと、1が表示されます。
前回の記事で、Application.WorksheetFunction.の後にエクセル関数を付ければ、Excel VBAでエクセル関数をそのまま使えると解説しました。
【参考】
物流シミュレーションに必要な機能はたったこれだけ!最短距離でExcel VBAを理解【算術計算】
しかし、残念ながらこれはすべてのエクセル関数に当てはまるわけではなく、MOD関数は使えません。
その代わりに、+(足し算)、―(引き算)、*(掛け算)、/(割り算)の演算子の仲間であるMod演算子を使うことができます。
どのように使うのかと言いますと、3+2の結果を(1,1)セルに表示したい時には
Range(Cells(1,1),Cells(1,1))=3+2
でよいのに対して、3÷2の余りを(1,1)セルに表示したい場合には
Range(Cells(1,1),Cells(1,1))=3 Mod 2
とExcel VBAに記述します。
このExcel VBAを実行すれば、(1,1)セルに1が表示されることになります。
If~Then~Else文で場合分けする
次にいよいよ場合分けのIf~Then~Elseの出番です。
Ifは英語で「もし」、Thenは「であるならば」、「さもなければ」という意味です。
Excel VBAでは例えば次のように記述します。
If X Mod 2 = 0 Then
Range(Cells(1,1),Cells(1,1))=0
Else
Range(Cells(1,1),Cells(1,1))=1
End If
このプログラムの意味は、もし変数Xを2で割って余りが0ならば、(1,1)セルに0を表示して、もしそうでなければ(1,1)セルに1を表示しなさいということです。
つまり、Xが偶数ならば(1,1)には0が表示され、奇数ならば1が表示されるということになります。
このXのところに20個の売上データを順々に入れていけば、それぞれのデータが偶数か奇数かの判定ができそうですね。
条件に合うデータをカウントする
但し、これだけでは偶数の日が何日あって、奇数の日が何日あるというカウントはまだできません。
カウントするには、売上が偶数の場合には偶数のカウンタに1を足し、奇数の場合には奇数のカウンタに1を足すという処理をしてやる必要があります。
具体的には偶数カウンタをCNT1、奇数カウンタをCNT2として、次のように記述します。
CNT1 = 0 (偶数カウンタをゼロにリセットする)
CNT2 = 0 (奇数カウンタをゼロにリセットする)
For I = 1 To 20
If Range(Cells(I, 2), Cells(I, 2)) Mod 2 = 0 Then
CNT1 = CNT1 + 1 (売上が偶数ならば偶数カウンタに1を足す)
Else
CNT2 = CNT2 + 1 (売上が奇数ならば奇数カウンタに1を足す)
End If
Next I
For~NextでIを1から20まで変えて繰り返し処理をしますので、1回目は(1,2)セルに入力されている472が2で割り切れるかどうかを計算します。
割り切れますので、
CNT1 = CNT1 + 1
が実行され、CNT1が1になります。
そして、Elseの次の
CNT2 = CNT2 + 1
はスキップされて(実行されずに)End If >> Next Iへ行き、今度はIが2になって2回目のループが実行されます。
2回目のループでは(2,2)セルに入力されている206が2で割り切れるかどうかが判断されます。
割り切れますので、CNT1は1が足されて2になり、CNT2 = CNT2 + 1はまたもやスキップされますのでCNT2は0のままです。
3回目のループではIが3になりますので、(3,2)セルに入力されている41が2で割り切れるかどうかが判断されます。
今度は割り切れませんので、CNT1 = CNT1 + 1はスキップされCNT1は2のままです。
一方、CNT2 = CNT2 + 1が初めて実行されますので、CNT2は1になります。
同様に20回ループが繰り返されることによって、CNT1には偶数の回数、CNT2には奇数の回数が入ることになります。
下記のようにサンプルプログラムを記述しました。
今まで解説してきた処理しか使っていませんので、もし分からない点があれば、前回の記事と併せて読み返してみて下さい。
【参考】
物流シミュレーションに必要な機能はたったこれだけ!最短距離でマクロを理解【算術計算】
このExcel VBAを実行すると、下記のように売上が偶数の日数が9日、奇数の日数が11日と表示されます。
ランク分けしたデータ数をカウントする
次に同じ売上データを使って、売上が100個未満の日数、100個以上200個未満の日数、200個以上の日数を数えるExcel VBAを作ってみましょう。
これをするには、If~Then~Elseを入れ子で使う必要があります。
どういうことかと言いますと、
If 条件1 Then
処理1-1
If 条件2 Then
処理2-1
Else
処理2-2
End If
Else
処理1-1
End If
のようにIf~Then~Elseの中にもIf~Then~Else を入れて、2重にして使うということです。
今回の課題では次のように考えます。
売上が100個未満の日数、100個以上200個未満の日数、200個以上の日数というように3ランクの日数を数えますので、3つのカウンタを用意し、それぞれをCNT1、CNT2、CNT3と定義します。
次に売上データは(1,2)セルから(20,2)セルに入っていますので、(I,2)セルとしてIを1から20にFor~Nextで変化させます。
(1,2)セルのデータから順番に調べていきますが、まず100個以上かどうかをチェックします。
NOの場合は100個未満が決定ですので、CNT1に1を加えます。
YESの場合は100個以上であることは決定ですが、100個以上200個未満か、200個以上か分かりません。
ですので引き続き200個以上かどうかを調べます。
そしてNOであれば100個以上200個未満が決定し、CNT2に1を加えます。
YESであれば200個以上が決定しますので、CNT3に1を加えます。
そしてIに1を加え、次に(2,2)セルの値を同様にチェックしていくという手順になります。
以上をExcel VBAプログラムで書くと次のようになります。
そしてこのExcel VBAを実行させると次のようになります。
まとめ
いかがでしたでしょうか?
今回は、わざわざExcel VBAでやらなくてもエクセル関数でもできるような簡単な計算例でしたが、If~Then~ElseとFor~Nextと算術式を組み合わせることで、実は物流におけるシミュレーションのほとんどが網羅できます。
次回以降で、その応用事例を紹介していきます。