Randomize を忘れずに!

Randomize を忘れずに!

 今まで説明していなかったステートメントが1つありますね。

Randomize

です。この記述について説明する前に、簡単なプロシージャを仮定して Rnd がどのようなはたらきをするか具体的に見てみます。

  Sub 乱数発生テスト1()
   Worksheets("いつ").Range("A1:A3").Value = Rnd
  End Sub

このようなマクロを実行すると A1 から A3 まで

0.7055475
0.7055475
0.7055475

と同じ数字が縦並びします。前回に「 Range プロパティで複数のセルを選択すると、選択されたセルがまとめて1つのオブジェクトとして扱われます」と説明しました。「乱数発生テスト1」マクロでは、複数セルに対して同じ乱数を格納してしまいます。これは論外な記述方法です。乱数は1回1回発生させて、それを1つ1つのセルに収めていかないといけません。というわけで、

  Sub 乱数発生テスト2()
   With Worksheets("いつ")
   .Range("A1").Value = Rnd
   .Range("A2").Value = Rnd
   .Range("A3").Value = Rnd
   End With
  End Sub

 このようなマクロを作ってみます。実行すると

0.7055475
0.5334240
0.5795186

 ちゃんと別々の数字が割り当てられていますね。でもねえ ... でもですねえ ... いったんエクセルを終了し、再起動させて、もう1度同じマクロを実行してみると ......

0.7055475
0.5334240
0.5795186

 こんなふうになってしまいますよ。さっきと全く同じです。
 「乱数と違うしー!」と叫びたくなりますね。これでは全く使い物になりません。

 実は Rnd は本物の乱数ではなく、シード値を使った疑似乱数を発生させるステートメントなのです。厄介なことに Rnd にはエクセルを再起動するたびに同じシード値が入ります。同じ種を使うと同じ乱数が発生します(当たり前です)。

 うーん。困りましたね。そこで登場するのが

Randomize

というステートメントです。 Randomize を忘れずに記述しておけば、システムタイマーから現在時刻を取得して、その値を種として Rnd が乱数を発生させてくれます。これはとても大切なステートメントなのです。
 
 マクロを実行して全てのデータに乱数が割り当てられていることを確認してください。ことあと、前回の「いつどこゲーム」マクロに「乱数割当」というサブルーチンを追加しておきます。今回は引数はありません。

 Sub いつどこゲーム()

 乱数割当
 並び替え 1
 並び替え 2
 並び替え 3
 並び替え 4
 
 End Sub

 これを実行すると「データに乱数を割り振って、並べ替えをして、いつどこ文章を完成させる」というマクロができます。しかし、それでは最初にマクロを実行したあとに、シートに乱数が残ってしまいます。最後のひと仕事が必要です。次回は「割り当てられた乱数を消すマクロ」を作ります。
 

[補足] Rnd 関数の使い方

 マクロの中で乱数を使うぶんには、「 Randomize を忘れずに」の記事内容で十分だとは思いますが、きちんと VBA を学びたい人のために、もう少しだけ詳しいお話を付け加えておきます。実は Rnd 関数は、Rnd(数値) という形で数値のところに引数にシード値を指定できます。引数に正数 1 を指定してみます:

  Sub 乱数発生テスト3()

   Worksheets("いつ").Range("A1").Value = Rnd(1)

  End Sub

というマクロを実行すると、セル A1 に

0.7055475

という値が出力されます。「 Rnd のときと一緒じゃん!」と思われるでしょうね。その通り。実は全く同じなんです。引数に正の値を入れると、その数値が何であれ、同じ乱数系列の値を順番に返します。なので特にシード値を指定しない場合は、() を省略します。ややこしいのですが、シード値を入れたい場合は、引数に負の値を入れなければなりません。試しに -1 を指定してみます。

  Sub 乱数発生テスト4()

   Worksheets("いつ").Range("A1").Value = Rnd(-1)

  End Sub

これを実行すると、

0.2240070

という、Rnd とは異なった値を出力してくれます。

 続いて、Excel ファイルを閉じずに

  Sub 乱数発生テスト5()
   Worksheets("いつ").Range("A1").Value = Rnd(0)
  End Sub

というマクロを実行すると、

0.2240070

という値を返します。Rnd() の引数に 0 を指定すると直前に出力した乱数と同じ値を返します。実用上の観点から見ると、Rnd(数値) の形で Rnd を使うのは「引数に負の値を入れて特定の乱数テーブルを得たい」ときに限られると思います。

スポンサードリンク
末尾大型広告
末尾大型広告

コメントをどうぞ

メールアドレスが公開されることはありません。

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)