- 최초 작성일: 2000-06-15
- 최종 수정일: 2026-09-30
- 조회수: 20 회
- 작성자: 권현욱 (엑셀러)
- 강의 제목: 스피너와 텍스트 박스의 만남
들어가기 전에
오래 전 엑셀 파일로 진행하던 강의를 웹 글로 복원한 것이라, "버튼을 눌러보세요"처럼 엑셀에서 직접 조작하라는 표현이 남아 있을 수 있습니다. 결과는 본문의 그림이나 표로 확인하실 수 있으며, 현재와 맞지 않는 내용은 보완하되 전반적인 스타일은 당시의 갬성(?)을 유지했습니다.
컴퓨터를 셈틀, 소프트웨어를 무른모, 오브젝트를 객체(또는 개체)라고 영어를 굳이 우리말로 번역해서 부르는 경향이 있는데, 제 개인적으로는 별로 내키지가 않습니다. 국제화 시대에 한글 도메인이 생겨서 "유숭준.com" 등과 같은 도메인이 생겨나는 것도 마찬가집니다. 중국같은 나라는 자기네 한자를 키보드로 입력하기가 힘드니까 숫자 도메인명(http:123.com 등)을 만들어 가면서까지 국제화의 추세에 편승하려고 기를 쓰는데 우리는 어찌된 게…
영어를 우리말로 바꾸어 부르는 것이 애국이라고 생각해서인지, 아니면 영어만 보면 본능적(!)으로 한글로 번역을 해야지만 직성이 풀려서인지는 모르겠지만 애써 번역해 놓은 것을 보면 미묘한 뉘앙스를 제대로 살리지 못한 경우가 거의 대부분이지요.
'회전자'라는 용어도 그런 것이 아닌가 생각됩니다. 그냥 스피너(Spinner)라고 하면 좋을 것을 왜 굳이 이것 을 '회전자'라는 우리말도 아닌, 국적불명의 말로 고쳐 부르는지 알다가도 모를 일입니다.
하여튼 이런저런 연유로 해서 용어를 가급적이면 원어 그대로 부르도록 하겠습니다. 영어에 알레르기(이것도 원어에 충실하려면 알러지라 해야 맞겠지요 ^^)가 있어서 안된다 하시는 분이 있으면 연락주세요. 그런 분이 많으시면 다른 방법을 찾아야지요. 앞으로는 회전자와 스피너(스핀버튼), 텍스트 상자와 텍스트 박스… 등을 혼용해서 사용하겠습니다.
오늘이 한글날도 아닌데 좀 흥분했습니다. 한글날에 더 흥분하도록(?) 하고 흥분을 여기서 접습니다.
스피너와 텍스트 박스의 만남
핵심 요약: 스피너와 텍스트 박스 연동
스피너는 현재 값을 표시할 수 없으므로 텍스트 박스와 연동합니다. 초기화, 양쪽 Change 이벤트, 확인 버튼의 유효성 검사 순서로 작성합니다.
- 초기화: UserForm_Initialize에서 Min, Max, 초기 Value를 지정합니다.
- 연동: SpinButton1_Change와 TextBox1_Change로 두 컨트롤의 값을 같게 유지합니다.
- 확인: btnOK_Click에서 값이 같으면 ActiveCell에 기록하고 폼을 닫습니다.
- 오류 처리: 유효하지 않으면 메시지를 띄우고 SetFocus, SelStart, SelLength로 텍스트를 선택합니다.
Step 1: 스피너와 텍스트 박스의 만남
스피너와 텍스트 박스의 만남이라… 이번 강좌 제목은 좀 낭만적(?) 이지요? 일단 아래 버튼을 눌러 오늘 만들어 볼 유저폼에 대해 살펴보고 오시기 바랍니다.
잘 보셨는지요? 이것이 우리가 이번 시간에 만들어 볼 내용입니다. 스피너(회전자)는 Value라는 속성(프로퍼티)을 가지고 있습니다. 그래서 버튼을 누르면 값(Value)이 차례로 증가(또는 감소)하게 되는 것입니다.
그런데 희한하게도 이 스피너는 현재 값이 얼마가 선택되었는지 볼 수 있는 다른 도구를 제공하지 않습니다. 혹시 기억하시는지 모르겠지만 워크시트 상에서 "양식" 도구모음에 있는 스피너를 사용할 때에도 꼭 "컨트롤 서식-셀 연결" 항목을 선택해서 다른 셀에 연결을 해야지만 현재 값을 볼 수가 있었지요?(회전자의 기본적인 사항에 대해서는 "이런 기능 아세요? X0047 강좌"를 참고하세요)
기업은 항상 고객을 염두에 두고 제품을 만들어야 하듯이 프로그래머는 사용자의 관점에서 프로그램을 짜야 합니다. 아무리 우수한 기능을 갖춘 노벨 프로그래밍상 받을 만한 소프트웨어라도 디자인이 엉성 하거나, 개발자 위주로 만들어져서 인터페이스가 엉망이거나 하면 당연히 고객으로부터 외면을 당하기 마련 이지요!!!
Step 2: 유저폼 디자인하기
- VB Editor 창을 띄운 상태에서 UserForm을 하나 삽입합니다.
- 아래 그림과 같이 유저폼의 적당한 위치에 레이블, 텍스트 박스, 스피너, 명령 버튼 등의 컨트롤을 그려 넣습니다.
명령 단추를 클릭하면 속성 창이 나타나는데(만약 나타나지 않으면 F4 키를 누르세요) 속성 중에서 Caption 속성을 클릭해서 OK로, Accelerator 속성을 선택해서 O(알파벳 O), 이름 속성을 btnOK로 각각 바꾸어 줍니다(다른 컨트롤의 속성은 그냥 그대로 둡니다).
Step 3: 프로그래밍하기
자, 이제부터 본격적인 프로그래밍에 들어갑니다.
(1) 유저폼 코드 창 열기
유저폼 중에서 컨트롤이 없는 빈 영역 아무데나 더블클릭을 합니다. 그러면 그림처럼 코드 모듈이 나타날 것입니다.
(2) UserForm_Initialize 프로시저 작성하기
여기서 이벤트 선택 단추(그림 오른쪽 위의 [Click] 드롭다운을 제가 붙여본 이름입니다)를 눌러서 Initialize를 선택합니다. 그러면 Private Sub UserForm_Initialize()라는 프로시저(이것을 유저폼 초기화 프로시져라고 합니다)가 나타나는데 이 부분에 아래와 같이 코드를 입력합니다.
Private Sub UserForm_Initialize()
With SpinButton1
.Min = 1
.Max = 1000
Label1.Caption = .Min & "~" & .Max & "사이의 수를 선택(또는 입력) 하세요"
.Value = 1
TextBox1.Text = .Value
End With
End Sub
코드는 크게 어려운 부분이 없을 것입니다. 먼저, SpinButton1 컨트롤의 최소값(Min)과 최대값(Max) 속성을 1과 1000으로 각각 지정을 해 주었습니다. 그 다음에, Label1 컨트롤의 캡션을 설정하고 초기값(Value)을 1로 지정해 준 다음 그 값을 텍스트 박스에 그대로 뿌려주게 하였지요.
유저폼의 초기화 모듈 입력작업이 끝났으면 Shift + F7을 눌러 유저폼으로 돌아갑니다.
(3) 스피너 Change 이벤트 작성하기
이번에는 스피너를 더블클릭 합니다. 이번에는 SpinButton1_Change()라는 프로시저가 나타나는데 아래와 같이 입력을 해 줍니다.
Private Sub SpinButton1_Change()
TextBox1.Text = SpinButton1.Value
'스피너의 값을 텍스트 박스로 옮겨주는 작업입니다.
End Sub
입력한 다음에는 다시 Shift + F7을 눌러 유저폼으로 돌아갑니다.
(4) 텍스트 박스 Change 이벤트 작성하기
이제 텍스트 박스를 더블클릭 하고 아래와 같이 코드를 입력합니다.
Private Sub TextBox1_Change()
Dim intNum As Integer
intNum = Val(TextBox1.Text)
'변수를 하나 선언해 준 다음, 텍스트 박스의 값을 intNum에 담아 두었지요?
'여기서 Val() 함수는 숫자 형태의 문자열 자료를 숫자로 바꾸어 주는 VB 함수입니다.
If intNum >= SpinButton1.Min And intNum <= SpinButton1.Max Then SpinButton1.Value = intNum
'intNum값, 즉 텍스트 박스 내에 있는 값이 스피너의 최대값과 최소값 범위 내에 있는 것이라면
'스피너의 값을 intNum값으로 대치합니다. 왜 대치를 하느냐 하면 스피너의 값과 텍스트 박스의 값이
'서로 따로 놀지 않고 같도록 해주기 위해서 입니다.
End Sub
다시 Shift + F7을 눌러 유저폼으로 돌아갑니다.
(5) 명령 버튼 Click 이벤트 작성하기
마지막으로, 명령 버튼을 더블클릭하게 되면 btnOK_Click()이라는 이벤트 핸들러 프로시저가 생성이 되는데 아래와 같은 코드를 넣어줍니다. 사실 이 부분이 이 프로젝트의 핵심입니다.
Private Sub btnOK_Click()
If CStr(SpinButton1.Value) = TextBox1 Then
ActiveCell = SpinButton1.Value
Unload Me
'CStr() 함수는 숫자 데이터를 문자 형태로 바꾸어 주는 VB 함수입니다. 스피너의 값은 항상 숫자 형태이고
'텍스트 박스의 자료는 항상 문자 형태이므로 이 두 컨트롤의 Value값을 비교해 주려면 형식을 통일시켜
'주어야 합니다. 따라서 CStr(SpinButton1.Value)와 같이 써 준 것이지요. 이 구문을
'If SpinButton1.Value=Val(TextBox1)과 같이 해 주어도 같은 결과를 얻을 수 있습니다.
'따라서 두 컨트롤의 Value 값을 비교해서 같으면 현재 셀에 스피너의 값을 기입하고 Unload 하게 되지요.
Else
MsgBox "유효하지 않은 숫자입니다!!!", , "//Exceller"
'만약 그렇지 않으면 메시지 박스를 띄우고 이하의 명령을 실행하게 되는데 그렇지 않은 경우란 어떤 경우
'를 말할까요?… 예를 들어 텍스트 박스에다가 1001이라고 타이핑을 해 보세요. 텍스트 박스의 최소값은 1,
'최대값은 1000으로 지정이 되어 있습니다.(누가 어디서 지정을 했냐고요? UserForm_Initialize 프로시저
'에서 Min, Max 속성으로 지정을 해 주었었지요?)
TextBox1.SetFocus
TextBox1.SelStart = 0
TextBox1.SelLength = Len(TextBox1.Text)
'SetFocus라는 것은 유저폼 내에서 포인터를 TextBox1에 고정시키는 속성이고,
'SelStart는 텍스트 박스의 시작값을 지정해 주는 속성입니다.
'SelLength라는 속성은 텍스트 박스의 선택된 문자의 수를 나타내는 속성입니다.
End If
End Sub
참고: 위 코드에서는 텍스트 박스의 내용을 Val()로 바꾸기 때문에 "12abc" 같은 값도 12로 인식됩니다. 엄격하게 숫자만 받으려면 IsNumeric()으로 먼저 검사하시면 됩니다. 또한 폼을 띄우려면 모듈에 아래와 같은 프로시저가 필요합니다. 그림의 폼 이름은 UserForm2이지만 새로 삽입하면 UserForm1이 되므로, 실제 폼 이름에 맞춰 사용하세요.
Sub ShowSpinForm()
UserForm1.Show
End Sub
여기까지 제대로 입력을 하셨다면 유저폼을 호출하여 (유효한) 숫자를 입력(또는 선택)을 할 경우, 현재 셀포인터가 위치한 셀(즉 ActiveCell)에 지정한 값이 출력이 되는 것입니다.
마무리
다음 시간에는 또다른 재미있는 것을 해보도록 하지요.
오늘은 여기까지…
정리 — 스피너와 텍스트 박스 연동 핵심
| 구분 | 코드 | 역할 |
|---|---|---|
| 범위 지정 | .Min = 1 / .Max = 1000 | 스피너 값 범위 |
| 값 표시 | TextBox1.Text = SpinButton1.Value | 스피너 → 텍스트 박스 |
| 값 변환 | Val(TextBox1.Text) | 문자열 → 숫자 |
| 값 비교 | CStr(SpinButton1.Value) = TextBox1 | 형식 통일 후 비교 |
| 커서 이동 | TextBox1.SetFocus | 텍스트 박스에 포인터 고정 |
자주 묻는 질문 (FAQ)
Q1. 스피너 값은 어떻게 확인하나요?
스피너 자체에는 현재 값을 보여주는 기능이 없으므로 텍스트 박스나 레이블 등 다른 컨트롤에 값을 표시해야 합니다.
Q2. Val()과 CStr()의 차이는 무엇인가요?
Val()은 숫자 형태의 문자열을 숫자로, CStr()은 숫자를 문자열로 바꾸어 줍니다.
Q3. UserForm_Initialize는 언제 실행되나요?
유저폼이 Show 메서드로 로딩될 때 자동으로 실행되어, 컨트롤의 초기값을 설정하기에 적합합니다.
마치며
이 예제를 제대로 입력하면 유저폼에서 유효한 숫자를 입력하거나 선택했을 때 현재 셀에 그 값이 출력됩니다.