• 최초 작성일: 2025-01-25
  • 최종 수정일: 2026-09-27
  • 조회수: 38 회
  • 작성자: 권현욱 (엑셀러)
  • 강의 제목: VBA 파워 코딩 251회 - 하위 폴더 검색

들어가기 전에

오래 전 엑셀 파일로 진행하던 강의를 웹 글로 복원한 것이라, "버튼을 눌러보세요"처럼 엑셀에서 직접 조작하라는 표현이 남아 있을 수 있습니다. 결과는 본문의 그림이나 표로 확인하실 수 있으며, 현재와 맞지 않는 내용은 보완하되 전반적인 스타일은 당시의 갬성(?)을 유지했습니다.

고난은 위장된 축복

'자원의 저주(Resource Curse)'라는 말이 있습니다. 브라질, 러시아, 인도, 중동 산유국 등의 경우처럼 자연자원은 풍부하나 경제성장이 둔해지는 현상을 말합니다. 그런가 하면, 자연자원은 보잘것없으나 이를 극복하고 발전을 이룬 나라들도 있죠.

개인의 경우로 내려와 보면, 우리가 잘 아는 위인들은 거의 예외 없이 고난을 딛고 위대한 성취를 이루었습니다.

모차르트가 많은 작품을 남길 수 있었던 것은 안정된 일자리를 얻을 수 없어서 일찍부터 프로 작곡가가 될 수밖에 없었기 때문입니다. '어둠과 빛의 화가' 렘브란트가 100여 점이나 되는 자화상을 남길 수 있었던 것은 돈이 없어서 모델을 고용할 수 없었기 때문입니다. 다산 정약용이 500여 편의 저작을 남길 수 있었던 것은 18년의 유배 기간이 있었기에 가능한 일이었습니다(물론 '복숭아뼈에 세 번이나 구멍이 뚫릴' 정도의 치열함이 있었습니다).

그런 의미에서 고난이나 역경은 "위장된 축복(Blessing in disguise)"이라는 말이 그르지 않은 듯합니다. 고난을 업적으로 "승화"할 수 있는 강인한 멘탈을 길러야겠습니다.

권현욱(엑셀러)
저자: 권현욱(엑셀러), 아이엑셀러 대표

필자는 Excel 컨설턴트, 작가, 그리고 크리에이터입니다. 현재 Microsoft Excel MVP이며, 『챗GPT+엑셀 업무자동화 정석』을 비롯한 10여 권의 도서를 집필했습니다. Excel 자동화 및 생산성 향상 분야에서 25년 넘는 경력을 보유하고 있습니다.

권현욱(엑셀러) 님의 최신 포스트:
  • 최신 글을 불러오는 중...


26년 경력 Microsoft MVP 권현욱(엑셀러) 대표 직강 1강 무료

🎁 파워툴스 마스터클래스 · 엑셀 바이브 코딩

AI에게 말로 지시해서 '나만의 엑셀 도구'를 만들고 리본에 장착합니다.

  • 코딩 지식 없이 시작 · 코드는 AI가 작성
  • 엑셀 리본에 내 탭과 버튼을 만들고 XLAM으로 공유
  • 1강 무료 수강 가능
수강 신청하기 강의 소개 보기

하위 폴더를 검색하고 하이퍼링크로 연결하는 Code

핵심 요약: 하위 폴더까지 검색해 하이퍼링크로 연결하기

SearchSubFolder가 폴더를 입력받고 RecursiveCall이 xlsx, xlsm 파일을 찾아 하이퍼링크와 함께 표시하며, 하위 폴더 수만큼 자기 자신을 다시 호출(재귀)해 아래 폴더까지 모두 검색합니다.

  • 입력: InputBox로 검색할 폴더 입력 (기본값은 통합 문서가 있는 폴더)
  • 결과: 새 워크시트에 파일명(하이퍼링크), 크기, 작성일자 표시
  • 핵심: RecursiveCall 프로시저의 재귀적 호출
  • 주의: 폴더명 뒤에 '\' 표시를 붙여야 에러가 생기지 않음

폴더 검색하기 버튼 실행해 보기

예제 파일의 '폴더 검색하기' 버튼을 클릭하면 InputBox가 나타납니다. 폴더명을 입력하면 지정한 폴더에서 확장자가 'xlsm'이거나 'xlsx'인 파일들이 표시됩니다. 폴더 아래에 있는 하위 폴더들까지 모두 검색하여 워크시트에 표시해 줍니다.

