- 최초 작성일: 2001-06-13
- 최종 수정일: 2026-09-30
- 조회수: 14 회
- 작성자: 권현욱 (엑셀러)
- 강의 제목: 조건을 충족하는 모든 데이터 추출하기
들어가기 전에
오래 전 엑셀 파일로 진행하던 강의를 웹 글로 복원한 것이라, "버튼을 눌러보세요"처럼 엑셀에서 직접 조작하라는 표현이 남아 있을 수 있습니다. 결과는 본문의 그림이나 표로 확인하실 수 있으며, 현재와 맞지 않는 내용은 보완하되 전반적인 스타일은 당시의 갬성(?)을 유지했습니다.
이번 시간에는 게시판에 올라온 질문을 살펴봅니다.
안녕하세요.
엑셀초보자로서 일반책에서도 언급되지 않은 많은 설명문을 접하게 되어
너무나도 기쁩니다. 모르는 내용이 있어도 가슴앓이해 오던 차에 궁금증을
풀 수 도 있겠다 싶어 이렇게 내용을 적습니다.
A1 B1 C1 D1 E1 F1 G1
호수 성명 주 소 우편번호 대지위치 건물명 면적
101 궁예 철원 123-456 원미동 원미빌딩 35
102 왕건 평양 236-564 소사동 소사빌딩 28
102 왕건 평양 236-564 심곡동 심곡빌딩 72
102 왕건 평양 236-564 원종동 원종빌딩 26
103 견훤 전주 145-245 고강동 고강빌딩 89
라는 자료(database)가 있구요.
아래 고지할 양식으로 추출하여 *예를 들어
------------------------------------------------------------------------
(고지서내용)
고 지 서
성명(H1)
주소(H2)
우편번호(H3)
=====================================================
고 지 내 역
=====================================================
일련번호(H4) 대지위치 (I4) 건물명 (J4) 면적(K4)
=====================================================
1
2
3
으로 데이타 내용이 고지서 항목으로 이동하여 101~103까지 자동인쇄(한꺼번에
인쇄) 하고자 하는데,
만약 제일 왼쪽데이타에 있는 호수 "102호'의 왕건이 3명 있는데 자료와 같이 주소,
우편번호,성명까지는 같구요, 대지위치,건물명, 면적이 다를 경우 모두 출력하고자
고지내역 전체적인 소스구성은 어떻게 해야 할지 ?
도와주실수 없나요
조건을 충족하는 모든 데이터 추출하기
핵심 요약: 조건에 맞는 모든 데이터 추출
입력받은 호수로 자동 필터를 적용하고 보이는 셀만 FilterSheet에 복사한 뒤, 성명·주소를 위쪽에 배치하고 일련번호를 붙이면 고지서 형태의 내역이 만들어집니다.
- 1단계: InputBox로 호수를 입력받고 3자리인지 검사합니다.
- 2단계: AutoFilter로 조건에 맞는 행만 보이게 하고 보이는 셀만 복사합니다.
- 3단계: 성명·주소를 위에 배치하고 우편번호 이하 열을 옮긴 뒤 일련번호를 넣습니다.
Step 1: 예제 보기
예제를 보도록 하지요. 아래 버튼을 누르세요.
원본 데이터 펼쳐 보기 (Source 시트: 호수 / 성명 / 주소 / 우편번호 / 대지위치 / 건물명 / 면적)
| 호수 | 성명 | 주소 | 우편번호 | 대지위치 | 건물명 | 면적 |
|---|---|---|---|---|---|---|
| 101 | 궁예 | 철원 | 123-456 | 원미동 | 원미빌딩 | 35 |
| 102 | 왕건 | 평양 | 236-564 | 소사동 | 소사빌딩 | 28 |
| 102 | 왕건 | 평양 | 236-564 | 심곡동 | 심곡빌딩 | 72 |
| 102 | 왕건 | 평양 | 236-564 | 원종동 | 원종빌딩 | 26 |
| 103 | 견훤 | 전주 | 145-245 | 고강동 | 고강빌딩 | 89 |
| 101 | 궁예 | 철원 | 123-456 | 신길동 | 원미빌딩 | 35 |
| 102 | 왕건 | 평양 | 236-564 | 구로동 | 소사빌딩 | 28 |
| 102 | 왕건 | 평양 | 236-564 | 서초동 | 심곡빌딩 | 72 |
| 102 | 왕건 | 평양 | 236-564 | 반포동 | 원종빌딩 | 26 |
| 103 | 견훤 | 전주 | 145-245 | 한강로 | 고강빌딩 | 89 |
| 301 | 궁예 | 철원 | 123-456 | 원미동 | 원미빌딩 | 35 |
| 302 | 왕건 | 평양 | 236-564 | 소사동 | 소사빌딩 | 28 |
| 302 | 왕건 | 평양 | 236-564 | 심곡동 | 심곡빌딩 | 72 |
| 302 | 왕건 | 평양 | 236-564 | 원종동 | 원종빌딩 | 26 |
| 303 | 견훤 | 전주 | 145-245 | 고강동 | 고강빌딩 | 89 |
| 401 | 궁예 | 철원 | 123-456 | 원미동 | 원미빌딩 | 35 |
| 402 | 왕건 | 평양 | 236-564 | 소사동 | 소사빌딩 | 28 |
| 402 | 왕건 | 평양 | 236-564 | 심곡동 | 심곡빌딩 | 72 |
| 402 | 왕건 | 평양 | 236-564 | 원종동 | 원종빌딩 | 26 |
| 403 | 견훤 | 전주 | 145-245 | 고강동 | 고강빌딩 | 89 |
| 501 | 궁예 | 철원 | 123-456 | 원미동 | 원미빌딩 | 35 |
| 502 | 왕건 | 평양 | 236-564 | 소사동 | 소사빌딩 | 28 |
| 502 | 왕건 | 평양 | 236-564 | 심곡동 | 심곡빌딩 | 72 |
| 502 | 왕건 | 평양 | 236-564 | 원종동 | 원종빌딩 | 26 |
| 506 | 견훤 | 전주 | 145-245 | 고강동 | 고강빌딩 | 89 |
| 601 | 궁예 | 철원 | 123-456 | 원미동 | 원미빌딩 | 35 |
| 602 | 왕건 | 평양 | 236-564 | 소사동 | 소사빌딩 | 28 |
| 602 | 왕건 | 평양 | 236-564 | 심곡동 | 심곡빌딩 | 72 |
| 602 | 왕건 | 평양 | 236-564 | 원종동 | 원종빌딩 | 26 |
| 603 | 견훤 | 전주 | 145-245 | 고강동 | 고강빌딩 | 89 |
호수를 입력하면 FilterSheet 시트에 해당 호수의 고지서 내역이 아래와 같은 형태로 만들어집니다.
| 일련번호 | 우편번호 | 대지위치 | 건물명 | 면적 |
|---|---|---|---|---|
| 1 | 236-564 | 소사동 | 소사빌딩 | 28 |
| 2 | 236-564 | 심곡동 | 심곡빌딩 | 72 |
| 3 | 236-564 | 원종동 | 원종빌딩 | 26 |
| … | … | … | … | … |
Step 2: MakeDigest 프로시저
코드는 아래와 같습니다. 시간이 없어서 최적화를 하지 못했습니다. 별로 마음에 드는 코드는 아니지만 방법을 이해하신 다음 직접 Optimizing을 시켜 보도록 하세요. 남이 짠 코드를 내 것으로 만드는 확실한 방법은 이렇게 저렇게 응용해 보는 것입니다.
Sub MakeDigest()
Dim strName As String
Dim shtSource As Worksheet, shtFilter As Worksheet
Dim rngData As Range
Dim i As Integer, intNum As Integer
Set shtSource = Sheets("Source")
Set shtFilter = Sheets("FilterSheet")
shtFilter.Cells.ClearContents
strName = InputBox("호수를 입력하세요", "호수 입력//By Exceller")
If Len(strName) <> 3 Then
MsgBox """호수를"" 확인하세요!", , "호수 입력 오류//By Exceller"
Exit Sub
End If
'''어느 호수를 출력할 것인지 사용자로부터 자료를 입력받습니다. 만약 유효하지 않은 값이
'''입력되면 프로그램을 종료합니다.
Set rngData = shtSource.[A1].CurrentRegion
shtSource.AutoFilterMode = False
rngData.AutoFilter Field:=1, Criteria1:=strName
'''이 작업을 수행하기 위해 자동 필터를 사용했습니다. 따라서 필터링이 이미 되어 있을지도
'''모르므로 일단 해제를 해 준 다음 1열, 즉 호수를 기준으로 자동 필터링을 합니다. 필터링할
'''기준은 사용자로부터 입력받은 strName입니다.
rngData.SpecialCells(xlCellTypeVisible).Copy shtFilter.Cells(7, 1)
shtSource.AutoFilterMode = False
'''필터링된 데이터, 즉 조건을 충족하는 데이터들만 복사를 합니다. 그리고 나서 자동 필터를
'''다시 원상복구 시킵니다.
Application.Goto shtFilter.Range("a1"), True
'''아래 부분은 코드는 길어 보입니다만 FilterSheet에 원하는 형태로 자료를 출력하기 위한
'''것입니다. 셀에 값을 기입하고 데이터를 원하는 형태로 만듭니다.
With shtFilter
.Range("a3") = "호수"
.Range("a4") = "성명"
.Range("a5") = "주소"
.Range("b3") = strName
.Range("b4") = .Range("a8").Offset(0, 1).Value
.Range("b5") = .Range("a8").Offset(0, 2).Value
.Range("a7") = "일련번호"
If .Cells(.Rows.Count, 4).End(xlUp).Row >= 8 Then
.Range(.Range("d7"), .Cells(.Cells(.Rows.Count, 4).End(xlUp).Row, 7)).Cut .Range("b7")
End If
intNum = Application.CountA(.Range("c:c")) - 1
If intNum = 0 Then
MsgBox "조건에 해당되는 자료가 없습니다."
Exit Sub
End If
'''만약 해당 데이터가 한 건도 없다면 메시지 박스를 보여주고 종료합니다.
'''데이터가 있을 경우에는 For ~ Next 문을 사용하여 셀에 하나씩 뿌려 줍니다.
For i = 1 To intNum
.Cells(7 + i, 1) = i
Next i
.Range("a1").Select
End With
MsgBox "총 " & intNum & " 건의 자료가 추출되었습니다!", , "작업 완료//By Exceller"
End Sub
마무리
생각보다 간단하지요? 이 코드는 수정해야 할 부분이 많이 있습니다. 잘 살펴 보시고 어떤 부분들을 더 추가해 주면 좋을지 직접 해 보시기 바랍니다. 좋은 생각들이 떠오르면 메일을 주시기 바랍니다. 아니면 코드를 직접 수정해서 보내 주시든가...
만약 질문이 없으면 구렁이 담넘어가듯 스을~쩍 넘어가 버릴지도 모릅니다. ^^
다음 시간에...
정리 — 조건 데이터 추출 핵심
| 구분 | 사용한 코드 | 역할 |
|---|---|---|
| 조건 입력 | InputBox / Len(strName) <> 3 | 호수 입력과 검사 |
| 필터링 | rngData.AutoFilter Field:=1, Criteria1:=strName | 호수 기준 필터 |
| 복사 | .SpecialCells(xlCellTypeVisible).Copy | 보이는 셀만 복사 |
| 재배치 | .Cut .Range("b7") | 열 위치를 옮겨 양식 구성 |
| 일련번호 | .Cells(7 + i, 1) = i | 추출 건수만큼 번호 입력 |
자주 묻는 질문 (FAQ)
Q1. 같은 호수에 자료가 여러 건 있어도 모두 추출할 수 있나요?
자동 필터로 조건에 맞는 행을 모두 남긴 뒤 보이는 셀을 통째로 복사하므로 건수와 관계없이 모두 추출됩니다.
Q2. 자동 필터가 이미 적용되어 있으면 어떻게 하나요?
AutoFilterMode를 False로 해제한 다음 새 조건으로 다시 필터링하면 됩니다.
Q3. 조건에 맞는 자료가 없을 때는 어떻게 처리하나요?
추출된 건수(intNum)가 0이면 메시지를 보여 주고 프로시저를 종료합니다.
마치며
자동 필터와 보이는 셀 복사를 활용하면 조건에 맞는 모든 데이터를 원하는 양식으로 쉽게 추출할 수 있습니다.