• 최초 작성일: 2000-06-16
  • 최종 수정일: 2026-09-30
  • 조회수: 12 회
  • 작성자: 권현욱 (엑셀러)
  • 강의 제목: ListBox 메뉴 만들기

들어가기 전에

오래 전 엑셀 파일로 진행하던 강의를 웹 글로 복원한 것이라, "버튼을 눌러보세요"처럼 엑셀에서 직접 조작하라는 표현이 남아 있을 수 있습니다. 결과는 본문의 그림이나 표로 확인하실 수 있으며, 현재와 맞지 않는 내용은 보완하되 전반적인 스타일은 당시의 갬성(?)을 유지했습니다.

Microsoft사를 둘로 쪼개야 한다, 셋으로 쪼개야 한다 말들이 많군요. 또한 둘로 쪼개면 MS가 공중분해 될 것 처럼 (언론에서)호들갑입니다. 개인적인 소견으로는, 회사를 둘로 나누든, 몇 개로 나누든 간에 별일 없을 것으로 생각됩니다. 왜냐하면 각 사업단위들은 중복요소가 없는, 말 그대로 하나의 효율적인 오브젝트 단위의 조직이기 때문이지요 (직접 가보지는 않았지만 들은 얘기로 짐작컨대 말입니다).

조직 내부에 비효율적인 중복, 불필요한 요소 등을 내포하고 있었다면 아마 지금과 같은 세계적인 규모의 기업은 될 수 조차 없었을 것입니다. 아마 약간의 시간이 지나면 다시 하나의 완전한 오브젝트가 될 것입니다.세포분열을 한 아메바 같은 단세포 동물이 시간이 지나면 다시 하나의 완전한 개체가 되듯이 말입니다.

이거 얘기를 하다 보니 꼭 MS사 홍보담당 같은 느낌이 드는군요. Exceller는 MS사 와는 하등 관련이 없음을 재차 밝힙니다. ^^;

오늘 만들어 볼 유저폼은 프로시저들의 목록을 리스트박스에 나타내고 이 중 하나를 선택하면 그 프로시저가 실행되도록 하는 것입니다.

권현욱(엑셀러)
저자: 권현욱(엑셀러), 아이엑셀러 대표

필자는 Excel 컨설턴트, 작가, 그리고 크리에이터입니다. 현재 Microsoft Excel MVP이며, 『챗GPT+엑셀 업무자동화 정석』을 비롯한 10여 권의 도서를 집필했습니다. Excel 자동화 및 생산성 향상 분야에서 25년 넘는 경력을 보유하고 있습니다.

권현욱(엑셀러) 님의 최신 포스트:
  • 최신 글을 불러오는 중...


26년 경력 Microsoft MVP 권현욱(엑셀러) 대표 직강 1강 무료

🎁 파워툴스 마스터클래스 · 엑셀 바이브 코딩

AI에게 말로 지시해서 '나만의 엑셀 도구'를 만들고 리본에 장착합니다.

  • 코딩 지식 없이 시작 · 코드는 AI가 작성
  • 엑셀 리본에 내 탭과 버튼을 만들고 XLAM으로 공유
  • 1강 무료 수강 가능
수강 신청하기 강의 소개 보기

ListBox 메뉴 만들기

핵심 요약: 리스트박스 메뉴 만들기

ListIndex로 선택 위치를 알아내고 Application.Run으로 프로시저에 매개변수를 전달해 실행합니다.

  • 1단계: Initialize 이벤트에서 AddItem으로 메뉴 목록을 채웁니다.
  • 2단계: ListIndex가 0보다 작으면 미선택으로 처리합니다.
  • 3단계: Application.Run 프로시저명, 매개변수로 실행합니다.

Step 1: 유저폼 만들기

(1) VB Editor 상태에서(Alt+<F11>) UserForm을 하나 삽입합니다. (2) 유저폼에 필요한 컨트롤들을 삽입한 후 속성값을 아래처럼 바꾸어 줍니다. 보시다시피, 이 유저폼 내에는 4개의 컨트롤이 사용되었습니다.

