• 최초 작성일: 2000-10-31
  • 최종 수정일: 2026-09-30
  • 조회수: 18 회
  • 작성자: 권현욱 (엑셀러)
  • 강의 제목: 여러 시트의 데이터 비교하기

들어가기 전에

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

이번 시간에는 질문 하나를 살펴봅니다.

VBA를 본격적으로 공부해 보려고 코드를 짜려는데 무척 헷갈린다는 질문입니다. 두 개의 데이터를 비교해서 코드가 같으면 값을 읽어오는 작업인데, 원래 VLOOKUP 함수를 사용해 보았으나 자료가 4만 건이라 속도가 엄청나게 느려지고 수시로 재계산을 하는 통에 속이 터진다며 도움을 청하셨습니다. 감기 조심하라는 인사도 함께 주셨습니다.

세상 만사가 다 그런 것 같습니다. 남들이 해 놓은 것을 보면 "그 정도는 나도 마음만 먹으면 얼마든지 한다. 마음을 잘 안먹어서 그렇지… (우물쭈물)… " 싶지만 정작 할려고 하면 뜻대로 안되는 것이지요. 이것은 모든 것을 자기를 기준으로 판단하기 때문입니다.

고속도로에서 차를 운전할 때, 자기보다 빠른 속도로 가는 차들은 다 "죽으려고 용쓰는 차"들이고, 자기보다 느린 차는 "원활한 교통 흐름을 방해하는 차"라고 생각들을 하는 것도 바로 거기에서 연유하는 것입니다.

소스 데이터를 공개하지 말아 달라고 요청하셨기 때문에 자료를 하나 만드느라 애먹었습니다. 혹시 질문하시는 분 중에 자료공개를 원치 않는 분은 이분처럼 꼭 말씀을 해 주시기 바랍니다. 안그러면 Exceller 맘대로(?) 인용을 할 테니까요.

사실 이 질문에 대한 답변은 VB0038(여러 시트 내용을 한 시트로 합치기) 강좌편을 참고하시면 충분히 해결가능한 것이나 이런 류의 질문을 하시는 분이 끊이지 않아 복습을 겸해 다시 한번 설명을 드리겠습니다. 하지만 VB0038 강좌와는 약간 다른 방법으로, 조금 단순화시켜 설명드릴테니 이번에 확실히 이해하시기 바랍니다. 버튼을 눌러 보세요. 시간이 좀 걸리니까 차나 한잔 하고 오세요.

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

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

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


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

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

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

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

여러 시트의 데이터 비교하기

핵심 요약: 코드로 여러 시트 데이터 옮기기

TARGET 시트의 거래처 코드와 월별 시트의 코드를 비교해 같으면 실적을 옮기고 Exit For로 반복을 빠져나옵니다.

  • 1단계: SpecialCells(xlTextValues)로 각 시트의 코드가 있는 셀을 변수에 담습니다.
  • 2단계: TARGET의 각 코드를 월별 시트의 코드와 For Each로 비교합니다.
  • 3단계: 같은 코드를 찾으면 실적을 옮기고 Exit For로 빠져나옵니다.

Step 1: 데이터 구조 살펴보기

TARGET 시트의 A열에는 거래처 코드, B열에는 거래처명이 있고 C열(SALES_01)과 D열(SALES_02)에 월별 실적을 채워 넣습니다. Sales_01, Sales_02 시트에는 각각 거래처 코드와 실적이 들어 있습니다(예제 시트에는 약 500건이 들어 있습니다).

CODENAMESALES_01SALES_02
A0001거래처A01(Sales_01에서 가져옴)(Sales_02에서 가져옴)
A0002거래처A02
……
CODESALES_01(또는 SALES_02)
A00299,824.55
A00309,003.67
……

작업 진행과정을 시각적으로 보여드리려고 이것저것 집어넣었기 때문에 작업속도는 좀 떨어집니다. 실제 여러분이 사용하실 때에는 이러한 요소들을 없애버리면 훨씬 빠르게 돌아갈 것입니다.

Step 2: 데이터 이전 코드 작성하기

