重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

電子書籍の厳選無料作品が豊富!

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年ほどですが、わけがわからずに不思議でなりません。
詳しい方、ぜひ解明をお願いします。同じマクロ使っても現象が起きないようでしたら
こちらの環境のせいだと思われるので、そういったご指摘でもかまいません。

よろしくお願いいたします。

A 回答 (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
    • good
    • 0
この回答へのお礼

Wendy02様、ありがとうございました。
一様乱数!!!そうだったんですねぇ。
つどつど乱数を出してるのかと思っていました。
あまりに同じ数字が出るのでムキになってRandomizeしてたりしましたが逆効果だったんですね。(^^;
とても勉強になりました。ありがとうございました。

お礼日時:2008/05/08 17:15

For r = 1 To 10000



テストのためにto 100にしてました。修正してください。

#1の補足
乱数は初期化するたびに同じ並びになります。randomizeは引数省略するとシステムタイマーになるようですが、同じ引数を与えれば同じ乱数列になるんじゃないかな?システムタイマーといえど有限ですから、同じ引数になることはよくあるでしょうね。未確認ですが。
    • good
    • 0
この回答へのお礼

修正してコピペしました。
ありがとうございます。

お礼日時:2008/05/08 17:32

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で初期化してるから、そのたびに乱数列が初期化されているようです。上記のようにしてみました。
    • good
    • 0
この回答へのお礼

okg00様、ありがとうございます。
明日くらいに解決できればいいなーと思っていたのですが
こんなすぐに教えていただけるとは思っていませんでした。
修正したいただいたコードはそのままコピペさせていただきます。
勉強になりました。
ありがとうございます。

お礼日時:2008/05/08 17:31

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!