- 최초 작성일: 2000-10-20
- 최종 수정일: 2026-09-30
- 조회수: 7 회
- 작성자: 권현욱 (엑셀러)
- 강의 제목: 하위폴더 검색하기 Ⅱ
들어가기 전에
오래 전 엑셀 파일로 진행하던 강의를 웹 글로 복원한 것이라, "버튼을 눌러보세요"처럼 엑셀에서 직접 조작하라는 표현이 남아 있을 수 있습니다. 결과는 본문의 그림이나 표로 확인하실 수 있으며, 현재와 맞지 않는 내용은 보완하되 전반적인 스타일은 당시의 갬성(?)을 유지했습니다.
지난 VB0044 강좌에서 FileSearch 오브젝트를 사용해서 하위폴더를 검색하는 방법에 대해 소개해 드렸습니다. 그런데 이 오브젝트는 Excel 2000 버전부터 추가된 새로운 것입니다. 역시 아래와 같은 질문을 하신 분이 있군요. 짐작한대로… ^^;
이번에 살펴볼 질문은 엑사모에 올라온 것인데, 그 때 제가 답변을 했던 내용을 좀더 응용해서 재미있는 것을 하나 만들어 보았습니다.
재귀(recursion) 문제를 구현하고 싶다는 질문입니다. 아래와 같은 계층 구조의 디렉토리가 있을 때 결과값으로 result = {file1, file2, file3, file4, file5, file6, file7}을 얻고 싶은데, 초보자라 구현하기가 조금 어렵다며 예제도 만들어 주시면 감사하겠다고 하셨습니다.
Main Folder
├ Sub Folder1
│ ├ File1
│ └ File2
├ Sub Folder2
│ ├ File3
│ ├ File4
│ └ File5
├ File6
└ File7
하위폴더 검색하기 Ⅱ
핵심 요약: 재귀 호출로 하위폴더 검색
현재 폴더의 파일을 처리하고 하위 폴더 이름을 배열에 모은 뒤, 각 하위 폴더에 대해 자기 자신을 다시 호출합니다.
- 1단계: Dir(Path)로 폴더 내 파일을 순환하며 확장자가 xls인 파일 정보를 기록합니다.
- 2단계: Dir(Path, vbDirectory)로 하위 폴더를 찾아 동적 배열에 저장합니다.
- 3단계: 배열의 각 폴더로 RecursiveCall을 다시 호출합니다.
Step 1: 결과 미리 보기
만약 Excel 2000 사용자라면 VB0044(하위 폴더 동시 검색하기) 강좌에서 설명드린 FileSearch 오브젝트를 사용하면 손쉽게 구현을 할 수 있습니다.
하지만 Excel 2000 이하 버전을 사용하고 있는 분이라면 오늘 소개해 드리는 방법을 사용해 보시기 바랍니다. 주말맞이 기념(?)으로 약간 까다로운(코드 자체는 어렵지 않지만 처음 접하면 개념 잡기가 그렇다는 것이지요 ^^) 것으로 준비해 봤습니다. 그리고 여러 곳에서 응용할 수 있는 좋은 코드니까 한번 보고 휙 버리지 말고 잘 보관해 두시기를…
일단 아래의 버튼을 누르세요.
사용자가 검색하고자 하는 폴더를 지정하면 해당 폴더의 하위 폴더까지 모두 검색을 합니다. 확장자가 xls이면 파일정보를 시트에 차례로 표시를 하고 하이퍼링크를 걸어 둡니다. 이렇게 하면 파일을 클릭하면 해당 파일이 열리게 됩니다. 작동되는 과정만을 보면, 지난 VB0044 강좌와 별 차이를 못 느끼실지도 모르겠으나 구현원리는 차이가 있습니다.
VB0044 강좌에서는 앞서 설명드린 Excel 2000 버전부터 지원되는 FileSearch 오브젝트를 사용했으나 Recursive 함수를 사용하였습니다. 재귀적 호출, 즉 자기가 자신을 불러와서 실행을 시키는 것입니다. 일단 코드를 살펴보도록 하지요.
Step 2: 시작 프로시저 작성하기
Option Explicit
Dim r As Long
Sub SearchSubFoldersByRecursiveCall()
Dim strPath As String
strPath = InputBox("검색할 폴더를 입력하세요", "폴더 지정//Exceller", "C:\")
If strPath = "" Then Exit Sub
If Right(strPath, 1) <> "\" Then strPath = strPath & "\"
Worksheets.Add after:=Sheets("Preface")
r = 1
Cells(r, 1) = "파일명"
Cells(r, 2) = "크기"
Cells(r, 3) = "작성일자"
Range("a1:c1").Font.Name = "Arial"
Columns("A").ColumnWidth = 30
Columns("C").ColumnWidth = 16
'//여기까지는 하나도 어려운 부분이 없을 것입니다. 워크시트를 하나 삽입하고 타이틀 부분을
'//시트상에 적는 부분이니까…
RecursiveCall strPath
'//RecursiveCall이라는 프로시저를 호출하되 strPath라는 변수를 함께 넘겨 실행시킵니다.
End Sub
Step 3: 재귀 호출 프로시저 작성하기
Sub RecursiveCall(Path As String)
Dim i As Integer
Dim intFolder As Integer
Dim strFile As String
Dim strFolder() As String
Dim strTemp As String
Dim Msg As String
strFile = Dir(Path)
'//일단 등장인물을 먼저 지정해 주고, Dir(Path)라고 하면 어떤 값이 나올까요? 그렇습니다!
'//Path에 "C:\"가 저장되어 있으므로 C: 드라이브의 루트 디렉토리 내에 있는 첫번째 파일의
'//이름이 strFile 변수에 저장되지요?
Do While strFile <> ""
'//Do While strFile<>""라는 것을 보니 순환문은 순환문인데… 그럼 어떨 때 순환을 멈추라는
'//걸까요? 직역을 하자면 "strFile이 공란이 아닌 동안만 실행해라?" 아하~ 폴더 내에 파일이
'//있는 수만큼 순환문을 계속 돌라는 뜻이지요?
strTemp = ActiveCell.Offset(r, 0).Value
Application.StatusBar = "File Searching... " & Path & strFile
If Right(Path & strFile, 3) = "xls" Then
'//만약 Excel 파일이 아닌 다른 종류의 파일을 검색하고 싶으면 이 부분을 수정해 주시면
'//되겠지요?(오늘 유난히 물음표를 많이 쓰는군요. 적적해서 그러나? ^^).
With ActiveCell
.Offset(r, 0) = Path & strFile
.Offset(r, 1) = FileLen(Path & strFile)
.Offset(r, 2) = FileDateTime(Path & strFile)
ActiveSheet.Hyperlinks.Add Anchor:=.Offset(r, 0), Address:=Path & strFile
End With
r = r + 1
If r > 20 Then ActiveWindow.SmallScroll down:=1
'//해당 파일이 발견될 때마다 워크시트 상에서 한줄씩 밑으로 이동하면서 파일의 이름,
'//크기, 작성일자 등의 정보를 적절한 위치에 뿌려줍니다.
End If
strFile = Dir()
'//Dir() 함수를 처음 쓸 때에는 경로명까지 다 적어 주어야 하지만 그 다음에 사용할 때에는
'//그냥 Dir()만 써도 자동으로 다음 파일이 검색되는 것은 아시지요?
Loop
strFile = Dir(Path, vbDirectory)
Do While strFile <> ""
If strFile <> "." And strFile <> ".." Then
'//해당 폴더의 하위 폴더를 검색하는데 .나 ..가 아닐 경우에만 아래의 문장을 실행합니다.
'//이렇게만 설명하고 그냥 넘어가면, "그럼 .나 ..는 뭔데요?" 라고 질문을 하시겠지요?
'//DOS 상태로 빠져 나간 다음 dir하고 Enter키를 쳐 보세요. 그러면
'// . <DIR>
'// .. <DIR>
'//이런 것이 나타날 것입니다. 바로 이것을 걸러내기 위한 과정입니다.
If GetAttr(Path & strFile) And vbDirectory Then
intFolder = intFolder + 1
ReDim Preserve strFolder(intFolder)
strFolder(intFolder) = Path & strFile
'//현재 폴더 내에 하위 폴더가 발견될 때마다 이것을 동적 배열변수 strFolder(intFolder)
'//에다가 차곡차곡 담아둡니다. 왜 담아 두냐고요? 그래야 나중에 Recursive 구조에서
'//다른 것은 같은데 폴더명만 다르게 해서 지정한 조건을 실행할 수 있을 것이니까요.
End If
End If
strFile = Dir()
Loop
For i = 1 To intFolder
RecursiveCall strFolder(i) & "\"
'//이 부분이 오늘 강좌의 핵심입니다. 즉, Recursive 구조에 의해서 폴더 내에 하위
'//폴더의 수만큼 자기 자신을 다시 호출해 오는 것입니다. 여기서 폴더명 뒤에 \를 반드시
'//붙여 주어야 Error가 생기지 않습니다.
Next i
Application.StatusBar = ""
End Sub
이 강좌에서 언급한 FileSearch 개체는 Excel 2007부터 제거되어 요즘 버전에서는 사용할 수 없습니다. 이 강좌의 Dir 함수와 재귀 호출 방식은 지금도 그대로 동작하며, FileSystemObject(Scripting.FileSystemObject)의 Folders/Files 컬렉션을 순환하는 방법도 많이 사용합니다.
마무리
이상 설명드린 코드를 잘 활용하면 재미있는 것들을 많이 만드실 수 있을 것입니다. 많이 응용해 보시기 바랍니다. 그러다가 진짜 재미있는 작품이 나왔다 싶으면 Exceller에게도 연락을 주시고…
다음 시간에…
정리 — 재귀 호출 검색 핵심
| 구분 | 사용한 코드 | 역할 |
|---|---|---|
| 파일 순환 | strFile = Dir(Path) ... Dir() | 폴더 내 파일 검색 |
| 폴더 검색 | Dir(Path, vbDirectory) | 하위 폴더 이름 구하기 |
| 폴더 판별 | GetAttr(...) And vbDirectory | 폴더 속성 확인 |
| 재귀 호출 | RecursiveCall strFolder(i) & "\" | 자기 자신을 다시 호출 |
| 하이퍼링크 | Hyperlinks.Add | 클릭하면 파일 열기 |
자주 묻는 질문 (FAQ)
Q1. 재귀 호출이란 무엇인가요?
프로시저가 자기 자신을 다시 호출해서 실행하는 구조로, 계층이 있는 폴더를 검색할 때 유용합니다.
Q2. Dir 결과에서 . 과 .. 은 왜 제외하나요?
현재 폴더와 상위 폴더를 뜻하는 항목이므로 그대로 재귀 호출하면 무한히 반복되기 때문입니다.
Q3. FileSearch를 쓸 수 없는 버전에서는 어떻게 하나요?
Dir 함수와 재귀 호출 또는 FileSystemObject를 사용하면 됩니다.
마치며
재귀 호출 구조를 익히면 폴더 검색뿐 아니라 계층 구조를 다루는 다양한 작업에 응용할 수 있습니다.