Excel (VBA)

Excel VBAに関するフォーラムです。
  • 解決済みのトピックにはコメントできません。
このトピックは解決済みです。
質問

 
(Windows 10 Home : Excel 2019)
母体からグループ毎に数を決めて抽出したい【再掲】
投稿日時: 22/11/21 02:39:25
投稿者: oga21

数日前に、町内会の抽選会に利用したくて、次のような質問をしました。
 
例えば、1000人の名簿から、Aグループ20人、Bグループ15人、・・・というように、数を決めてランダムに抽出する方法は、Excelで可能でしょうか?ちなみに抽出数の合計は100人で、グループ数は15です。
名簿は、
1 ○○さん A
2 ××さん A
3 □□さん B
4 △△さん B
5 ●●さん C
・ ・・・・ ・
・ ・・・・ ・
というような一覧表です。よろしくお願いします。
 
 
その後、半平太さんから次のようにご回答頂きました。
 
一般機能でも、下の手順で出来そうですけどね。。
  
1.グループ別の当選者数を下図(G1:I2)の様に埋める(サンプルでは、3グループ、計10人)
2.C2セルに=RAND() と入力して、フィルダウン
3.C列全体をコピーして、値の貼付け
  
4.乱数にダブりがないか、D2に数式を入れて、念のため確認する。
  D2セル =IF(OR(COUNTIF(C2:C1200,C2:C1200)>1),"有","無")
  
5.G3セル =XLOOKUP(TAKE(SORT(FILTER($C$2:$C$1200,$B$2:$B$1200=G1)),G2),$C$2:$C$1200,$A$2:$A$1200,"")
  と入力して、右へコピー
  
<結果図>
行 ___A___ ____B____ _______C_______ __D__ _E_ ____F____ ___G___ ___H___ ___I___
 1 氏名 グループ 乱数生成後値化 重複 グループ A B C
 2 Name01 A 0.594714537 無 当選者数 5 2 3
 3 Name02 A 0.554952974 Name07 Name12 Name14
 4 Name03 A 0.323293225 Name03 Name09 Name16
 5 Name04 A 0.723990988 Name02 Name13
 6 Name05 A 0.974484221 Name01
 7 Name06 A 0.939029356 Name04
 8 Name07 A 0.085922578
 9 Name08 B 0.94932929
10 Name09 B 0.264407234
11 Name10 B 0.564305458
12 Name11 B 0.554734358
13 Name12 B 0.030535968
14 Name13 C 0.478480494
15 Name14 C 0.058312015
16 Name15 C 0.82291206
17 Name16 C 0.153581672
 
 
小生のPCでは問題なく動作したのですが、町内会のPCがEXCEL2019だったため、XLOOKUPは動作しませんでした。
お恥ずかしい話ですが、EXCEL019でも上記のような抽出が可能でしょうか。
よろしくお願いいたします。

回答
投稿日時: 22/11/21 11:02:29
投稿者: 半平太

Microsoft 365 じゃないと数式では面倒なので、本来のVBAにします。
 
1.「作業」と言う名前のシートを一枚挿入してください。
2.基本データが入っているシートを「抽選」と言うシート名に変えてください。
3.抽選シートは下図の様にデータをセットしてください。
 
<抽選 シート 初期状態>

行  ___A___  ____B____  _C_  ____D____  _E_  _F_  _G_  _H_  _I_
 1  氏名     グループ        グループ   A   B   C   ・   ・ 
 2  Name01    A            当選者数    5    2    3   ・   ・ 
 3  Name02    A                                             
   :   :

4.後記VBA(lottery)を実行する
 
<抽選 シート 実行後の結果例>
行 ___A___ ____B____ _C_ ____D____ ___E___ ___F___ ___G___ _H_ _I_
 1 氏名    グループ      グループ   A      B      C     ・  ・ 
 2 Name01     A         当選者数     5       2       3     ・  ・ 
 3 Name02     A                   Name07  Name08  Name14         
 4 Name03     A                   Name03  Name11  Name16         
 5 Name04     A                   Name01          Name15         
 6 Name05     A                   Name02                         
 7 Name06     A                   Name04                         
 8 Name07     A                                                  

5.標準モジュールに貼り付けるVBA
Sub lottery()
    Dim ws抽選 As Worksheet
    Dim ws作業 As Worksheet
    Dim lastRW As Long, gTopRW
    Dim Grp As Range
    Dim rToSearch As Range
    
    Set ws抽選 = Worksheets("抽選")
    Set ws作業 = Worksheets("作業")
    
    ws作業.Range("A1") = "Dummy"
    ws作業.UsedRange.ClearContents
    
    With ws抽選
        Intersect(.UsedRange.Offset(1), .Columns("A:C")).Copy ws作業.Range("A1")
    End With
    
    With ws作業
        lastRW = .Cells(Rows.Count, "A").End(xlUp).Row
        
        With .Range("C1:C" & lastRW)
            .FormulaLocal = "=RAND()"
            .Value = .Value
        End With
        
        .Range("D1").FormulaArray = "=IF(OR(COUNTIF(C1:C1500,C1:C1500)>1),""有"",""無"")"
        
        If .Range("D1") = "有" Then
            MsgBox "乱数に重複があります。再試行してください"
            Exit Sub
        End If
        
        .Sort.SortFields.Clear
        .Sort.SortFields.Add Key:=.Range("B1"), Order:=xlAscending
        .Sort.SortFields.Add Key:=.Range("C1"), Order:=xlAscending
        
        .Sort.SetRange .Range("A1:C" & lastRW)
        .Sort.Header = xlNo
        .Sort.Apply
        
        ws抽選.Range("E3").Resize(lastRW, 100).ClearContents
        
        Set rToSearch = .Range("B1:B" & lastRW)
        
        For Each Grp In ws抽選.Range("E1", ws抽選.Cells(1, 100).End(xlToLeft))
            gTopRW = Application.Match(Grp, rToSearch, 0)
            
            If IsNumeric(gTopRW) Then
                With Grp
                    ws作業.Cells(gTopRW, "A").Resize(.Offset(1)).Copy Grp.Offset(2)
                End With
            End If
        Next Grp
    End With
End Sub

投稿日時: 22/11/21 14:36:05
投稿者: oga21

半平太さん、ありがとうございます。
結構大変そうですが、頑張ってみます。

投稿日時: 22/11/21 15:07:12
投稿者: oga21

半平太さん、出来ました!
大変助かりました。ありがとうございました。