라벨, 리스트박스, 실행하기/닫기 버튼이 있는 유저폼
아이엑셀러
컨트롤명변경할 속성변경 내용
Label1Caption실행할 메뉴를 선택하세요
ListBox1없음속성 변경 없이 크기만 적당히 조절
CommandButton1Caption실행하기
NamebtnOK
CommandButton2Caption닫기
NamebtnCancel

속성의 변경은 속성창에서 하며, 만약 속성창이 안보일 경우 <F4>키를 누르면 된다는 것은 이제 다들 아시겠지요?

Step 2: 코드 작성하기

(1) 초기화 이벤트

(3) 컨트롤을 만들고 속성값을 변경하였으면 이제 각 컨트롤에 지능을 심어주는 작업을 합니다. 컨트롤 그 자체로는 그냥 껍데기일 뿐입니다. VB 코딩작업을 통해 인공지능을 부여해 주어야 제대로 작동을 합니다.

먼저 유저폼 중에서 컨트롤이 없는 빈 영역을 더블클릭 합니다. 그러면 코드 창이 나타나는데 "이벤트 선택 메뉴"의 드롭다운 버튼을 눌러 Initialize 이벤트를 선택합니다.

코드 창의 이벤트 선택 메뉴에서 Initialize 선택
아이엑셀러

(4) 이제 Private Sub UserForm_Initialize라는 (빈) 유저폼 초기화 이벤트가 생성이 될 것입니다. 여기에다 아래와 같은 코드를 입력합니다.

Private Sub UserForm_Initialize()
    Dim i As Integer

    For i = 1 To 20
        ListBox1.AddItem "메뉴" & i
        '//AddItem 속성은 리스트박스의 아이템을 추가하는 명령어입니다.
        '//For~Next 반복문을 20번 돌면서 메뉴1, 메뉴2, 메뉴3,…,메뉴20 등 총 20개의 메뉴가
        '//리스트 박스에 Display 됩니다.
    Next i
End Sub

(2) 실행하기 버튼

(5) "실행하기" 버튼을 더블클릭 합니다. 그러면 Private Sub btnOK_Click()이라는 이벤트 프로시저가 나타나는데 다음과 같이 코딩을 합니다. 이 부분이 오늘 강좌의

Private Sub btnOK_Click()
    Dim strMenu As String
    Dim intNum As Integer

    If ListBox1.ListIndex < 0 Then
    '//ListIndex라는 새로운 속성이 하나 나왔습니다.
    '//이것은 리스트 박스 내에서 몇번째 항목이 선택되었는지 그 위치를 되돌려주는 속성입니다.
    '//즉 위의 UserForm_Initialize 프로시저의 순환문에 의해 리스트 박스 내에는 '메뉴1'에서
    '//'메뉴20'까지 20개의 아이템들이 추가가 되어 있습니다.
    '//이 중에서 메뉴2를 선택했다면 ListIndex는 1의 값을 갖게 되는 것이지요.

    '//그런데 '메뉴2를 선택했는데 왜 ListIndex값은 1을 가질까?' 이런 의문이 들지요?
    '//그것은 바로 ListIndex는 0부터 시작이 되기 때문입니다. 숫자형 변수의 경우에도 초기값은
    '//0이었지요? 그리고 배열의 경우에도 초기 시작값은 0이었습니다. 배열의 시작값을 0이 아닌
    '//1부터 시작되도록 하려면 어떻게 해야 한다고 했는지 기억이 나시는지요?
    '//그렇습니다! 모듈의 맨 위에다가 Option Base 1이라고 지정해 주면 되었지요.
    '//헷갈리지 말고 잘 기억해 두시기 바랍니다.

    '//따라서 ListBox1.ListIndex가 0보다 작다는 것은 아무 항목도 선택하지 않았을 경우입니다.
    '//그래서 아무 것도 선택하지 않았을 경우 에러표시를 해 주기 위해 위와 같은 조건이 필요한
    '//것입니다.

        MsgBox "메뉴를 제대로 선택하세요!", , "//Exceller"
        Exit Sub
    End If
    strMenu = "메뉴"
    intNum = ListBox1.ListIndex + 1
    '//여기서 왜 ListIndex에다가 1을 더해 주었을까요?
    '//그렇습니다. 리스트인덱스 속성은 0부터 시작이 되지만 UserForm_Initialize 프로시저에서
    '//메뉴를 만들 때에는 "메뉴1"부터 시작되기 때문입니다.

    Application.Run strMenu, intNum
    '//Run 메서드(Method)는 다른 매크로나 함수를 실행하는 명령입니다. strMenu에는 "메뉴"라는
    '//값이 저장되어 있으니 "메뉴" 프로시저를 호출, 즉 실행을 할 것이고, 그 뒤의 intNum변수에는
    '//현재 리스트박스 내의 선택된 메뉴의 위치가 지정이 되어 있습니다.
    '//따라서 "메뉴"라는 프로시저를 실행하되 intNum에 저장된 값을 그대로 가지고 가서 함께
    '//실행이 되는 것입니다.

    '//여기서 intNum과 같은 것을 파라미터(parameter, 매개변수)라고 합니다.
