- 최초 작성일: 2001-10-11
- 최종 수정일: 2026-09-30
- 조회수: 9 회
- 작성자: 권현욱 (엑셀러)
- 강의 제목: FIND 메서드에 대하여
들어가기 전에
오래 전 엑셀 파일로 진행하던 강의를 웹 글로 복원한 것이라, "버튼을 눌러보세요"처럼 엑셀에서 직접 조작하라는 표현이 남아 있을 수 있습니다. 결과는 본문의 그림이나 표로 확인하실 수 있으며, 현재와 맞지 않는 내용은 보완하되 전반적인 스타일은 당시의 갬성(?)을 유지했습니다.
삶에 의욕이 떨어지면 흔히들 시장에 가 보라는 말을 하곤 합니다. Exceller는 시장보다는 서점을 즐겨찾습니다. 가서 이런저런 책을 뒤적이기도 하지만 수많은 책들을 보고 있노라면 '이 중에서 내가 알고 있는 지식이 얼마나 보잘 것 없고 편협한 것인가!'하는 생각에 잠시 나태했던 정신 상태를 다시 추스리게 됩니다.
There is nothing new under the sun,
but there are lots of old things we don't know!
이 세상에 새로운 것이란 하나도 없다. 단지 우리가 모르고 있는 아주 오래된 것들이 잔뜩 널려있을 따름이다!
발명이라는 것은 인간의 영역이 아니라는 얘기지요. 우리가 얘기하는 발명이라는 것은 이미 존재하는 것을 남들보다 빨리 발견한 것에 다름아니지요. 발명이란 오로지 신만이 할 수 있습니다. 언젠가 언급한 바와도 같이 평생을 살아보았자 아주 조금 알고 가는 것입니다. 조금 안다고 해서 아는 체 하지 말고 항상 진지한 자세로, 가는 날까지 열심히 배우다가 가는 것입니다.
그저 신기해서 엑셀과 VBA를 한동안 쫓아왔는데 자꾸 쌓이다 보니 실력이 더 이상 느는 것 같지 않고 관심도 떨어져 간다는 분들이 있어서 드리는 말씀입니다.
사설은 이 쯤에서 접고…
FIND 메서드에 대하여
핵심 요약: 순환문 대 Find 메서드
Find와 FindNext 메서드는 검색 대상 셀만 골라내므로 모든 셀을 순환하는 방식보다 데이터가 많을수록 훨씬 빠릅니다.
- 1단계: 순환문 방식으로 조건에 맞는 셀을 찾고 소요 시간을 측정합니다.
- 2단계: Find로 첫 셀을 찾고 FindNext로 다음 셀을 찾으며 시간을 측정합니다.
- 3단계: 처음 찾은 셀의 주소로 되돌아오면 Do~Loop를 종료합니다.
Step 1: 데이터에 접근하는 방법
이번 시간에는 데이터(셀)에 접근하는 방법에 대해 알아보도록 하겠습니다.
현실 세계에서 낯선 찾아가려면 지도나 주소가 있어야 하듯이 컴퓨터도 마찬가지 입니다. 워크시트의 모든 셀에도 셀 주소가 있듯이 컴퓨터의 메모리에도 주소가 있고 하드디스크에도 수없이 많은 주소가 있습니다. 컴퓨터는 주소를 찾아다니다가 시간을 다 보내는 물건이라고 해도 과언이 아닙니다.
데이터를 가공/분석/출력을 하려면 우선 데이터가 어디에 들어있는 지를 알아야 그 다음 작업을 해도 하겠지요? 서울에서 광주까지 가는 방법은 수도 없이 많듯이 프로그래밍을 할 때에도 마찬가지입니다. 아래의 버튼들을 클릭하면 숫자를 입력하라는 메시지가 나오는데 10~99 사이의 임의의 숫자를 입력한 다음 수행 속도를 비교해 보세요. 77을 입력해 보세요.
현재는 데이터 량이 그다지 많지 않아 큰 차이를 보이지 않습니다만, 검색할 데이터 량이 많으면 많을수록 그 격차는 더욱 벌어집니다.
Step 2: 순환문으로 찾기 (SequentialAccess)
코드를 살펴보도록 하지요. 먼저, '세월아 네월아' 버튼에 연결된 코드부터 볼까요?
Sub SequentialAccess()
Dim rngCell As Range, rngSource As Range
Dim i As Integer, intWhatNumber As Integer
Dim Msg As String
Dim lngStart As Long
lngStart = Timer
'''필요한 등장 인물(변수)을 선언하고 현재의 시간을 lngStart 변수에 담아둡니다.
Set rngSource = [Source]
rngSource.Interior.ColorIndex = xlNone
intWhatNumber = Val(InputBox("10 ~ 99 사이의 숫자를 입력하세요!", "검색값 입력//By Exceller"))
'''데이터가 들어있는 부분에 미리 Source라는 이름을 붙여 두었습니다.
'''워크시트에 이름을 정의해 두면 프로그래밍시 접근하기가 훨씬 용이합니다.
'''데이터가 있는 부분의 배경색을 지운 다음 사용자로부터 검색할 값을 받습니다.
If intWhatNumber > 99 Or intWhatNumber < 10 Then
MsgBox "유효하지 않은 값입니다!", vbCritical, "입력 오류//By Exceller"
Exit Sub
End If
'''10~99 사이의 값만 유효한 것으로 설정합니다.
For Each rngCell In rngSource
If rngCell = intWhatNumber Then
rngCell.Select
Selection.Interior.ColorIndex = 3
i = i + 1
End If
'''Find라는 메서드(방법)이 없을 경우에는 위와 같이 순환문을 신나게(?) 돌려야
'''합니다. 그래서 수행 속도가 떨어지게 되는 것이지요.
Next rngCell
rngSource.Cells(1).Select
Msg = Msg & i & " 개의 셀이 발견되었습니다." & vbCr
Msg = Msg & "작업 소요 시간은 " & Format(Timer - lngStart, "00:00:00") & "초 입니다" & vbCr & vbCr
Msg = Msg & "이번에는 옆에 있는 ""날쌘돌이"" 버튼을 눌러 시간을 비교해 보세요"
MsgBox Msg, vbInformation, "작업 완료//By Exceller"
End Sub
이 코드를 아래의 '날쌘돌이' 코드와 비교해 보세요.
Step 3: Find/FindNext로 찾기 (Find_FindNextAccess)
Sub Find_FindNextAccess()
Dim rngCell As Range, rngSource As Range
Dim i As Integer, intWhatNumber As Integer
Dim Msg As String, strAddress As String
Dim lngStart As Long
lngStart = Timer
Set rngSource = [Source]
rngSource.Interior.ColorIndex = xlNone
intWhatNumber = Val(InputBox("10 ~ 99 사이의 숫자를 입력하세요!", "검색값 입력//By Exceller"))
If intWhatNumber > 99 Or intWhatNumber < 10 Then
MsgBox "유효하지 않은 값입니다!", vbCritical, "입력 오류//By Exceller"
Exit Sub
End If
'''변수를 선언하고, 사용자로 부터 데이터를 받은 다음 유효한 지 여부를 판단하는
'''과정은 위의 '세월아 네월아' 코드와 같습니다.
Set rngCell = rngSource.Find(What:=intWhatNumber, LookIn:=xlValues, LookAt:=xlWhole)
'''여기서부터 차이가 있습니다. Find 메서드를 사용하여 검색 대상 영역 중에서
'''사용자가 입력한 데이터가 있는 지 파악합니다.
If Not rngCell Is Nothing Then
strAddress = rngCell.Address
'''Not rngCell Is Nothing 이라는 것은 해당되는 데이터가 있다는 의미이지요?
'''즉 사용자로부터 입력받은 데이터와 같은 것이 있을 경우, 아래로 내려가서
'''Do~Loop 문을 수행하게 됩니다.
'''여기서 한 가지 주의할 점!
'''Find나 FindNext 메서드는 해당 셀의 값이 아닌 Range 오브젝트를 돌려준다는
'''사실입니다. 따라서 Range 오브젝트 변수의 값을 strAddress라는 문자열
'''변수에 담아 두었습니다.
Do
rngCell.Select
Selection.Interior.ColorIndex = 4
i = i + 1
Set rngCell = rngSource.FindNext(After:=rngCell)
'''같은 데이터가 계속 있을 경우, FindNext 메서드를 사용하여 계속 검색을
'''진행 합니다. 언제까지 하느냐 하면 rngCell의 주소가 strAddress 값과
'''다를 때까지, 그러니까 같은 값이 없을 때 Do~Loop 문을 탈출하게 됩니다.
Loop While rngCell.Address <> strAddress
End If
rngSource.Cells(1).Select
Msg = Msg & i & " 개의 셀이 발견되었습니다." & vbCr
Msg = Msg & "작업 소요 시간은 " & Format(Timer - lngStart, "00:00:00") & "초 입니다" & vbCr & vbCr
MsgBox Msg, vbInformation, "작업 완료//By Exceller"
End Sub
마무리
보신 바와 같이, 어떤 연장을 사용하느냐에 따라 많은 차이가 있습니다. Find/FindNext라는 훌륭한 부하가 있는데 그걸 몰라서 오로지 For~Next 하고만 친하게 지내다 보면 그만큼 경쟁력이 떨어지는 것이지요. 많이 연구해 보세요.
오늘은 여기까지…
정리 — Find 메서드 핵심
| 구분 | 사용한 코드 | 역할 |
|---|---|---|
| 시간 측정 | lngStart = Timer | 시작 시각 저장 |
| 순환 검색 | For Each rngCell In rngSource | 모든 셀을 하나씩 검사 |
| 첫 셀 검색 | rngSource.Find(What:=…, LookAt:=xlWhole) | 조건에 맞는 첫 셀 반환 |
| 다음 셀 검색 | rngSource.FindNext(After:=rngCell) | 다음 셀 반환 |
| 종료 조건 | Loop While rngCell.Address <> strAddress | 처음 셀로 돌아오면 종료 |
자주 묻는 질문 (FAQ)
Q1. Find 메서드가 순환문보다 빠른 이유는 무엇인가요?
모든 셀을 하나씩 검사하지 않고 조건에 맞는 셀만 찾아서 돌려주기 때문입니다.
Q2. Find와 FindNext는 무엇을 반환하나요?
셀의 값이 아니라 Range 오브젝트를 반환하므로 주소를 문자열 변수에 담아 비교합니다.
Q3. FindNext 반복은 언제 끝내나요?
처음 찾은 셀의 주소로 다시 돌아오면 모든 셀을 찾은 것이므로 Loop를 종료합니다.
마치며
Find와 FindNext 메서드를 익혀 두면 대량의 데이터에서도 빠르게 원하는 셀을 찾을 수 있습니다.