知らずに落ちると抜け出せなくなるVBAの落とし穴です。
- シミュレーターを作ったけど結果が毎回一緒
- 乱数による分岐が毎回同じCaseに入る
あたりにお悩みの方は、この落とし穴に落ちていないかご確認ください。
Rnd関数の仕様
以下のコードを実行してみてください。
Sub 乱数生成テスト() Debug.Print Rnd End Sub
「0.7055475」が表示されたんじゃないでしょうか?
いきなり手品師みたいな問いかけから始めましたが、
種も仕掛けもなく、単純にVBAの乱数は固定になっています。
Excelを開いて最初に生成された乱数は「0.7055475」で固定で、
「0.533424」「0.5795186」・・・と続きます。
Excelを閉じるとこの生成がリセットされ、
また↑の羅列が再スタートする仕様になっています。
ExcelVBAでシミュレータなどを作成する場合は、
この仕様に注意してください。
対策 - Randomize/RandBetween
対策は簡単で、マクロの冒頭でRandomizeを実行してください。
Sub 乱数生成テスト() Randomize ' ← これを実行 Debug.Print Rnd End Sub
今回の仕様は「乱数のシードが毎回固定」であることに起因しているのですが、
Randomizeを実行するとこのシード値が更新されます。
更新されるシード値はランダムになっていますので、
これで正真正銘のランダムな値を生成してくれるようになります。
また他の対策として、シート関数のRandBetweenを使用しても良いです。
Sub 乱数生成テスト() Debug.Print WorksheetFunction.RandBetween(1, 10) End Sub
シート関数で生成する乱数は毎回別シード値で生成されますので、
特にRandomizeなどを実行せずともランダムな値を生成できます。
生成する値が整数でよいなら、こちらを使用するのが簡単ですね。
ちなみにWorksheetFunction.Randは残念ながら実装されていません。
シート関数に「RAND」はありますが、
LEFTやRIGHTと同様、同名同機能の関数がある場合は、
WorksheetFunctionは実装されない模様です。
小数0~1の乱数が欲しい場合は、
素直にRandomizeを実行してください。