- 최초 작성일: 2001-08-29
- 최종 수정일: 2026-09-30
- 조회수: 16 회
- 작성자: 권현욱 (엑셀러)
- 강의 제목: 엑셀로 못하는게 머야 시리즈(2) - 주소록 관리
들어가기 전에
오래 전 엑셀 파일로 진행하던 강의를 웹 글로 복원한 것이라, "버튼을 눌러보세요"처럼 엑셀에서 직접 조작하라는 표현이 남아 있을 수 있습니다. 결과는 본문의 그림이나 표로 확인하실 수 있으며, 현재와 맞지 않는 내용은 보완하되 전반적인 스타일은 당시의 갬성(?)을 유지했습니다.
Excel로 무슨 일을 할 수 있느냐는 질문을 가끔 받습니다. 아주 오래 전에 길을 지나가는데 약장사처럼 생긴 어떤 장사꾼이 길에 좌판을 펴놓고 호객행위를 하는 광경을 보았습니다. 가까이 가서 보니까 접착제(일명 뽄드) 장사꾼이었습니다. 다른 것은 기억나지 않고,
"... 이 본드로 붙일 수 없는 것이 세 가지가 있습니다. 저는 절대로 거짓말을 하지 않습니다. 안되는 것은 안되는 것이니까... 그렇다면 그 세 가지가 도대체 무어냐? 첫번째, 물과 불은 붙일 수 없습니다. 두번째로 하늘과 땅도 붙일 수 없습니다. 그리고 마지막으로 남자와 여자도 붙일 수 없습니다. 이 세 가지 말고는 다 해결됩니다..."
Exceller가 무슨 얘기를 할려고 본드 장사 기억을 들추어 냈는 지 짐작이 가시지요? ^^ 엑셀로 무엇을 해야할 지 모르겠다고 하는 것은 다른 말로 하면 문제의식이 없다는 말과 상통할 것입니다. 자신의 생각이 구체화되지 않았다는 얘깁니다.
비디오나 영화를 보더라도 아무 생각없이(때론 그것도 필요하지만...) 그냥 멍하니 보지 말고 정리를 해 보세요.
| 제목 | 감독 | 주연 | 감상일자 | Theme | 감상 내용 |
|---|---|---|---|---|---|
| … | … | … | … | … | … |
이렇게 한 몇 년간 정리를 해 본다면 영화평론가가 될 지도 모르지요. 만약 여러분이 영업 사원이라면,
| 거래처명 | 전화번호 | 점주 성향 | 출현 시간 | 가족 관계 | 취미 | 생일 | 결혼기념일 | 방문일자 | 상담 내용 | 지급 판촉물 |
|---|---|---|---|---|---|---|---|---|---|---|
| … | … | … | … | … | … | … | … | … | … | … |
거래처를 방문할 때마다 이런 식으로 한 2~3년만 정리를 해 놓으면 이것은 엄청난 재산이 될 것입니다. 요즘 기업에서 화두 중 하나인 고객관계관리(CRM, Customer Relationship Management)가 별건가요? 이런 것이 바로 CRM이지. 이제는 구멍가게를 하나 하더라도 고객 DB가 없으면 못 해먹는 세상이 되었습니다.
이런 말도 있지요. "동네 대소사를 잘 아는 거지는 굶어죽지 않는다"고 (가만있자... 이것은 Exceller가 지어낸 말인가? ^^). 하여튼 거지도 동냥질 할 고객 DB가 구축되어 있어야 먹고 살 수 있는 그런 세상이 되었습니다.
무슨 얘기를 하다가 또 여기까지 왔지? 하여튼 중요한 것은 엑셀은 여러분의 생각을 정리하고 구체화시키기에는 더없이 좋은 도구입니다. 여러분 주변의 무엇이든 좋으니까 작은 것이라도 잘 정리해 두는 습관을 기르시기 바랍니다.
사설은 이쯤에서 접고... 오늘 진도 나갑니다. 엑셀로 주소록 관리를 하는 분이 많은 것 같습니다. 어떤 분이 질문을 해 오셨는데,
엑셀로 못하는게 머야 시리즈(2) - 주소록 관리
핵심 요약: 자음별 주소록 필터
자음 버튼의 캡션을 Application.Caller로 읽어 자음별 글자 범위를 정한 뒤 이름의 첫 글자가 그 범위에 속하면 다른 위치로 추출합니다.
- 1단계: 양식 도구모음으로 14개의 자음 버튼을 만들고 캡션과 이름을 지정합니다.
- 2단계: Select Case로 누른 버튼을 구분해 FilterByConsonant를 호출합니다.
- 3단계: Left(rngCell, 1)이 지정한 범위에 속하는 레코드를 추출합니다.
Step 1: 이번 시간의 질문
"엑셀로 주소록 관리를 하는데 버튼을 딱 누르면 이름이 "ㄱ"으로 시작되는
사람만 출력되고, 또 다른 버튼을 탁 치면 이름이 "ㄴ"으로 시작되는
사람들만 나타나도록 할 수 없겠느냐"고 하신 분이 있었습니다.
당연히 있겠지요? 버튼을 눌러 예제를 살펴보고 오세요.
예제 주소록 데이터 일부 펼쳐 보기 (Workplace 시트 A1:E8)
| NO | 고객명 | 주소 | 전화번호 | 성별 |
|---|---|---|---|---|
| 1 | 갑돌이 | 서울시 강남구 | 504-4919 | 남 |
| 2 | 을돌이 | 서울시 강남구 | 881-8251 | 남 |
| 3 | 병돌이 | 서울시 강남구 | 550-5462 | 남 |
| 4 | 정돌이 | 서울시 강남구 | 872-8868 | 남 |
| 5 | 무돌이 | 서울시 강남구 | 074-1606 | 남 |
| 6 | 기돌이 | 서울시 강남구 | 035-9497 | 남 |
| 7 | 경돌이 | 서울시 강남구 | 148-7339 | 남 |
Step 2: 버튼 만들기
그럼 만들어 보도록 하지요. (1) '보기-도구 모음-양식'을 선택하여 양식 도구모음이 나타나도록 합니다.
(2) '단추' 아이콘을 클릭하고 적당한 크기로 단추를 하나 그립니다. 한글의 자음이 14개니까 14개의 버튼을 그려야 겠군요. 일일이 그리기가 귀찮으면 복사를 하시든가...
(3) 14개의 버튼을 그리셨으면 각 버튼의 캡션을 ㄱ, ㄴ, ㄷ,... 등과 같이 바꾸어 줍니다.
(4) 이제 각 버튼의 이름을 지어 줍니다. 가, 나, 다,... 하 이런 식으로. 버튼의 이름을 어떻게 지어 주냐구요? 이러면 곤란한데... 버튼을 그린 다음 '이름 상자'에 '가'라고 입력하고 엔터키를 탁 치시면 되지요?
Step 3: ConsonantOrderFiltering 프로시저
(5) 14개 버튼에 대해 캡션과 이름 정의가 끝났으면 이제부터 코딩 작업에 들어갑니다. Alt + <F11> 키를 눌러 VB Editor 상태를 만듭니다. '삽입- 모듈' 메뉴를 클릭하여 모듈 시트를 한장 삽입하고 아래와 같은 코드를 작성합니다.
Sub ConsonantOrderFiltering()
With ActiveSheet
.[G1:K1].EntireColumn.ClearContents
'''[G1:K1]은 Range("G1:K1")의 다른 표현입니다.
Select Case .Buttons(Application.Caller).Caption
Case "ㄱ"
Call FilterByConsonant("ㄱ", "가", "깋")
'''Workplace 시트에 있는 버튼 중 하나를 클릭하면 Application.Caller, 즉
'''눌려진 버튼의 캡션을 파악합니다. 그래서 ㄱ 버튼이 눌려 졌으면 다른
''' 프로시저를 호출합니다. 이 때 앞에 Call이라는 명령어는 아주 예전에
'''BASIC(Visual Basic 말고) 시절부터 사용되던 것으로 다른 프로시저를
'''호출한다는 것을 시각적으로 알려주는 단서(Visual Clue)가 되는 것입니다.
'''생략해도 프로그램의 실행과는 아무 상관이 없습니다. 다만 인수를 넘겨
'''주지 않을 때에는 그냥 Call FilterByConsonant와 같이 사용하지만 인수를
'''넘길 때에는 반드시 괄호로 둘러싸 주어야 한다는 점에 주의하세요.
'''나머지 아래 구문은 같은 내용이 반복되는 것입니다. 어떤 버튼이 선택되어
'''졌느냐에 따라 넘겨주는 인수의 값이 약간씩 다를 뿐입니다.
Case "ㄴ"
Call FilterByConsonant("ㄴ", "나", "닣")
Case "ㄷ"
Call FilterByConsonant("ㄷ", "다", "띻")
Case "ㄹ"
Call FilterByConsonant("ㄹ", "라", "링")
Case "ㅁ"
Call FilterByConsonant("ㅁ", "마", "밓")
Case "ㅂ"
Call FilterByConsonant("ㅂ", "바", "삫")
Case "ㅅ"
Call FilterByConsonant("ㅅ", "사", "앃")
Case "ㅇ"
Call FilterByConsonant("ㅇ", "아", "잏")
Case "ㅈ"
Call FilterByConsonant("ㅈ", "자", "찧")
Case "ㅊ"
Call FilterByConsonant("ㅊ", "차", "칳")
Case "ㅋ"
Call FilterByConsonant("ㅋ", "카", "킿")
Case "ㅌ"
Call FilterByConsonant("ㅌ", "타", "팋")
Case "ㅍ"
Call FilterByConsonant("ㅍ", "파", "핗")
Case "ㅎ"
Call FilterByConsonant("ㅎ", "하", "힣")
Case Else
'''Doing Nothing
End Select
End With
End Sub
Step 4: FilterByConsonant 프로시저
(6) 위에서 호출한 FilterByConsonant 프로시저를 작성합니다.
Sub FilterByConsonant(strFilter As String, strFirst As String, strSecond As String)
'''위의 프로시저에서 세 개의 변수를 넘겨주었으므로 받을 때도 세 개의 변수를 받습니다.
Dim rngCell As Range, rngTarget As Range
Dim r As Integer
Dim Msg As String
Set rngTarget = Range([B2], [B2].End(xlDown))
'''주소록의 이름이 들어있는 부분을 rngTarget이라는 Range 오브젝트로 지정합니다.
[G7:K7] = Array("NO", "고객명", "주소", "전화번호", "성별")
For Each rngCell In rngTarget
Select Case Left(rngCell, 1)
'''rngTarget 오브젝트 내의 각 셀값을 하나씩 검사하여 지정한 조건을 충족하는
'''경우에만 아래의 작업을 수행합니다.
Case strFirst To strSecond
'''만약 'ㄱ' 버튼을 클릭하였다면 strFirst에는 "가", strSecond 변수에는 "갛"이라는
'''값이 들어가 있겠지요? 그러므로 rngCell값의 맨 앞 글자값이 가~갛 범위 내에
'''포함되는 지를 검사하여 조건을 충족하면 소스 테이블 내의 해당 레코드 중에서
'''다른 필드값을 가져오는 것입니다.
With [Start]
.Offset(r, 0) = rngCell.Offset(0, -1)
.Offset(r, 1) = rngCell.Offset(0, 0)
.Offset(r, 2) = rngCell.Offset(0, 1)
.Offset(r, 3) = rngCell.Offset(0, 2)
.Offset(r, 4) = rngCell.Offset(0, 3)
End With
r = r + 1
Case Else
'''Doing Nothing
End Select
Next rngCell
Msg = Msg & """" & strFilter & """(으)로 시작되는 이름은 모두 " & r & " 명 입니다"
MsgBox Msg, , "작업 완료//By Exceller"
End Sub
마무리
처음 생각해 내기가 어렵지 그 나머지는 아무 것도 아닙니다. 문제를 구체화, 단순화 시키는 노력들을 많이 해 보시기 바랍니다. 잘 정리된 문제는 반은 해결된 것이지요.
다음 시간에 또...
정리 — 주소록 자음 필터 핵심
| 구분 | 사용한 코드 | 역할 |
|---|---|---|
| 눌린 버튼 | .Buttons(Application.Caller).Caption | 버튼 캡션 확인 |
| 프로시저 호출 | Call FilterByConsonant("ㄱ", "가", "깋") | 자음과 글자 범위 전달 |
| 첫 글자 검사 | Select Case Left(rngCell, 1) | 이름의 첫 글자 비교 |
| 범위 조건 | Case strFirst To strSecond | 가~깋 범위 검사 |
| 결과 기록 | With [Start] .Offset(r, 0) = … | 조건에 맞는 레코드 입력 |
자주 묻는 질문 (FAQ)
Q1. 이름이 특정 자음(ㄱ, ㄴ…)으로 시작하는 사람만 골라내려면?
자음별로 시작 글자와 끝 글자(예: 가~깋)를 정해 두고 이름의 첫 글자가 그 범위에 속하는지 Select Case로 검사합니다.
Q2. 어떤 버튼이 눌렸는지는 어떻게 알 수 있나요?
Application.Caller가 매크로를 실행한 버튼의 이름을 돌려주므로 Buttons(Application.Caller).Caption으로 캡션을 읽습니다.
Q3. Call 명령어는 꼭 써야 하나요?
생략해도 실행에는 영향이 없으며, 인수를 넘길 때 Call을 쓰면 괄호로 묶어야 합니다.
마치며
문제를 구체화하고 단순화하면 자음 버튼 하나로 이름을 골라 보는 주소록도 간단히 만들 수 있습니다.