End Sub

(3) 닫기 버튼

(6) 이번에는 "닫기" 버튼을 더블클릭한 후, 아래의 코드를 입력합니다. 유저폼을 닫는 프로시저 이지요.

Private Sub btnCancel_Click()
    Unload Me
End Sub

(4) 메뉴 프로시저

(7) 이제 "삽입-모듈" 메뉴를 선택(또는 아이콘을 클릭)하여 모듈(general VBA 모듈) 시트를 하나 만듭니다.

Sub 메뉴(intNum As Integer)
    '//코드 자체는 아주 간단합니다.
    '//위 btnOK_Click 프로시저의 intNum 변수(정확히 말하면 파라미터)가 그대로 여기에서
    '//사용 되었습니다. 다른 프로시저의 값을 불러와서 사용하는 방법, 즉 파라미터 변수의
    '//사용방법을 눈여겨 보시기 바랍니다.
    MsgBox intNum & "번 메뉴를 실행했습니다"
End Sub

(5) 유저폼 호출

(8) 마지막으로, 이 유저폼을 호출하는 프로시저를 만들어 주어야 겠지요? 일반 VBA 모듈((7)에서 만든 모듈시트)에 다음의 프로시저를 하나 더 입력합니다.

Sub ShowForm()
    UserForm1.Show
End Sub

이제 워크시트로 다시 돌아와서 "도구-매크로-매크로" 메뉴를 선택(또는 "매크로 실행" 아이콘을 선택)한 다음, 위의 ShowForm 프로시저를 지정하면 실행이 될 것입니다.

마무리

오늘은 요기까지 하지요…

정리 — 리스트박스 메뉴 핵심

구분 사용한 코드 역할
항목 추가 ListBox1.AddItem "메뉴" & i 메뉴 목록 채우기
미선택 검사 ListBox1.ListIndex < 0 선택 여부 확인
번호 계산 ListBox1.ListIndex + 1 0부터 시작하는 인덱스 보정
프로시저 실행 Application.Run strMenu, intNum 매개변수와 함께 실행
폼 호출 UserForm1.Show 유저폼 표시

자주 묻는 질문 (FAQ)

Q1. ListIndex는 몇 번부터 시작하나요?

0부터 시작합니다. 메뉴2를 선택하면 ListIndex는 1입니다.

Q2. Application.Run은 무엇을 하나요?

다른 매크로나 함수를 이름으로 실행하는 메서드이며 뒤에 매개변수를 함께 전달할 수 있습니다.

Q3. 배열의 시작값을 1로 바꾸려면 어떻게 하나요?

모듈 맨 위에 Option Base 1을 지정합니다.

마치며

프로시저에 값을 전달하는 매개변수의 사용법을 눈여겨 보시기 바랍니다.