- 최초 작성일: 2003-08-14
- 최종 수정일: 2026-09-30
- 조회수: 10 회
- 작성자: 권현욱 (엑셀러)
- 강의 제목: 이름 상자 크기 조절하기 (API 함수)
들어가기 전에
오래 전 엑셀 파일로 진행하던 강의를 웹 글로 복원한 것이라, "버튼을 눌러보세요"처럼 엑셀에서 직접 조작하라는 표현이 남아 있을 수 있습니다. 결과는 본문의 그림이나 표로 확인하실 수 있으며, 현재와 맞지 않는 내용은 보완하되 전반적인 스타일은 당시의 갬성(?)을 유지했습니다.
A man is insensible to the relish of prosperity till he has tasted adversity. 인간은 역경을 겪어보기 전까지는 행복에 대해서 무신경하다.
비바람 몰아치는 궂은 날씨를 겪어봐야 좋은 날씨를 제대로 즐길 수 있고, 호경기를 지난 다음의 불경기가 더 고통스럽게 여겨지는 법이겠지요.
이름 상자 크기 조절하기 (API 함수)
핵심 요약: 이름 상자의 드롭다운 너비 늘리기
긴 이름은 이름 상자에서 잘려 보이지만 API 함수를 사용하면 드롭다운 목록의 너비를 늘려 이름을 모두 확인할 수 있습니다.
- 1단계: 필요한 API 함수(FindWindow, FindWindowEx, SendMessage)를 선언합니다.
- 2단계: InputBox로 원하는 너비(50~500)를 입력받습니다.
- 3단계: 이름 상자 콤보박스에 CB_SETDROPPEDWIDTH 메시지를 보냅니다.
Step 1: 이름 상자의 문제점
프로그래밍을 할 때 작업 대상 영역에 이름을 정의해 두고 활용하는 것은 좋은 습관이라고 시간날 때마다 강조를 드린 바 있습니다.
그런데 이름을 아주 길게 정의해 두었을 경우(예를 들어 '하늘에_조각구름_떠_있냐'라고 정의하고 위의 이름 상자 옆 드롭다운 버튼을 클릭해 보세요) 이름이 제대로 표시되지 않습니다.
이처럼 대략 16 Character를 넘어가게 되면 뒷부분이 잘려서 표시됩니다. 그런데 위의 그림과 같이 비슷한 긴 이름을 가진 여러 개의 이름이 있다고 할 경우에는 어느 것이 어느 것인지 구분할 수 없습니다(물론 '삽입-이름-정의' 메뉴를 사용하는 방법이 있기는 합니다).
이런 경우 이름 상자의 크기를 늘려서 이름을 제대로 확인할 수 있는 방법이 없을까요?
예, 없습니다!
Step 2: API 함수를 이용하면 가능합니다
하시겠지요? ^^ 엑셀 자체적으로는 방법이 없습니다만 간단한(초보님들이 보시기에는 전혀 그래보이지 않긴합니다만…) API 함수를 사용하면 가능합니다.
API라는 단어가 기억나시나 모르겠습니다. 이전 VB0093, VB0094 강좌에서 맛보기로 소개드린 적이 있습니다.
API는 Application Programming Interface의 약자로 엑셀이나 VBA 만으로는 버거운 일을 하고자 할 때(예를 들면 화면의 해상도를 바꾼다거나 레지스트리를 건든다거나 할 때) 불러다 사용할 수 있는 일종의 용병이라고 쉽게 생각하시면 되겠습니다.
예제에서 버튼을 누르고 적당한 숫자를 입력합니다. 50 ~ 500 사이의 값을 입력해야 다음 단계로 넘어가며, 입력 가능 횟수는 3번까지로 제한하였습니다. 3회 이내에 알맞은 숫자를 넣지 않으면 프로그램이 종료됩니다.
250 정도를 넣으니 이름 상자의 드롭다운 목록이 넓어져서 이름을 명확히 구분할 수 있게 되었습니다.
Step 3: 코드 살펴보기
코드를 보도록 합니다. 그리 길지는 않은 코드지만 API 함수를 불러다 사용하는 것이므로 좀 복잡해 보입니다. API 함수에 대해 관심이 있는 분은 VB0093, 94 강좌를 다시 한번 살펴보시고 관심 없는 분은 그냥 이런게 있구나 정도로만 여기셔도 지장이 없겠습니다. (아래 코드는 외국의 엑셀 고수(Chip Pearson)의 것을 수정하여 만들어 본 것입니다)
#If VBA7 Then
Public Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
Public Declare PtrSafe Function FindWindowEx Lib "user32" Alias "FindWindowExA" _
(ByVal hWnd1 As LongPtr, ByVal hWnd2 As LongPtr, _
ByVal lpsz1 As String, ByVal lpsz2 As String) As LongPtr
Public Declare PtrSafe Function SendMessage Lib "user32" Alias "SendMessageA" _
(ByVal hwnd As LongPtr, ByVal wMsg As Long, _
ByVal wParam As LongPtr, lParam As Any) As LongPtr
#Else
Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Public Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" _
(ByVal hWnd1 As Long, ByVal hWnd2 As Long, _
ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
(ByVal hwnd As Long, ByVal wMsg As Long, _
ByVal wParam As Long, lParam As Any) As Long
#End If
' 필요한 API 함수를 미리 선언해 둡니다. API 함수의 기본적인 사용 형태는 아래와 같습니다.
' Declare Function 함수명 Lib "라이브러리명" Alias "별명" (구성요소) As 리턴 타입
Sub ExpandNameBoxSize()
Dim intSize As Integer
Dim i As Integer
Const CB_SETDROPPEDWIDTH = &H160
On Error GoTo ET
' 필요한 변수 및 상수들을 선언합니다.
Do
' 이름 상자의 크기를 사용자로부터 입력받되 약간의 Entertainment 적 요소(?)를 가미하여…
' 3회 이내에 정해진 사이즈를 입력하지 않으면 그냥 종료하도록 설정하였습니다.
i = i + 1
intSize = Val(InputBox("50 ~ 500 사이의 숫자를 입력하세요. 꼭이요~~", "www.iExceller.com"))
Select Case i
Case 2: MsgBox "50 ~ 500 사이의 숫자를 입력하세요", , i & "번째 시도//www.iExceller.com"
Case 3: MsgBox "글쎄 50 ~ 500 사이의 숫자만 입력하라니까요!", , i & "번째 시도//www.iExceller.com"
Case 4
MsgBox "말 참 안듣네... 그냥 종료할래요!", , "www.iExceller.com"
Exit Sub
End Select
Loop While intSize < 50 Or intSize > 500
' 아래 부분이 문제의 API 함수입니다.
' FindWindow 함수는 지정한 클래스 명과 윈도우 명이 같은 윈도우가 발견되면 해당 윈도우의 핸들을
' 돌려주는 함수이고, FindWindowEx는 시스템 상에서 현재 수행중인 윈도우 중에서 찾으려는 윈도우를
' 검색해 주는 함수입니다. 그리고 SendMessage 함수는 파라미터로 지정된 윈도우 핸들값을 갖고 있는
' 윈도우나 컨트롤에게 지정된 메시지를 보내는 함수입니다.
SendMessage _
FindWindowEx( _
FindWindowEx( _
FindWindow("XLMAIN", Application.Caption) _
, 0, "EXCEL;", vbNullString) _
, 0, "combobox", vbNullString), _
CB_SETDROPPEDWIDTH, intSize, 0
ET:
If Err.Number <> 0 Then
MsgBox Err.Description, , "에러 번호 : " & Err.Number
Err.Clear
End If
End Sub
SendMessage, FindWindowEx, FindWindow 함수를 차례로 사용해 이름 상자 콤보박스의 핸들을 찾고, CB_SETDROPPEDWIDTH 메시지로 드롭다운 목록의 너비를 지정합니다.
참고: API 함수의 종류는 매우 많지만 모두 외울 필요는 없습니다. 어떤 것이 있는지만 알고 있다가 필요할 때 문법에 맞게 가져다 수정해서 쓰면 됩니다. 64비트 엑셀에서는 Declare 문에 PtrSafe 키워드와 LongPtr 형식이 필요하므로 위 코드에서는 조건부 컴파일로 함께 선언해 두었습니다.
만약 이름 상자의 크기를 엑셀이 시작될 때 마다 실행시키시려면 위 코드를 Personal.xls 파일 내에 auto_open 프로시저나 Workbook_Open 이벤트 핸들러 프로시저 내에 넣어두시면 되겠지요?
오늘은 여기까지…
정리 — 이름 상자 크기 조절 핵심
| 구분 | 사용한 코드 | 역할 |
|---|---|---|
| 엑셀 창 찾기 | FindWindow("XLMAIN", Application.Caption) | 엑셀 메인 창 핸들 |
| 하위 창 찾기 | FindWindowEx(...) | 이름 상자 콤보박스 핸들 |
| 메시지 전송 | SendMessage | 창에 메시지 전달 |
| 상수 | CB_SETDROPPEDWIDTH = &H160 | 드롭다운 너비 지정 |
| 입력 제한 | Do ~ Loop While | 50~500 범위 확인 |
자주 묻는 질문 (FAQ)
Q1. 이름 상자의 크기는 엑셀 기능으로 바꿀 수 없나요?
엑셀 자체 기능으로는 이름 상자의 크기를 바꿀 수 없어서 API 함수를 사용해야 합니다.
Q2. API 함수는 무엇인가요?
Application Programming Interface의 약자로, 엑셀이나 VBA만으로 하기 어려운 일을 운영체제의 함수를 불러다 처리하게 해 주는 기능입니다.
Q3. 엑셀을 시작할 때마다 자동으로 적용하려면 어떻게 하나요?
개인용 매크로 통합 문서(Personal.xls)의 Auto_Open 프로시저나 Workbook_Open 이벤트 프로시저에 이 코드를 넣어 두면 됩니다.
마치며
API 함수는 외울 필요는 없고, 어떤 기능이 가능한지 알아 두었다가 필요할 때 가져다 쓰면 됩니다.