ここから本文です

Excel2010、VBAの質問です。 対象者リストからランダムに当選者を選ぶVBAをお教え...

lip********さん

2017/9/620:43:34

Excel2010、VBAの質問です。
対象者リストからランダムに当選者を選ぶVBAをお教えください。

たとえば対象者リストのフィールドは2列、ナンバーと氏名とします。
そこに何十名かのデータを

はりつけ、抽選を行った結果として同シート内の別の2列に当選した人たちのナンバーと氏名を表示させたいのです。

対象者リストの人数は毎回変動があります。
当選者の人数は50人で一応、毎回固定です
(手入力のセルを参照して当選人数も可変にしよう頑張りましたが自力でうまくいきませんでした…)

配列を利用するなど試みましたが動かず…お手本となるコードを頂けますと大変助かります。
どうぞよろしくお願い致します。

閲覧数:
124
回答数:
2
お礼:
500枚

違反報告

ベストアンサーに選ばれた回答

sk_********さん

2017/9/622:09:00

一つの例ですが、こんな感じでどうでしょうか。
以下の前提を満たしていれば上手く動作するはずです。
・A列にナンバー
・B列に氏名
・ナンバー、氏名はデータ間に空白がない

該当のシートをアクティブにした状態で、マクロを実行してください。
セル[D1:E50]に結果を表示します。

’ここから

Sub Sample()
Dim r As Range, lngRC As Long, v As Variant, varData As Variant
Set r = Range("A1").CurrentRegion
lngRC = r.Rows.Count
v = r.Value
Range("D1:E50").ClearContents
varData = Range("D1:E50").Value
Dim lngRnd As Long, lngCount As Long, lngValue() As Long, bolFlg() As Boolean
ReDim bolFlg(1 To lngRC)
ReDim lngValue(1 To lngRC)
Randomize
lngCount = 1
Do
lngRnd = Int(lngRC * Rnd()) + 1
If bolFlg(lngRnd) = False Then
bolFlg(lngRnd) = True
lngValue(lngCount) = lngRnd
lngCount = lngCount + 1
If lngRC < lngCount Then Exit Do
End If
Loop
If 50 < lngRC Then lngRC = 50
For lngCount = 1 To lngRC
varData(lngCount, 1) = v(lngValue(lngCount), 1)
varData(lngCount, 2) = v(lngValue(lngCount), 2)
Next
Range("D1:E50").Value = varData
Range("D1:E50").Sort Key1:=Range("D1"), Order1:=xlAscending, Header:=xlNo
End Sub

'ここまで

【簡単な解説】

Set r = Range("A1").CurrentRegion
lngRC = r.Rows.Count
ナンバー、氏名データの行数を求める

Range("D1:E50").ClearContents
varData = Range("D1:E50").Value
結果を表示するセルの値をクリア、クリアした範囲の大きさの変数を準備

ReDim bolFlg(1 To lngRC)
ReDim lngValue(1 To lngRC)
ナンバー、氏名データの行数分の配列を準備(Boolean型,Long型)

Do
lngRnd = Int(lngRC * Rnd()) + 1
If bolFlg(lngRnd) = False Then
bolFlg(lngRnd) = True
lngValue(lngCount) = lngRnd
lngCount = lngCount + 1
If lngRC < lngCount Then Exit Do
End If
Loop
配列に1~行数間の値をランダムに入れていく。値が重複しないよう、Boolean型配列変数で、チェック

For lngCount = 1 To lngRC
varData(lngCount, 1) = v(lngValue(lngCount), 1)
varData(lngCount, 2) = v(lngValue(lngCount), 2)
Next
結果表示用配列に、先に配列に格納したランダムを元に、最初のナンバー、氏名データから値を引っ張ってくる

Range("D1:E50").Sort Key1:=Range("D1"), Order1:=xlAscending, Header:=xlNo
並べ替え

一つの例ですが、こんな感じでどうでしょうか。
以下の前提を満たしていれば上手く動作するはずです。...

  • 質問者

    lip********さん

    2017/9/713:51:36

    動きました!
    簡潔なコードで驚きました、ありがとうございます!とても勉強になりましたし、仕事でも助かりました。
    これからじっくり内容の確認もして、学ばせて頂きます。すぐにご回答くださってありがとうございました。

返信を取り消しますが
よろしいですか?

  • 取り消す
  • キャンセル

質問した人からのコメント

2017/9/7 13:54:19

ご回答くださったお二方とも、ご親切にありがとうございました。いずれのご回答も大変助かりました。
VBAのコードを教えてくださったsk_tamotu様にベストアンサーとさせて頂きます。

ベストアンサー以外の回答

1〜1件/1件中

the********さん

2017/9/622:38:40

VBA有りきですか?それとも関数で出来るならVBAじゃなくてもいい?
既にソースをいただいているようなので、別の切り口です。
自身、VBAでしか出来ないと思ってて、関数でも出来ると知ってエエェェ(゚Д゚)ェェエエて事が多いので笑

職務上、似たような事した事してます。
C列に、=INT(RAND()*100000)
それをオートフィル。
C列をコピーして、そのままC列に「値で貼り付け」(または数式タブの計算方法を「手動」)。
これで、C列全行に0〜99999までのランダムな値がありますので、昇順なり降順なりで並び替えて、上位50名(行)当選みたいな感じです。
※値で貼り付け、または計算を手動にしないと、並び替えた時点でまた乱数の関数が実行されちゃいます。

で、それをコピペ。
答えになってなくてすいませんが、参考までに!

返信を取り消しますが
よろしいですか?

  • 取り消す
  • キャンセル

みんなで作る知恵袋 悩みや疑問、なんでも気軽にきいちゃおう!

Q&Aをキーワードで検索:

Yahoo! JAPANは、回答に記載された内容の信ぴょう性、正確性を保証しておりません。
お客様自身の責任と判断で、ご利用ください。
本文はここまでです このページの先頭へ

「追加する」ボタンを押してください。

閉じる

※知恵コレクションに追加された質問は選択されたID/ニックネームのMy知恵袋で確認できます。

不適切な投稿でないことを報告しました。

閉じる