EXCEL VBA

엑셀 VBA로 중복없는 무작위 숫자 생성하기, 중복없는 랜덤 숫자 생성하기

카루루1007 2024. 1. 12. 13:45
728x90
반응형

 들어가며

 

엑셀을 사용하면서 무작위 값을 생성하기 위해

RANDBETWEEN() 함수를 주로 사용합니다.

 

하지만 RANDBETWEEN() 함수의 문제

중복된 값을 거르지 못한다는 단점이 있습니다.

 

오늘은 VBA를 사용하여 

중복된 값이 없는 랜덤한 숫자를 만드는 방법을 알아보겠습니다.

 

 작동방법

 

먼저 사용자가 셀의 범위를 입력하도록 합니다.

셀의 범위는 랜덤한 숫자가 채워질 범위입니다.

 

그 다음 시작값을 입력받습니다.

시작값이란 숫자의 범위 중 작은 값을 말합니다.

예를들어 1부터 100까지의 숫자 중 랜덤으로 숫자를 추출하려 할때

시작값은 1이 됩니다.

 

그 다음 종료값을 입력을 받습니다.

종료값은 숫자의 범위 중 큰 값을 말합니다.

예를들어 1부터 100까지의 숫자 중 랜덤으로 숫자를 추출하려 할때

종료값은 100이 됩니다.

 

단, 시작값과 종료값 사이의 숫자 개수가

선택한 셀 범위의 갯수보다 작을 경우

종료값을 다시 입력받습니다.

 

예를들어 선택한 셀의 범위가 A1 ~ A3일때

셀의 숫자는 3개입니다.

그런데 1과 2 사이의 숫자를 랜덤으로 반환하려고 하면

어느 한 셀에는 중복된 숫자가 들어가게 됩니다.

이를 미연에 방지하고자 셀 범위의 갯수보다는 큰 범위의 숫자를 입력하게 했습니다.

반응형

 

 전체 소스 코드

 

Sub FillRangeWithUniqueRandomNumbers()
    Dim rng As Range
    Dim lower As Long, upper As Long
    Dim numbers() As Variant
    Dim i As Long, j As Long
    Dim tmp As Long
    Dim count As Long

    Set rng = Application.InputBox("범위를 선택하세요.", Type:=8)
    If rng Is Nothing Then Exit Sub

    lower = Application.InputBox("시작값을 입력하세요.", Type:=1)
    If lower = 0 Then Exit Sub


    Do
        upper = Application.InputBox(lower + rng.Cells.count - 1 & " 이상의 종료값을 입력하세요.", Type:=1)
        If upper = 0 Then Exit Sub
        If upper < lower + rng.Cells.count - 1 Then
            MsgBox "정해진 숫자보다 작습니다"
        End If
    Loop Until upper >= lower + rng.Cells.count - 1

    ReDim numbers(lower To upper)
    For i = lower To upper
        numbers(i) = i
    Next i

    For i = lower To upper
        j = lower + Int((upper - lower + 1) * Rnd)
        tmp = numbers(i)
        numbers(i) = numbers(j)
        numbers(j) = tmp
    Next i

    count = rng.Cells.count
    ReDim Preserve numbers(lower To lower + count - 1)

    i = lower
    For Each cell In rng
        cell.Value = numbers(i)
        i = i + 1
    Next cell
End Sub

 

 코드 분석

 

    Set rng = Application.InputBox("범위를 선택하세요.", Type:=8)
    If rng Is Nothing Then Exit Sub ' 사용자가 취소를 누르면 매크로 종료

    lower = Application.InputBox("시작값을 입력하세요.", Type:=1)
    If lower = 0 Then Exit Sub ' 사용자가 취소를 누르면 매크로 종료

InputBox를 통해 셀의 범위와 시작값을 입력받습니다.

확인을 누르면 계속 진행이 되고

취소를 누르면 매크로가 종료됩니다.

[ Type := 8 ]은 셀의 범위를 입력받을 수 있게 하는 유형을 지정한 것이고

[ Type := 1 ]은 숫자를 입력받을 수 있게 하는 유형을 지정한 것입니다.

 

    Do
        upper = Application.InputBox(lower + rng.Cells.count - 1 & " 이상의 종료값을 입력하세요.", Type:=1)
        If upper = 0 Then Exit Sub
        If upper < lower + rng.Cells.count - 1 Then
            MsgBox "정해진 숫자보다 작습니다"
        End If
    Loop Until upper >= lower + rng.Cells.count - 1

종료값을 입력을 받습니다.

셀의 범위가 [ A1 ~ B10 ]일 경우 셀의 갯수는 20개 입니다.

시작값이 1일 경우 종료값은 20 이상이 되어야 합니다.

1+20을 하면 종료값이 21이 되므로 범위내 셀 갯수보다 크므로

-1을 해서 셀의 갯수와 맞추었습니다.

 

    ReDim numbers(lower To upper)
    For i = lower To upper
        numbers(i) = i
    Next i

Redim을 사용해 배열의 크기를 동적으로 변경합니다.

그리고 for문을 사용하여 시작값과 종료값 사이의 숫자를

배열에 할당합니다.

 

    For i = lower To upper
        j = lower + Int((upper - lower + 1) * Rnd)
        tmp = numbers(i)
        numbers(i) = numbers(j)
        numbers(j) = tmp
    Next i

위 코드는 배열 numbers를 무작위로 섞는 역할을 합니다.

 

j = lower + Int((upper - lower + 1) * Rnd)

이 줄은 lower와 upper 사이의 무작위 정수를 생성하고

이를 j에 할당합니다.

rnd 함수는 0과 1사이의 무작위 실수를 반환하며

이를 upper - lower + 1에 곱하고

int 함수를 사용해 정수 부분만 취한 후 

lower를 더하면

lower과 upper 사이의 무작위 정수를 얻을 수 있습니다.

 

    count = rng.Cells.count
    ReDim Preserve numbers(lower To lower + count - 1)

이 코드는 배열의 크기를

사용자가 선택한 범위의 셀 개수에 맞게 조정하는 역할을 합니다.

 

    i = lower
    For Each cell In rng
        cell.Value = numbers(i)
        i = i + 1
    Next cell

위 코드는 각 셀에 해당 값을 입력하는 역할을 합니다.

 

여기를 방문하시면 더 많은 엑셀 관련 자료를 확인할 수 있습니다.

엑셀 공부하기
VBA 공부하기

728x90
반응형