본문 바로가기
VBA

[VBA] 등급별 랜덤 순번과 전체순번을 구하라

by 일등미노왕국 2022. 4. 12.

등급은 A,B,C,D,E 총 5 등급이 있다.

등급을 나누는 조건은 또 있는데 5등급을 임의로 나누어서 셀에 뿌려 놓았다.

영역 [F1:G6]는 전체 영역에서 각 등급의 구성갯수를 엑셀의 Countif를 통해서 구하였다.

 

랜덤값을 구해야 함으로 Application.Randbetween(1 to 마지막값)을 구해야 한다.

각 등급별로 마지막값이 다르므로 전체영역을 순환하면서 등급을 확인 후 해당 등급의 구성값을 끌어와서 랜덤값을 도출하여야 한다.

 

도출된 값이 기존에 있던 값인지 결과배열(임시배열)에서 찾아본 후 값이 정상적으로 도출이 된다면 값이 중복 되었다는 것이고 값이 "Error"로 도출이 된다면 중복이 되지 않았다는 뜻이므로 셀에 출력 후 다음을 위해 중복 되지 않은 값을 배열에 담아주는 방식으로 구문을 풀어가면 된다.

 

단 전체 순번을 주기 위해서는

A등급은 가장 처음이기에 등급 순번이 전체 순번이 되지만

B등급부턴 앞선 등급들의 구성의 누적합을 등급 순번에 더해줌으로서 전체순번을 구할 수 있으니 그 코드 역시 놓치지 말아야한다.

Option Explicit
Sub haja_no()
    
    Dim rngAll As Range: Set rngAll = Range([a2], [a2].End(4))   '= 전체 영역
    Dim rngA As Range                                            '= 순환개체
    Dim Cnt&, Value&, Skey$  '= Cnt: 등급크기 / Value:랜덤값 / Skey: 등급/순번 조합
    Dim str, r&, NumYesno&   '= Str값의 일치여부 / r: 결과배열의 순차순번 , NumYesno: 랜덤순번 시작여부
    Dim Vresult              '= 결과배열
    
    ReDim Vresult(1 To rngAll.Rows.Count, 1 To 1)                '= 결과 배열 재 선언
    [A1].CurrentRegion.Offset(1, 1).ClearContents                '= 초기화
    
    NumYesno = MsgBox("랜덤순번을 시작하겠습니까", vbYesNo)         '= 시작 여부
    
    If NumYesno = 6 Then                                         '= 시작을 원한다면
        For Each rngA In rngAll                                  '= 등급영역을 순환해라
        
            Cnt = Application.VLookup(rngA, [f2:g6], 2, 0)       '= 등급의 크기를 알기 위해 Vlookup으로 값 도출
haja:
            Value = Application.RandBetween(1, Cnt)              '= 등급에 맞는 Value값을 도출해라
            
            Skey = rngA & "/" & Value                            '= Skey에 키조합을 하여라
            
            str = Application.Match(Skey, Application.Index(Vresult, , 1), 0) '= 결과 배열에 키값의 존재유무 확인
            
            If TypeName(str) = "Error" Then                      '= 에러가 난다면 / 결과 배열에 값이 없다면
                                                                 '= 즉, 중복이 없다면
               rngA.Next = Value                                 '= 등급옆에 순번을 출력하고
               Select Case rngA                                  '= 등급에 따라 전체 순번을 출력하기 위해
                                                                 '= 등급의 이전 구성의 누적합과 등급 순번을 합해라
                    Case Is = "A": rngA(1, 3) = Value
                    Case Is = "B": rngA(1, 3) = Value + Application.Sum([G2])
                    Case Is = "C": rngA(1, 3) = Value + Application.Sum([G2:G3])
                    Case Is = "D": rngA(1, 3) = Value + Application.Sum([G2:G4])
                    Case Else: rngA(1, 3) = Value + Application.Sum([G2:G5])
                    
                End Select
               
               r = r + 1                                          '= 결과 배열 +1
               Vresult(r, 1) = Skey                               '= 결과 배열에 중복되지 않은 값을 담아라
               
            Else                                                  '= 만일 중복값이 있다면
               GoTo haja                                          '= Haja로 돌아가서 다시 랜덤값을 도출해라
            End If
        
        Next rngA
    End If
    MsgBox "랜덤 순번을 완성했습니다."
End Sub

등급별 랜덤값이 아닌 중복되지 않은 랜덤값을 찾으려면 본인은 주로 Collection을 이용하였는데 Collection을 이용한 로또번호나 추첨 번호를 구성하는 구문도 만들어 보는 시간을 갖기로 하겠다.

 

등급순차문제(22.04.13).xlsm
0.02MB

댓글