Excel VBAの「Rnd関数」について解説します。
Rnd関数とは
Excel VBA の Rnd関数とは、単精度浮動小数点数型(Single型)の疑似乱数( 0 以上 1 未満の値)を返します。
Rnd 関数(Visual Basic for Applications リファレンス)
疑似乱数とは
乱数とは「規則性のない数字」です。乱数の例としてよく取り上げられるのは、サイコロの出目です。サイコロを振って出る数字は何回振っても適当で規則性がありません。
疑似乱数とは「乱数に見えるようにコンピュータでそれっぽくつくった数字」言い換えると「規則性がないように見えるけど実際には規則性がある数字」です。
実際は「乱数」として扱っているケースのほとんどが「疑似乱数」と言ってもよいかもしれません。
構文(引数と戻り値)
Excel VBAの関数を使いこなすには、関数の構文を理解しておくことが重要です。
構文
Rnd[(number)]
※ [ ] は省略可能を意味します。
引数と戻り値
引数:(number) は省略可能です。
- number には単精度浮動小数点数型(Single)の数値 または 数値式を指定します。
戻り値:number の値によって Rnd が擬似乱数を生成する方法を次のように決定します。
number | Rnd関数が返す値(Single型) |
---|---|
負の値 | number をシード値とした乱数の値を返します (同じシード値なら常に同じ乱数の値となります) |
正の値 | 【省略時の既定】次の乱数の値を返します |
0 | 直前に生成した乱数の値を返します |
解説
Rnd 関数は、引数 number の値によって 0 以上 1 未満の擬似乱数を生成する方法を決定します。
引数に「負の値」を指定した場合
「負の値」が引数(number)の場合は、その値をシード値として特定の演算(疑似ランダムシーケンス)で乱数を生成します。シード値とは、疑似乱数の生成に使用される初期値のことです。
シード値が固定ならば、発生する乱数はまったく同じものとなります。乱数を固定したい場合に利用できます。
引数が「正の値」または「省略」の場合
引数(number)が「正の値」と「省略」の戻り値は同じです。
Excel起動時のシード値は固定されているので毎回同じ結果になるので注意が必要です。Rnd関数を最初に実行する際のシード値にこの値が使われてしまうからです。「負の値」の引数を指定したのと同じように、初期シードが同じなので、同じ番号シーケンスが生成されます。これは、Rnd 関数を連続して呼び出すたびに、シーケンス内の次の値のシードとして、前の値が使用されるためです。
次の画像がテスト検証してみたものです。
test_01 のコードを実行後に「リセット」してから test_02 のコードを実行したものです。
test_02 では、Rnd(Rnd)とすることで、最初の Rnd の結果をシード値にした Rnd の値が返っています。test_01 の結果と比較してみるとその動きが良くわかると思います。
しかし、毎回同じ結果になってしまうのでは乱数の意味がありません。初期シード値を変更する必要があります。
Randomizeステートメントで初期シードを変更する
Rnd関数を呼び出す前に、Randomizeステートメントを使用することで、シード値をシステムタイマーから返される値に変更させることができます。
Randomize ステートメント(Visual Basic for Applications リファレンス)
任意の範囲でランダムな整数を生成する
指定した範囲の中でランダムな整数(整数の乱数)を生成するには、次の式を使用します。
Int((上限値 – 下限値 + 1) * Rnd + 下限値)
Rnd関数が返す値は、ランダムな 0 ~ 1 未満の値(小数)です。その値に範囲値を掛けて+1 した値の小数部分を取り除く Int関数 または Fix関数を利用すれば整数値の乱数になります。
上のコードでは、Rnd(0) で直前に生成した乱数の値を使って整数値を算出しています。
使用例
乱数を連続生成する例です。実用的には一定の範囲内の整数で使うことが多いと思います。Rnd関数の戻り値は小数なので、それをどう処理すれば良いのかを見てください。
使用例1(同じ乱数を取得する)
次のサンプルコードは、Rnd関数の引数に「負の値」を指定して毎回同じ2桁の乱数を発生させる例です。1桁の場合は範囲の指定部分を(0~9などに)調整します。
'毎回同じ乱数を取得する例
Sub RndSample_01()
Dim i As Long
Dim rndArr As String
'負の数を引数にして初期シード値を固定
Rnd (-1)
'範囲10~99の初期乱数を文字列に代入
rndArr = Int((99 - 51 + 1) * Rnd + 51)
For i = 2 To 10
'範囲10~99の乱数をコンマ区切りで文字列として結合
rndArr = rndArr & "," & Int((99 - 51 + 1) * Rnd + 51)
Next
MsgBox rndArr
End Sub
何度実行しても同じ乱数の文字列が表示されます。変更すれるには、引数の「負の値」を変える必要があります。
使用例2(違う乱数を発生させる)
Rnd関数の引数は「省略」しますが、Randomizeステートメントを事前に置いてシード値を初期化することで実行毎に違う乱数を発生させる例です。
'毎回違う乱数を発生させる例
Sub rndSample_02()
Dim i As Long
Dim rndArr As String
'シード値初期化
Randomize
'範囲10~50の初期乱数を文字列に代入
rndArr = Int((50 - 10 + 1) * Rnd + 10)
For i = 2 To 10
'範囲10~50の乱数をコンマ区切りで文字列として結合
rndArr = rndArr & "," & Int((50 - 10 + 1) * Rnd + 10)
Next
MsgBox rndArr
End Sub
実行する度に、違う乱数の文字列が表示されます。
Rnd関数を使っている例
Rnd関数を利用している過去の記事がこちらです。
おわりに
Excel VBA「Rnd関数」で疑似乱数を生成する方法について解説しました。
乱数を固定したい場合は、引数に「負の値」を指定すれば初期シード値が固定されます。
毎回違う乱数を発生させたい場合は、Rnd関数実行前に Randomizeステートメントを使うことで初期シード値を変更することができます。
Rnd関数の戻り値は小数( 0 以上 1 未満の値)なので、整数にする場合は Int関数 か Fix関数を利用します。使用例のサンプルコードでは、欲しい乱数の範囲と個数を指定して取得する例を紹介しました。
この解説が、少しでもみなさまのお役に立てたなら幸いです(^^;
VBAサンプルファイルはダウンロードできます
このページで使用したサンプルファイルの登録はありません(^^;
ダウンロードページへトップリンクは下のカードクリックでジャンプできます。
よろしければご利用ください!