폴더 검색하기 버튼을 클릭하면 나타나는 폴더명 입력 InputBox
아이엑셀러

그냥 화면에 표시만 해주는 것이 아니라 하이퍼링크가 자동으로 설정되므로 파일 이름을 클릭하면 해당 파일이 열립니다.

검색된 파일명, 크기, 작성일자가 하이퍼링크와 함께 표시된 워크시트
아이엑셀러

'폴더 검색하기' 버튼에 연결된 코드

'폴더 검색하기' 버튼에 연결된 코드를 보도록 하죠.

Dim r As Long          ' 여러 프로시저에서 공통적으로 사용할 변수를 프로시저 외부에 선언

Sub SearchSubFolder()
    Dim strFolder As String        ' 폴더 이름을 저장할 변수

    strFolder = InputBox(prompt:="검색할 폴더를 입력하세요", _
        Default:=ThisWorkbook.Path & "\")
        ' InputBox 함수를 이용하여 검색할 폴더를 입력받음.
        ' Default 인수를 지정하여 디폴트 값이 대화상자에 표시되도록 함.

    If strFolder = "" Then        ' 만약 '취소' 버튼을 눌렀다면 프로시저 실행 종료
        MsgBox "아무 폴더도 선택되지 않았으므로 종료합니다"
        Exit Sub
    End If

    If Right(strFolder, 1) <> "\" Then strFolder = strFolder & "\"
                                  ' 폴더명 뒤에 '\' 표시를 붙이지 않았다면 추가
    Worksheets.Add after:=Sheets(1)    ' 첫 번째 시트 뒤에 새로운 워크시트 추가
    r = 1                         ' 변수 r값 지정

    ' A1:C1 영역에 표의 제목을 입력하고 서식 지정
    Cells(r, 1) = "파일명"
    Cells(r, 2) = "크기"
    Cells(r, 3) = "작성일자"
    Range("a1:c1").Font.Name = "Arial"
    Columns("A").ColumnWidth = 60
    Columns("A").ShrinkToFit = True
    Columns("C").ColumnWidth = 16

    RecursiveCall strFolder    ' 외부 프로시저를 호출함. 이 때 strFolder 값 함께 전달
End Sub

핵심은 RecursiveCall 프로시저

중요한 것은 프로시저 마지막에 호출한 'RecursiveCall'이라는 외부 프로시저입니다.

Sub RecursiveCall(Path As String)
    Dim i As Integer               ' For ~ Next 문에서 사용할 Flag 변수
    Dim intFolder As Integer
    Dim strFile As String          ' 파일 이름을 저장할 변수
    Dim strFolder() As String      ' 하위 폴더가 있을 경우를 대비하여 동적 배열 변수로 선언
    Dim strTemp As String          ' 파일 확장자에 접근하기 위한 임시 문자열 변수

    strFile = Dir(Path)            ' 지정한 폴더에 있는 첫 번째 파일을 변수에 지정

    Do While strFile <> ""         ' 폴더 내에 파일이 있는 동안 순환문 반복 실행
        strTemp = Split(Path & strFile, ".")(1)
        ' Split 함수를 이용하여 첫 번째 콤마 이후 부분(즉 확장자)을 추출하고 변수에 저장

        If strTemp = "xlsm" Or strTemp = "xlsx" Then
        ' Split 함수로 분리해 낸 문자열 값이 xlsm 또는 xlsx이면...

            strTemp = ActiveCell.Offset(r, 0).Value
            ' 활성화 된 셀에서 1행 이동한 셀 값을 strTemp 변수에  저장

            With ActiveCell        ' 활성화 된 셀에 대하여...
                .Offset(r, 0) = Path & strFile
                ' 행 방향으로 1, 열 방향으로 0만큼 이동한 셀에 폴더명과 파일명 표시

                ActiveSheet.Hyperlinks.Add Anchor:=ActiveCell.Offset(r, 0), _
                    Address:=ActiveCell.Offset(r, 0).Value, TextToDisplay:=strTemp
                    ' 같은 셀에 하이퍼링크 설정

                .Offset(r, 1) = FileLen(Path & strFile)       ' 같은 행 1열 옆에 파일 길이 표시
                .Offset(r, 2) = FileDateTime(Path & strFile)  ' 같은 행 2열 옆에 파일 생성 일자 표시
            End With

            r = r + 1            ' 다음 작업을 위해 변수 값 1증가
        End If

        strFile = Dir()          ' 다음 파일 검색
    Loop

    strFile = Dir(Path, vbDirectory)

    Do While strFile <> ""       ' 하위 폴더 검색
        If strFile <> "." And strFile <> ".." Then
        ' 폴더명이 '.' 또는 '..'가 아닌 경우에만 다음 명령을 실행함.

            ' 하위 폴더가 발견될 때마다 동적 배열 변수에 담아둠.
            If GetAttr(Path & strFile) = vbDirectory Then  ' 하위 폴더가 있다면...
                intFolder = intFolder + 1                  ' 변수 값 1 증가
                ReDim Preserve strFolder(intFolder)        ' 동적 배열의 크기 재지정(기존 내용은 보존)
                strFolder(intFolder) = Path & strFile      ' 하위 폴더 경로를 배열에 저장
            End If
        End If
        strFile = Dir()
    Loop

    For i = 1 To intFolder                   ' 발견된 하위 폴더 수만큼 반복 실행
        RecursiveCall strFolder(i) & "\"     ' 자기가 자기를 불러오는 재귀적 호출
    Next i
End Sub

이 코드에서는 'RecursiveCall strFolder(i)' 이 부분이 핵심입니다. "재귀적(Recursive) 방식"에 의해서 폴더 내에 하위 폴더 수만큼 "자기 자신을 다시 호출하는 구조"입니다. 이 때 폴더명 뒤에 '\' 표시를 붙여주어야 에러가 생기지 않는다는 점에 유의하세요!

참고: 코드 주석 수정

원문 코드의 주석 중 세 곳을 바로잡았습니다. "A1:A3 영역"은 실제 범위에 맞게 "A1:C1 영역"으로, "눌렸다면"은 "눌렀다면"으로 고쳤고, ReDim Preserve 줄과 배열에 폴더 경로를 저장하는 줄의 주석 내용이 서로 바뀌어 있어 제자리로 돌려놓았습니다. 코드 동작은 그대로입니다.

참고: 이미지에 대하여

이 글은 원래 네이버 포스트에 게재되었던 글로, 네이버 포스트 서비스 종료로 네이버 블로그로 옮기는 과정에서 원본 이미지가 소실되었습니다. 위 이미지는 본문 설명을 바탕으로 당시 화면 구성을 재구성한 예시 이미지이며, 실제 엑셀 화면과 세부 디자인(버전별 UI)은 다를 수 있습니다. 이미지 속 폴더 경로와 파일 이름, 크기, 날짜는 예시입니다.

정리 — 하위 폴더 검색 코드의 구성

구성 요소 역할
SearchSubFolder InputBox로 폴더를 입력받고 새 워크시트와 제목 행을 만든 뒤 RecursiveCall 호출
RecursiveCall Dir 함수로 xlsx, xlsm 파일을 찾아 하이퍼링크와 함께 표시하고, 하위 폴더 수만큼 자기 자신을 다시 호출
Hyperlinks.Add 파일 경로 셀에 하이퍼링크를 설정하여 클릭하면 파일이 열리게 함
모듈 수준 변수 r 여러 프로시저가 함께 사용하는 결과 행 번호 카운터

자주 묻는 질문 (FAQ)

Q1. 하위 폴더까지 모두 검색하려면 어떻게 하나요?

재귀적(Recursive) 방식을 사용합니다. 폴더 안에서 하위 폴더를 발견하면 하위 폴더 수만큼 프로시저가 자기 자신을 다시 호출하는 구조로 만들면 됩니다.

Q2. 재귀 호출할 때 주의할 점은 무엇인가요?

폴더명 뒤에 '\' 표시를 붙여 주어야 에러가 생기지 않습니다. 예제 코드에서도 RecursiveCall strFolder(i) & "\"와 같이 호출합니다.

Q3. 검색된 파일을 바로 열 수 있나요?

검색 결과를 워크시트에 표시할 때 하이퍼링크가 자동으로 설정되므로 파일 이름을 클릭하면 해당 파일이 열립니다.

마치며

재귀 호출만 이해하면 아무리 깊은 폴더 구조도 코드 몇 줄로 훑을 수 있습니다. 디버깅 도구로 한 단계씩 따라가 보세요!
VBA에 대한 기초 지식을 공부하실 분은 아이엑셀러 닷컴 사이트 정문 왼쪽에 있는 'VBA 강좌 - VBA 입문강좌'를 읽어보시면 이해가 빠릅니다.