- 최초 작성일: 2000-11-17
- 최종 수정일: 2026-09-30
- 조회수: 21 회
- 작성자: 권현욱 (엑셀러)
- 강의 제목: 두 개의 콤보박스 링크하기
들어가기 전에
오래 전 엑셀 파일로 진행하던 강의를 웹 글로 복원한 것이라, "버튼을 눌러보세요"처럼 엑셀에서 직접 조작하라는 표현이 남아 있을 수 있습니다. 결과는 본문의 그림이나 표로 확인하실 수 있으며, 현재와 맞지 않는 내용은 보완하되 전반적인 스타일은 당시의 갬성(?)을 유지했습니다.
이번 시간에는 질문 하나를 살펴봅니다.
두 개의 드롭다운 박스가 있는데, 한쪽을 선택하면 그 내용에 따라 다른 한쪽의
드롭다운 박스 내용이 변경되도록 하고 싶은데 잘 안됩니다.
방법을 알려 주세요.
두 개의 콤보박스 링크하기
핵심 요약: 두 콤보박스 연동
첫 번째 콤보박스의 Change 이벤트에서 선택된 항목에 따라 두 번째 콤보박스의 RowSource를 다른 이름 정의로 바꿉니다.
- 1단계: Initialize 이벤트에서 콤보박스 초기값과 레이블을 정합니다.
- 2단계: cmbBox1_Change에서 ListIndex에 따라 cmbBox2.RowSource를 지정합니다.
- 3단계: 확인 버튼에서 입력값을 검사한 뒤 워크시트에 기록하고 컨트롤을 초기화합니다.
Step 1: 두 콤보박스를 연결하는 두 가지 방법
두 개의 콤보박스를 연결하여 사용하는 것, 즉 이쪽 콤보박스에서 어떤 항목이 선택되느냐에 따라 다른 콤보박스의 항목이 다르게 리스팅되게 하는 방법은 크게 두 가지로 나누어 볼 수 있습니다. 일반 워크시트 상에서 하는 것과, UserForm에서 하는 것이 바로 그것입니다.
일반 워크시트 상에서는 "유효성 검사"를 응용해서 "이중 유효성 검사"를 설정하는 것으로, 이것은 VB0023 강좌에서 상세히 설명을 드렸으니까 참고하시기 바랍니다.
이번 시간에는 또 한 가지 방법인 유저폼 상에서 이것을 가능하도록 하는 방법에 대해 설명을 드리도록 하겠습니다. 우선 백문이 불여일견 이니까… 아래 버튼을 눌러 예제를 실행시켜 보세요.
이 프로그램은 다음과 같은 세 부분으로 구분할 수 있습니다.
- (1) 유저폼을 띄울 때, 초기 값들을 설정하는 부분
- (2) 첫번째 콤보박스의 결과에 따라 두번째 콤보박스의 내용을 지정하는 부분
- (3) 각 항목 선택이 끝났을 때 유저폼의 선택사항들을 워크시트로 옮기는 부분
예제에 사용한 계정 시트는 아래와 같으며, 각 열에 이름이 정의되어 있어 두 번째 콤보박스의 목록으로 사용됩니다(급여, 식비, 의생활, 공과금, 육아교육, 교통비).
| 계정 | 급여 | 식비 | 의생활 | 공과금 | 육아교육 | 교통비 |
|---|---|---|---|---|---|---|
| 급여 | 월급 | 주식 | 옷 | 관리비 | 학교 | 전철 |
| 식비 | 상여금 | 부식 | 신발 | 전기 | 급식비 | 버스 |
| 의생활 | 특별 상여금 | 외식 | 잡화 | 상하수도 | 책 | 택시 |
| 공과금 | 장려금 | 기타1 | 도시가스 | 놀이방 | 기름 | |
| 육아교육 | 교통비 보조 | 기타2 | 재산세 | 학용품 | 자동차 수리 | |
| 교통비 | 교육비 보조 | 기타3 | 전화 | 장난감 | 자동차 보험 | |
| 식비 보조 | 이동 전화 | 학원1 | 자동차세 | |||
| 수당 | 호출기 | 학원2 | 면허세 | |||
| 기타1 | 난방비 | 학원3 | 주차비 | |||
| 기타2 | 기타 | 차비 | ||||
Step 2: 유저폼 만들기
이제 본격적으로 만들어 볼까요?
(1) VB Editor를 실행시키고 UserForm을 하나 삽입합니다. 아래의 그림을 참고로 필요한 컨트롤들을 그려 넣습니다.
어떤 컨트롤들이 사용되었는지 아시겠지요? 3개의 Label, 2개의 콤보박스, 1개의 텍스트박스, 2개의 커맨드버튼, 1개의 이미지 컨트롤 등 모두 4종류, 9개의 컨트롤이 사용되었습니다.
Step 3: 초기값 정의하기
(2) 유저폼이 처음 실행될 때 기본값을 정의하는 프로시저를 작성합니다. 유저폼 중에서 컨트롤이 없는 빈 영역을 더블클릭하고 이벤트 선택상자에서 Initialize 이벤트를 선택한 다음, 코드를 작성합니다.
Private Sub UserForm_Initialize()
'//유저폼의 기본값을 정의하는 프로시저입니다. 두 콤보박스의 default값으로 아무 것도
'//선택되지 않게하고 두 번째 콤보박스 위에 있는 리스트 박스의 캡션을 지정합니다.
With Me
.cmbBox1.Value = ""
.cmbBox2.Value = ""
.cmbBox1.RowSource = "계정"
.lblCost = "비목"
End With
End Sub
Step 4: 첫 번째 콤보박스 Change 이벤트 작성하기
(3) Shift + <F7>키를 눌러 유저폼을 호출하고, 첫번째 콤보박스를 클릭한 다음, 이벤트 선택 상자에서 이번에는 Change 이벤트를 선택하고 코딩을 합니다.
Private Sub cmbBox1_Change()
'//콤보박스의 Change 이벤트를 사용하여, 어떤 항목이 선택되었는가에 따라 두번째 콤보
'//박스의 RowSource 영역을 서로 다르게 지정해 줍니다.
With Me
Select Case cmbBox1.ListIndex
Case 0
.lblCost = "급여 비목"
cmbBox2.RowSource = "급여"
Case 1
.lblCost = "식비 비목"
cmbBox2.RowSource = "식비"
Case 2
.lblCost = "의생활 비목"
cmbBox2.RowSource = "의생활"
Case 3
.lblCost = "공과금 비목"
cmbBox2.RowSource = "공과금"
Case 4
.lblCost = "육아교육 비목"
cmbBox2.RowSource = "육아교육"
Case 5
.lblCost = "교통비 비목"
cmbBox2.RowSource = "교통비"
End Select
End With
End Sub
Step 5: 확인 버튼 코드 작성하기
(4) 다시 유저폼으로 돌아가서 OK 버튼을 더블클릭하고 아래의 코드를 기입합니다. 이제 이 부분은 워낙 설명을 많이 드렸기 때문에 별도의 설명이 필요없겠지요? ^^
Private Sub btnOK_Click()
Dim sht As Worksheet
Dim r As Long
Set sht = Sheets("WorkPlace")
r = Application.WorksheetFunction.CountA(sht.Range("A:A")) + 1
'//WorkPlace 시트의 A열에 순차적으로 자료를 입력하기 위해 현재 A열에 몇 개의 데이터가
'//들어 있는지 카운팅해서 거기다 1을 더해 준 수를 변수 r에 넣어 둡니다.
If txtMoney.Text = "" Or Not IsNumeric(txtMoney.Text) Then
'//[금액] 입력란에 아무 값도 입력되지 않았거나 숫자가 아닌 값이 입력되었을 경우
'//사용자에게 다시 입력하도록 하기 위한 부분입니다.
MsgBox "금액은 반드시 숫자를 입력하세요", , "금액 입력//Exceller"
With txtMoney
.SetFocus
.SelStart = 0
.SelLength = Len(.Text)
'//이렇게 설정을 해 주면 에러가 발생한 컨트롤에 Focus가 설정되면서 바로 입력할 수
'//있게 됩니다.
End With
Exit Sub
End If
sht.sht.Cells(r, 1) = cmbBox1.Value
sht.sht.Cells(r, 2) = cmbBox2.Value
sht.sht.Cells(r, 3) = Val(txtMoney.Text)
cmbBox1.Value = ""
cmbBox2.Value = ""
txtMoney.Text = ""
'//항목들이 정상적으로 선택이 되었다면 이것을 워크시트 상의 각 셀로 옮겨주고 유저폼의
'//각 컨트롤 값들을 초기화합니다.
End Sub
Step 6: 취소 버튼 코드 작성하기
마지막으로, 닫기 버튼을 클릭했을 때 유저폼을 닫는 코드를 작성합니다.
Private Sub btnCancel_Click()
Unload Me
End Sub
이 예제는 콤보박스의 RowSource에 이름 정의를 지정하는 방식입니다. 목록이 자주 늘어난다면 이름을 OFFSET 수식이나 표(테이블)로 정의하면 항목을 추가할 때 자동으로 반영됩니다.
마무리
오늘은 여기까지…
정리 — 콤보박스 연동 핵심
| 구분 | 사용한 코드 | 역할 |
|---|---|---|
| 초기화 | UserForm_Initialize | 폼이 열릴 때 기본값 설정 |
| 선택 감지 | cmbBox1_Change | 첫 콤보박스 변경 이벤트 |
| 목록 변경 | cmbBox2.RowSource = "급여" | 이름 정의를 목록으로 지정 |
| 입력 확인 | IsNumeric(txtMoney.Text) | 금액이 숫자인지 검사 |
| 다음 행 찾기 | WorksheetFunction.CountA(...) + 1 | 기록할 행 번호 계산 |
자주 묻는 질문 (FAQ)
Q1. 두 개의 콤보박스를 연결하는 방법에는 어떤 것이 있나요?
워크시트에서는 이중 유효성 검사를, 유저폼에서는 Change 이벤트와 RowSource를 이용하는 방법이 있습니다.
Q2. RowSource는 무엇인가요?
콤보박스나 리스트박스의 목록으로 사용할 셀 범위(또는 이름 정의)를 지정하는 속성입니다.
Q3. ListIndex는 무엇인가요?
목록에서 선택된 항목의 위치를 나타내는 번호이며 첫 항목은 0입니다.
마치며
Change 이벤트에서 RowSource만 바꿔 주면 두 콤보박스를 간단하게 연동할 수 있습니다.