- 최초 작성일: 2008-05-15
- 최종 수정일: 2026-09-30
- 조회수: 32 회
- 작성자: 권현욱 (엑셀러)
- 강의 제목: 간단 경품추첨기 만들기
들어가기 전에
오래 전 엑셀 파일로 진행하던 강의를 웹 글로 복원한 것이라, "버튼을 눌러보세요"처럼 엑셀에서 직접 조작하라는 표현이 남아 있을 수 있습니다. 결과는 본문의 그림이나 표로 확인하실 수 있으며, 현재와 맞지 않는 내용은 보완하되 전반적인 스타일은 당시의 갬성(?)을 유지했습니다.
질문 메일을 어딘가에 잘 뒀는데 너무 잘 둔 나머지 기억조차 나질 않는군요. ^^;
기억을 더듬어 보면…(요즘 기억 참 자주 더듬습니다)
세미나가 끝날 때 참석자들 중 몇 명을 뽑아서 경품을 주고 싶은데 그냥 밋밋하게 이름 불러서 주는 것 말고 뭔가 좀 비주얼하게 할 방법이 없나요…?
하는 내용이었습니다.
간단 경품추첨기 만들기
핵심 요약: 유저폼으로 만드는 Go!/Stop! 경품추첨기
유저폼 하나와 버튼 하나로 사번이 빠르게 돌아가다 멈추면 당첨자 이름이 나타나는 경품추첨기를 만듭니다. 버튼 캡션을 Go!와 Stop!으로 번갈아 바꾸는 것이 핵심입니다.
- 1단계: 유저폼에 레이블 2개와 Go!, 닫기 버튼을 배치합니다.
- 2단계: Workplace 시트의 사번을 배열 변수에 담습니다.
- 3단계: Go!를 누르면 Rnd로 뽑은 사번을 계속 표시하고, Stop!을 누르면 해당 사원의 이름을 보여줍니다.
Step 1: 완성된 경품추첨기 살펴보기
아래 버튼을 클릭한 다음, 유저폼에서 "Go!"와 "Stop!" 버튼을 번갈아가며 눌러 보세요.
세련미는 좀 떨어지는 감이 있습니다만, 그래도 상자에서 명함이나 탁구공(?)을 꺼내는 것보다는 비주얼하고 재미가 있지 않나요? ^^
Step 2: 유저폼 만들기
어떤 과정을 통해 만들었는지 살펴보겠습니다.
먼저, VB Editor 상태에서 유저폼을 하나 삽입하고 다음 그림을 참고로 필요한 컨트롤을 삽입합니다. 어떤 컨트롤의 속성을 어떻게 바꾸어 주었는지는 VB Editor로 가서 확인해 보세요.
참고 - 예제 파일 구성: 코드에 사용된 컨트롤은 검은색 배경의 lblDisplay 레이블(돌아가는 사번 표시), cmdOK 버튼(Go!/Stop! 전환), 그리고 당첨자를 보여주는 lblName 레이블입니다. 데이터는 Workplace 시트의 A열에 사번, B열에 이름이 입력되어 있고, 첫 번째 사번이 들어 있는 A1 셀에 'Start'라는 이름이 정의되어 있습니다.
Step 3: 'Go!' 버튼 코드 작성하기
'Go!' 버튼을 클릭하고 다음과 같은 코드를 작성합니다.
Dim blnGoStop As Boolean
' 프로시저 바깥 쪽에 선언을 하여 다른 프로시저에서도 사용할 수 있도록 합니다.
Private Sub cmdOK_Click()
Dim rngNum As Range
Dim i As Integer
Dim intNum As Integer
Dim strNum() As String
Dim rngCell As Range
On Error GoTo ET
lblName.Caption = ""
Set rngNum = Worksheets("Workplace").Columns(1).SpecialCells(xlTextValues)
' Workplace 시트의 A열 중 값이 들어있는 데이터를 작업 대상 영역으로 합니다.
intNum = rngNum.Cells.Count
ReDim strNum(1 To intNum)
' rngNum 영역의 셀 수가 파악되었으므로 strNum 배열 변수의 크기를 재선언합니다.
For i = 1 To intNum
' 순환문을 돌면서 직원들의 사원번호(혹은 좌석번호나 고유의 일련번호 등)를 배열 변수에
' 차례로 담아둡니다.
strNum(i) = Range("Start").Offset(i - 1)
Next i
If cmdOK.Caption = "Go!" Then
' cmdOK 버튼의 캡션이 'Go!'로 되어 있다면 이것을 'Stop!'으로 바꾸어 줍니다.
cmdOK.Caption = "Stop!"
blnGoStop = False
Randomize
Do Until blnGoStop
' 사용자가 버튼을 누를 때까지 lblDisplay 레이블에 임의의 사원번호를 계속 보여줍니다.
lblDisplay.Caption = strNum(Int(Rnd * (UBound(strNum) - LBound(strNum) + 1) + LBound(strNum)))
DoEvents
Loop
Else
' Stop 버튼을 클릭한 경우에 대한 처리입니다.
' 랜덤하게 선택된 사번에 해당되는 사원의 이름을 lblDisplay 레이블에 표시합니다.
blnGoStop = True
cmdOK.Caption = "Go!"
If lblDisplay.Caption <> "" Then
Set rngCell = rngNum.Find(lblDisplay.Caption, LookIn:=xlValues).Offset(0, 1)
If Not rngCell Is Nothing Then _
lblName = vbCrLf & "축하합니다" & vbCrLf & rngCell.Value & "님!"
End If
End If
ET:
If Err.Number <> 0 Then
MsgBox Err.Description, , "오류 번호 : " & Err.Number
Err.Clear
End If
End Sub
원문 오류 수정: 사번을 무작위로 뽑는 수식이 Rnd * (UBound(strNum) - LBound(strNum))로 되어 있으면 마지막 순번의 사번은 절대 뽑히지 않습니다. 배열 크기가 N이라면 Int(Rnd * (N - 1) + 1)의 결과는 1 ~ N-1이기 때문입니다. 위 코드에서는 + 1을 추가하여 모든 사번이 추첨 대상이 되도록 바로잡았습니다.
이것 말고도 몇 개의 프로시저가 더 필요한데… '닫기' 버튼에 연결된 코드나 UserForm_Initialize 이벤트 핸들러 프로시저의 코드는 직접 확인해 보시기 바랍니다. 따로 설명드릴 것도 없을 만큼 아주 간단한 코드입니다.
오늘은 여기까지…
정리 — 경품추첨기 코드 핵심
| 구분 | 사용한 코드 | 역할 |
|---|---|---|
| 모듈 수준 변수 | Dim blnGoStop As Boolean | Go!/Stop! 상태를 여러 프로시저에서 공유 |
| 대상 영역 지정 | Columns(1).SpecialCells(xlTextValues) | A열에서 값이 들어 있는 셀만 작업 영역으로 지정 |
| 사번 담기 | strNum(i) = Range("Start").Offset(i - 1) | 사번을 차례로 배열에 저장 |
| 무작위 표시 | Randomize, Rnd, DoEvents | 버튼을 누를 때까지 임의의 사번을 계속 표시 |
| 당첨자 찾기 | rngNum.Find(...).Offset(0, 1) | Stop! 시점의 사번 오른쪽 셀에서 이름을 가져옴 |
자주 묻는 질문 (FAQ)
Q1. Go! 버튼을 누르면 화면이 멈춘 것처럼 보입니다.
Do Until 순환문 안에 DoEvents가 있어야 순환문이 도는 동안에도 Stop! 버튼의 클릭을 처리할 수 있습니다. DoEvents 구문이 빠지지 않았는지 확인하세요.
Q2. 이미 당첨된 사람이 또 뽑히지 않게 하려면 어떻게 하나요?
당첨자가 결정될 때마다 해당 사번을 다른 열에 기록하거나 배열에서 제외하는 방법을 사용하면 됩니다. 예를 들어 당첨된 행에 표시를 해 두고 사번을 배열에 담을 때 표시가 없는 행만 담도록 바꿔 보세요.
Q3. 사번 대신 좌석번호나 일련번호로 추첨해도 되나요?
됩니다. 코드는 A열의 값을 무작위로 보여주고 B열의 값을 결과로 표시할 뿐이므로, A열에 좌석번호나 일련번호를, B열에 표시할 이름을 넣어 두면 그대로 사용할 수 있습니다.
마치며
유저폼 하나에 버튼 캡션 전환만으로도 제법 그럴듯한 경품추첨기가 완성됩니다. 행사 분위기에 맞게 색상이나 글꼴을 꾸며서 여러분만의 추첨기를 만들어 보세요!