Excel VBAで重複しないランダムな数字を生成するマクロ
趣味でエクセルVBAを使ってあるツールを作ってたとき、重複しないランダムな数(乱数)を生成する必要があり、他のWebサイトを見ながら調べました。それと同じものですが、備忘録がわりに以下にコードを載せます。
早速、コードは以下です。
このコードは数字の1から指定した任意の数まで、1回ずつランダムに数字が生成されます。生成したい数の最大値は、変数MaxNumで指定します(たとえば、1から10までの乱数を生成したいなら“MaxNum = 10”とする)
このコードを丸ごとコピペして、標準モジュールに張り付けて実行すればセルA1からA10までランダムに1から10までの数字が1回ずつ入力されます。
5つ乱数がほしい場合は、"For i = 1 To MaxNum"の部分の”1 To MaxNum”を”1 to 5”とすればOKです。
簡単な解説
おそらくほかの方の記事で解説があるかと思いますし、解説するほどでもないのですが、念のため触れておきます。
配列の要素数を再定義するReDim
最初に以下の記述があると思います。
ReDim Number(1 To MaxNum) As Long
ReDim flg(1 To MaxNum) As Boolean
Number()という配列は、生成したランダムな数字を格納していく配列です。ReDimは最初の決めた配列の要素数を再定義するための宣言です。もちろんこの要素数を最初のDimの段階で定義してももちろん動作しますが、プログラムの途中で要素数を変更する必要もあるかもしれませんし、この記述をしたほうが他のプログラムなどへの移植性や柔軟性を考えた際に便利です。
乱数の生成
ランダムな数の生成を行っているのは“num = Int(Rnd * MaxNum) + 1”の部分です。MaxNumを10とすると、1から10までのランダムな数値が変数numに格納されます。
単にランダムな数字がほしいのであればこの1行でOKです。ただ、これだと重複が発生するかもしれません。そこで必要になるのが次の記述です。
重複を避けるための処理
If flg(num) = False Then
flg(num) = True
Number(i) = num
Exit Do
End If
前の項でランダムな数字numが出現したら、配列変数のflg()の[num]番をフラグオンにしておき、「その[num]番はすでに使いましたよ」という目印を立てておくのです。
ランダムな数字はNumber()という配列変数にどんどん格納してきます。ただし、上記の5行のコードをみてわかるように、それは flg()がフラグオフ(=まだ一度もその数字が出現していない)でなければ実行されません。Do Loopをかけているので、無事にNumberに格納されない限り繰り返されます。
以上が簡単な解説です。ランダムな数字の生成は、業務で使用するツールにはまず出てくることはないでしょうけど、私のようにExcelでの簡単なゲームとかくだらないツール作るときには頻出なので備忘録としてここに記しました。