- ベストアンサー
VBAマクロに詳しい方助けてください!
Excel2007で乱数を使ったマクロを組んだのですが、同じ数字が繰り返し出力されて困っています。詳しい方、どうか解明をお願いします。 やりたいこと: 100分の1の確率で抽選を繰り返し、当たり(乱数で1が発生したら当たりとする)がでたら「何回目の抽選で当選したか」をセルA1に記入し、セルA2に移行して同じ抽選をやり直す。その作業をA10000まで続ける。 作成したマクロ: Sub 百分の一抽選() Dim r, cou, ransuu As Integer For r = 1 To 10000 'A1 からA10000まで繰り返す For cou = 1 To 10000 '↑100分の1の確率で当たり(1を当たりとする)が出るまで繰り返す Randomize '乱数初期化 ransuu = Int(Rnd() * 100) + 1 '1から100までの乱数を作成 If ransuu = 1 Then '乱数で1が発生したら当たりとしてセルに記入 Cells(r, 1) = cou Exit For '当たりが出たのでひとつ下のセルでの抽選に移行 End If Next Next End Sub マクロを走らせた結果: 62,43,110,103,43,110,103,43,110,8,94,47,115・・・ 上記のように同じ数字のカタマリができてしまいます。 もちろん乱数ですので連続したり重複したりするでしょうが、 あまりに同じパターンが繰り返されるのでどこかおかしいのだと思います。 マクロを実行するたびに数字はかわるのですが、やはりカタマリになります。 作成・動作環境はWinXP,Excel2007(ファイル自体は.xlsで作成),Core2Duo2.20GHz,メモリ2GBです。 ほかのExcelのバージョンでも試してみましたが同じような結果です。 当方VBA歴3年ほどですが、わけがわからずに不思議でなりません。 詳しい方、ぜひ解明をお願いします。同じマクロ使っても現象が起きないようでしたら こちらの環境のせいだと思われるので、そういったご指摘でもかまいません。 よろしくお願いいたします。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
こんにちは。 Randomize で、乱数ジェネレータで、初期化して、同じものをまた呼び出しているからです。ヘルプでは、Randomize ステートメントで、引数に同じ値を使用しても、前の乱数系列を繰り返すことはできません、と書かれていますが、実際には、コンピュータで扱うものは、「自然乱数」ではなく、区間を区切った「一様乱数」を使っているので、Randomize を頻繁に使うと同じものを呼び出す結果になってしまいます。 したがって、 Randomize '乱数初期化 '←これは、ある一定の場所では、繰り返してはならないわけです。 なお、私なら、このように書きます。 まあ、無限ループにはならないことを信じますが、1が出るまでですから、気が遠くなるような先かもしれません。(^^; Sub 百分の一抽選R() Dim i As Long Dim j As Long 'Integerにすれば、無限ループは回避されます Dim Ransuu As Integer Application.ScreenUpdating = False Randomize For i = 1 To 10000 Do j = j + 1 Ransuu = Int(Rnd() * 100) + 1 Loop While Ransuu <> 1 Cells(i, 1).Value = j j = 0 Next i Application.ScreenUpdating = True End Sub
その他の回答 (2)
- okg00
- ベストアンサー率39% (1322/3338)
For r = 1 To 10000 テストのためにto 100にしてました。修正してください。 #1の補足 乱数は初期化するたびに同じ並びになります。randomizeは引数省略するとシステムタイマーになるようですが、同じ引数を与えれば同じ乱数列になるんじゃないかな?システムタイマーといえど有限ですから、同じ引数になることはよくあるでしょうね。未確認ですが。
お礼
修正してコピペしました。 ありがとうございます。
- okg00
- ベストアンサー率39% (1322/3338)
Sub 百分の一抽選() Dim r, cou, ransuu As Integer Randomize '乱数初期化 For r = 1 To 100 'A1 からA10000まで繰り返す For cou = 1 To 10000 '↑100分の1の確率で当たり(1を当たりとする)が出るまで繰り返す ransuu = Int(Rnd() * 100) + 1 '1から100までの乱数を作成 If ransuu = 1 Then '乱数で1が発生したら当たりとしてセルに記入 Cells(r, 1) = cou Exit For '当たりが出たのでひとつ下のセルでの抽選に移行 End If Next Next End Sub ループのたびにrandomizeで初期化してるから、そのたびに乱数列が初期化されているようです。上記のようにしてみました。
お礼
okg00様、ありがとうございます。 明日くらいに解決できればいいなーと思っていたのですが こんなすぐに教えていただけるとは思っていませんでした。 修正したいただいたコードはそのままコピペさせていただきます。 勉強になりました。 ありがとうございます。
お礼
Wendy02様、ありがとうございました。 一様乱数!!!そうだったんですねぇ。 つどつど乱数を出してるのかと思っていました。 あまりに同じ数字が出るのでムキになってRandomizeしてたりしましたが逆効果だったんですね。(^^; とても勉強になりました。ありがとうございました。