- 최초 작성일: 2000-06-20
- 최종 수정일: 2026-09-30
- 조회수: 22 회
- 작성자: 권현욱 (엑셀러)
- 강의 제목: 특수계산기 만들기
들어가기 전에
오래 전 엑셀 파일로 진행하던 강의를 웹 글로 복원한 것이라, "버튼을 눌러보세요"처럼 엑셀에서 직접 조작하라는 표현이 남아 있을 수 있습니다. 결과는 본문의 그림이나 표로 확인하실 수 있으며, 현재와 맞지 않는 내용은 보완하되 전반적인 스타일은 당시의 갬성(?)을 유지했습니다.
우선 위의 버튼을 눌러 오늘 만들어 볼 프로그램을 실행시켜 보고 오시기 바랍니다.
이제 서서히 제대로 된 프로그램의 구조를 갖추어져 가고 있습니다. 그에 따라 조금씩 복잡해 지기도 하지요. 이번 강좌에서 만들어 볼 프로그램은 "특수계산기" 입니다.
Today's Sample 예제에서 보시다시피, 유저폼을 호출하면 사용자가 특정 영역(셈을 할 영역)을 선택하도록 합니다. 그런 다음 연산 조건과 그 값을 입력하게 되면 지정한 영역 내의 모든 유효한 셀들에 대해 지정한 연산을 해 주는 그런 계산기를 만들어 보도록 합니다. 적어도 논리적으로 따져보면 매우 단순한 개념입니다. 세부적으로 따지고 들어가면 골치가 조금씩 아파오지만 말입니다. ^^;
특수계산기 만들기
핵심 요약: 특수계산기 만들기
RefEdit로 받은 범위에서 상수 셀만 골라 옵션버튼에 따라 사칙연산을 적용합니다.
- 1단계: Initialize에서 RefEdit1에 CurrentRegion 주소를 넣습니다.
- 2단계: On Error Resume Next와 IsNumeric으로 범위와 연산값을 검증합니다.
- 3단계: Select Case True로 선택된 연산을 For Each로 적용합니다.
Step 1: 유저폼 만들기
(1) VB Editor 상태에서(Alt+<F11>) UserForm을 하나 삽입합니다. (2) 유저폼에 예제와 같은 컨트롤 들을 삽입합니다(아래 그림처럼).
위 유저폼에는 6종류, 총 11개의 컨트롤이 사용되었습니다. 좀 복잡해 보이시지요? 각각의 컨트롤 및 변경해야 할 속성에 대해 하나씩 설명을 드리겠습니다.
① Label 컨트롤
| 컨트롤명 | 변경할 속성 | 변경 내용 |
|---|---|---|
| Label1 | Caption | 1단계: 범위 지정하기 |
| Label2 | Caption | 3단계: 연산값 입력 |
② RefEdit 컨트롤
| 컨트롤명 | 변경할 속성 | 변경 내용 |
|---|---|---|
| RefEdit1 | 없음 | 속성은 변경하지 말고 크기만 적당하게 조절 |
③ Frame 컨트롤
| 컨트롤명 | 변경할 속성 | 변경 내용 |
|---|---|---|
| Frame1 | Caption | 2단계: 연산방법 지정하기 |
④ 옵션버튼(OptionButton)
| 컨트롤명 | 변경할 속성 | 변경 내용 |
|---|---|---|
| OptionButton1 | Name | optAdd |
| Caption | 더하기 | |
| OptionButton2 | Name | optSubtract |
| Caption | 빼기 | |
| OptionButton3 | Name | optMultiply |
| Caption | 곱하기 | |
| OptionButton4 | Name | optDivide |
| Caption | 나누기 |
⑤ 텍스트 박스(TextBox)
| 컨트롤명 | 변경할 속성 | 변경 내용 |
|---|---|---|
| TextBox1 | Name | txtValue |
⑥ CommandButton
| 컨트롤명 | 변경할 속성 | 변경 내용 |
|---|---|---|
| CommandButton1 | Name / Caption | btnOK / OK |
| CommandButton2 | Name / Caption | btnCancel / Cancel |
컨트롤들이 모두 추가되었으면 이제부터 각 컨트롤에 지능을 부여하는 작업을 합니다.
Step 2: 코드 작성하기
(1) 초기화 이벤트
(3) 유저폼 중에서 컨트롤이 없는 빈 영역을 더블클릭 합니다. 그러면 코드 창이 나타나는데 "이벤트 선택 메뉴"의 드롭다운 버튼을 눌러 Initialize 이벤트를 선택합니다. 이제 Private Sub UserForm_Initialize라는 유저폼의 초기화 이벤트가 생성이 되는데 여기에다 아래의 코드를 입력합니다.
Private Sub UserForm_Initialize()
RefEdit1.Text = Selection.CurrentRegion.Address
'//RefEdit1 이라는 컨트롤에다가 현재 셀이 선택되어진 영역(CurrentRegion)의 주소값을 대입합니다.
'//대입합니다. 여기서 CurrentRegion이라는 속성은 현재 선택된 셀과 접해 있는 상/하/좌/우의 모든
'//의미합니다. 이처럼 RefEdit라는 컨트롤을 사용할 때에는 CurrentRegion값을 지정해 주실 것을
'//적극 권장합니다. 그렇게 함으로써 에러 발생빈도를 낮출 수 있습니다.
End Sub
입력이 끝났으면 Shift + <F7>키를 눌러 유저폼을 호출합니다.
(2) OK 버튼
(4) 이번에는 OK 버튼을 더블클릭한 후 btnOK_Click() 이벤트 부분에 다음의 코드를 입력합니다. 이 부분이 오늘의 핵심입니다.
Private Sub btnOK_Click()
Dim rngTarget As Range
Dim rngWork As Range
Dim rngCell As Range
Dim dblOperator As Double
'//먼저 프로그램의 등장인물을 미리 정의해 두고…
On Error Resume Next
'//On Error Resume Next라는 것은 '만약에 에러가 발생하더라도 잔말말고 계속 진행하라'는 뜻입니다.
Set rngTarget = Range(RefEdit1.Text)
'//다른 변수의 경우에는 그냥 등호(=)로 값을 지정하지만 오브젝트 변수는 반드시 Set으로 지정해
'//주어야 한다는 점에 유의하시기 바랍니다.
If Err <> 0 Then
'//Err=0이라는 말은 에러가 발생하지 않았다는 말입니다. 그러므로 Err<>0라는 것은 바로 에러가
'//발생했을 경우 Then 이하의 부분을 실행하라는 뜻이지요.
MsgBox "범위를 다시 선택하세요!", , "//Exceller"
RefEdit1.SetFocus
Exit Sub
End If
If Not IsNumeric(txtValue) Then
'//If Not IsNumeric(txtValue)라는 것은 "txtValue란에 입력된 값이 숫자 형태의 값이 아니라면 ~" 이라는
'//뜻입니다. 즉 txtValue라는 텍스트 박스에 숫자 이외의 값이 입력되면 Then 이하 문장을 실행하겠지요.
MsgBox "[연산값 입력]란에는 반드시 숫자값을 입력하세요!", , "//Exceller"
txtValue.SetFocus
Exit Sub
End If
Set rngWork = rngTarget.SpecialCells(xlCellTypeConstants)
If rngWork Is Nothing Then
MsgBox "계산할 값이 없습니다!", , "//Exceller"
Exit Sub
End If
'//rngWork라는 오브젝트(정확하게는 Range 오브젝트)에 현재 선택된 영역 중에서 상수가 들어있는
'//셀만을 골라서 지정을 해 주었습니다.
dblOperator = Val(txtValue.Value)
'//사칙연산을 하기 위해 txtValue라는 텍스트 박스에 입력된 숫자 형태의 문자열 값을 완전한 숫자
'//형태로 바꾸어 주고…
Select Case True
'//이제 여기서부터는 프레임 안에 있는 네 개의 옵션 버튼과 관련된 사항입니다. Select Case문은
'//If~Then 구문에 비해 좀더 세련된 형태라고 할 수 있을 것입니다. Select Case True라는 것은
'//옵션버튼 중에 체크표시 된 것이 어느 것인지를 선별해 내는 것입니다.
'//여기서 한 가지 주의해야 할 점은, 옵션버튼들이 프레임에 의해 그루핑(Grouping) 되어져 있으면
'// 그 중에 어느 한 버튼만 선택이 되어진다는 점입니다. 그런 의미에서 옵션버튼을 예전에는 라디오
'//버튼 이라고도 불렀습니다. 라디오 채널을 생각해 보세요. 한꺼번에 하나의 주파수 만을 선택할
'//수밖에 없습니다. 그래서 붙여진 이름입니다.
Case optAdd
'Case optAdd라는 것은 'Case optAdd=True'와 같은 것입니다. 즉 optAdd 버튼이 눌려져 있으면 아래
'의 명령을 실행하고…
For Each rngCell In rngWork
rngCell.Value = rngCell.Value + dblOperator
Next rngCell
MsgBox "지정하신 대로 " & dblOperator & "만큼 더했습니다", , "//Exceller"
Case optSubtract
'optSubtract 버튼이 눌려졌으면 아래의 명령을 실행하고…
For Each rngCell In rngWork
rngCell.Value = rngCell.Value - dblOperator
Next rngCell
MsgBox "지정하신 대로 " & dblOperator & "만큼 뺐습니다", , "//Exceller"
Case optMultiply
'optMultiply 버튼이 눌려졌으면 아래의 명령을 실행하고…
For Each rngCell In rngWork
rngCell.Value = rngCell.Value * dblOperator
Next rngCell
MsgBox "지정하신 대로 " & dblOperator & "만큼 곱했습니다", , "//Exceller"
Case optDivide
'optDivide 버튼이 눌려졌으면 아래의 명령을 실행합니다.
For Each rngCell In rngWork
rngCell.Value = rngCell.Value / dblOperator
Next rngCell
MsgBox "지정하신 대로 " & dblOperator & "(으)로 나누었습니다", , "//Exceller"
End Select
Unload Me
'상황이 끝났으면 유저폼을 없애고 종료합니다.
End Sub
(3) Cancel 버튼
(5) Shift + <F7>을 눌러 유저폼을 나타낸 다음 이번에는 Cancel 버튼을 더블클릭 합니다. 코드 창에 다음의 코드를 입력합니다. 이 코드는 이제 설명을 안드려도 아시겠지요? 바로 유저폼을 종료하는 프로시저이지요.
Private Sub btnCancel_Click()
Unload Me
End Sub
(4) 유저폼 호출
Sub ShowForm()
UserForm1.Show
End Sub
마무리
이로서 특수계산기를 만드는 일련의 과정이 끝났습니다. 논리 자체는 비교적 간단하지만 한치의 오차도 허용하지 않는 치밀함이 요구되는 작업이라고 할 수 있을 것입니다. ^^;
오늘 설명드린 프로젝트만 잘 소화하신다면 웬만한 코드는 직접 짜실 수가 있을 것입니다. 설령 직접 프로그래밍은 못하시더라도 웬만한 Logic 자체는 이해하실 수 있을 것입니다. Logic을 이해한다는 것은 곧 컴퓨터와 의사소통이 자연스러워져 간다는 말입니다. 그만큼 컴퓨터에게 일을 더 잘 시킬 수 있는 개연성이 높아간다는 뜻이지요.
오늘 강좌도 한번 보고 휙 버리지 마시고 잘 보관해 두셨다가 사골 우려내듯 두번, 세번 잘 고아드시기(?) 바랍니다.
다음 시간에 또…
정리 — 특수계산기 핵심
| 구분 | 사용한 코드 | 역할 |
|---|---|---|
| 범위 기본값 | Selection.CurrentRegion.Address | 오류 발생 빈도 감소 |
| 범위 지정 | Set rngTarget = Range(RefEdit1.Text) | 오브젝트 변수는 Set 사용 |
| 숫자 검사 | IsNumeric(txtValue) | 연산값 검증 |
| 상수 셀 | SpecialCells(xlCellTypeConstants) | 상수가 있는 셀만 |
| 연산 선택 | Select Case True | 옵션버튼 판별 |
자주 묻는 질문 (FAQ)
Q1. RefEdit에 CurrentRegion을 지정하는 이유는 무엇인가요?
에러 발생 빈도를 낮추기 위해 권장되는 방법입니다.
Q2. 옵션버튼은 왜 프레임 안에 넣나요?
프레임으로 그룹핑하면 그 안에서 하나의 버튼만 선택되기 때문입니다.
Q3. 오브젝트 변수에는 왜 Set을 써야 하나요?
일반 변수는 등호로 값을 지정하지만 오브젝트 변수는 반드시 Set으로 지정해야 합니다.
마치며
한 번 보고 버리지 말고 잘 보관해 두었다가 두세 번 곱씹어 보시기 바랍니다.