Sub DataTransfer()
    Dim rngCell As Range
    Dim rngTarget As Range
    Dim rng01 As Range, rng01S As Range
    Dim rng02 As Range, rng02S As Range
    '//한 행에 두 개 이상의 변수를 선언해 줄 때에는 위와 같이 콤마로 구분하되 변수의 타입을
    '//명기해 주어야 합니다. 만약 이것을
    '//Dim rng01, rng01S as Range
    '//이렇게 하면 rng01S는 Range 오브젝트 변수로 선언이 되나 rng01은 Range Object가 아닌
    '//Variant형 변수로 선언이 되므로 주의하시기 바랍니다.

    Set rngTarget = Worksheets("target").Range("a:a").SpecialCells(xlTextValues)
    Set rng01S = Worksheets("Sales_01").Range("a:a").SpecialCells(xlTextValues)
    Set rng02S = Worksheets("Sales_02").Range("a:a").SpecialCells(xlTextValues)

    For Each rngCell In rngTarget
        For Each rng01 In rng01S
        '//이제부터 순환문을 돌면서 Target 시트의 거래처 코드와 Sales_01, Sales_02 시트의
        '//거래처 코드를 비교하여 코드가 같으면 자료를 옮겨줍니다.

            If rngCell = rng01 Then
            '//먼저 Target 시트의 거래처 코드와 Sales_01 시트 내의 거래처 코드들을 비교합니다.
            '//그래서 같은 것이 발견되면 Sales_01 시트의 해당값을 Target 시트에 옮겨 적은 다음,
            '//Exit For 문을 사용해서 순환문을 빠져 나갑니다.

                Application.DisplayStatusBar = True
                rngCell.Offset(0, 2) = rng01.Offset(0, 1)
                Application.StatusBar = "TARGET: " & rngCell.Offset(0, 2) & "/Sales_01: " & _
                    rng01.Offset(0, 1)
                Exit For
            End If
        Next rng01

        For Each rng02 In rng02S
        '//이번에는 Target 시트의 거래처 코드와 Sales_02 시트 내의 거래처 코드들을 비교해서
        '//같은 것이 발견되면, Target 시트에 그 값을 기재하고 역시 Exit For문을를 사용해서
        '//For~Next 반복문을 빠져나갑니다.

            If rngCell = rng02 Then
                Application.DisplayStatusBar = True
                rngCell.Offset(0, 3) = rng02.Offset(0, 1)
                Application.StatusBar = "TARGET: " & rngCell.Offset(0, 3) & "/Sales_02: " & _
                    rng02.Offset(0, 1)
                Exit For
            End If
        Next rng02

    Next rngCell
    Application.StatusBar = ""
    MsgBox "Data Transferring 작업이 끝났습니다", , "작업 완료//Exceller"
End Sub

이 코드는 원리를 쉽게 보여 주는 이중 반복문(For Each)이어서 자료가 4만 건이면 매우 느려집니다. 실무에서는 Scripting.Dictionary에 코드를 키로 담아 두고 찾거나, 배열로 읽어 처리하면 훨씬 빠릅니다. 또한 최신 엑셀에서는 XLOOKUP이나 Power Query 병합도 좋은 대안입니다.

숙제

몇 개의 시트라도 이런 식으로 가능할 것입니다. 이 코드를 보니까 어떤 생각이 드십니까? 혹시 VB0038 강좌에서 설명드린 "여러 시트 내용을 한 시트로 합치기" 강좌보다 쉽다는 생각이 드는 분이 있으시지요? 그런 생각이 드는 분은 자기자신도 모르게 실력이 일취월장하신 분입니다.

만약 그런 분들은 이 코드를 수정해 보시기 바랍니다. 어떻게? 오늘 강좌는 쉽게 설명을 드리기 위해 TARGET 시트에 있는 거래처 코드와 각 월별 시트에 있는 그것이 서로 같습니다. 그런데 경우에 따라서는 1월에는 있던 거래처가 폐쇄되어 2월에는 실적이 없을 수도 있고, 반대로 2월에 신설된 거래처의 경우에는 1월에 실적이 없을 수도 있겠지요? 이러한 경우를 체크할 수 있는 코드를 직접 만들어 보시기 바랍니다. 그다지 어렵지는 않을 것입니다.

마무리

어느덧 10월의 마지막 밤… 아니 날이군요. ^___^ 잘들 보내시고 11월에도 변함없이 의미있는 날들이 되시기를 바랍니다.

다음 시간에…

정리 — 여러 시트 데이터 비교 핵심

구분 사용한 코드 역할
코드 셀 수집 Range("a:a").SpecialCells(xlTextValues) 텍스트가 있는 셀만 대상
비교 If rngCell = rng01 Then 코드가 같은지 확인
값 옮기기 rngCell.Offset(0, 2) = rng01.Offset(0, 1) 같은 행의 실적 복사
반복 종료 Exit For 찾으면 안쪽 반복 종료
진행 표시 Application.StatusBar 상태표시줄에 진행 상황 표시

자주 묻는 질문 (FAQ)

Q1. VLOOKUP이 너무 느릴 때는 어떻게 하나요?

VBA로 코드를 비교해 값을 옮기거나, 배열이나 Dictionary를 활용하면 속도를 크게 높일 수 있습니다.

Q2. Dim rng01, rng01S As Range처럼 선언하면 어떻게 되나요?

rng01S만 Range로 선언되고 rng01은 Variant형이 되므로 각 변수에 타입을 명기해야 합니다.

Q3. Exit For는 언제 사용하나요?

찾고자 하는 값을 발견하면 나머지 반복이 필요 없으므로 반복문을 빠져나올 때 사용합니다.

마치며

원리를 이해하면 몇 개의 시트라도 같은 방식으로 데이터를 비교해 옮길 수 있습니다.