• 최초 작성일: 2023-08-21
  • 최종 수정일: 2023-08-21
  • 조회수: 3,458 회
  • 작성자: 권현욱 (엑셀러)
  • 강의 제목: 중복 값을 제거하는 VBA 코딩법 2가지

들어가기 전에 ㅡ 개/고양이보단 나은 사람이 되고자 하였으나

'동물의 왕국'을 좋아하는 사람들이 많다. 40대 이상 중장년 남성층에서 특히 두드러진다. 이유는 다양하다. '동물은 배신하지 않아서', '자연의 순리를 깨달을 수 있어서', '우리 안에 내재된 공격성이 적나라하게 발현되므로' 등이다. 소수 의견으로 이런 것도 있다. '물소 떼가 연대해서 사자의 공격을 막아내는 통쾌한 역전이 있어서'(뭐지, 이건?)

지인이 동영상 링크를 하나 보내 줬다. 곰 한 마리와 할아버지(정확하게는 '푸바오'와 '강할부지')가 투닥거리는 영상이었다. 생각이 정리되지 않을 때마다 보면서 피식거리기도 하고 아무 생각 없이 빠져 들기도 했다. 추천 영상이 이내 곰으로 도배되기 시작했다.

로딩 중...

에버랜드 유튜브 채널

유튜브를 처음 시작할 때 작은 다짐(혹은 기대)을 했다. '개나 고양이만도 못한 사람은 되지 말자'가 그것이었다. 개나 고양이를 능가하는 사람이 되기 어렵다는 걸 깨닫는 데는 그리 오랜 시간이 필요치 않았다(잠자고 물만 마셔도 몇 십만 뷰를 훌쩍 넘어가는 녀석들을 어떻게 이긴담?)

우리 사회가 푸바오에게 열광하는 것은 그만큼 힘들고 비정상적인 사회의 단면을 보여주는 게 아닐까 하는 생각이 들었다. 안타까운 사고가 수습되기도 전에 더 큰 사건으로 덮히고 있으니 왜 안 그렇겠는가.

사회가 정상을 되찾아서 '곰 영상'보다 '엑셀러TV' 같은 콘텐츠가 더 관심을 받는 날이 왔...으면 좋겠지만 그건 아마 힘들겠지?(푸바오의 인기는 이제 아이돌급이다. 톱스타들에게만 해준다는 지하철 생일 광고도 최근에 받았다)

동물을 보고 있으면 혈압이 떨어지고 심신이 안정된다는 연구 결과들도 있고, 반려동물과의 상호 교감을 통해 정신적 안정감을 주는 '애니멀 테라피'animal theraphy도 있다고 하니 이제 공연한 경쟁심은 접고 '덕심'을 발휘해 볼까나.

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

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

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


이 글은 멤버십 회원 우선 공개 콘텐츠입니다. 전체 대상으로는 일주일 후 공개됩니다(작성일 기준).
26년 경력 Microsoft MVP 권현욱(엑셀러) 대표 직강 1강 무료

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

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

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

중복 값을 제거하는 VBA 코딩법 2가지

핵심 요약: 엑셀 VBA로 중복 값을 제거하는 2가지 코딩법

여러 항목 중에서 중복을 제거하고 고유한 값만 추출하는 VBA 코드를 두 가지 방법으로 소개합니다. 수식이나 기본 기능으로는 어려운 작업까지 유연하게 처리할 수 있는 기본기를 익히는 데 집중합니다.

  • 컬렉션 개체: New Collection으로 개체를 만들고 Add 메서드의 key 인수에 셀 값을 지정하면, 같은 key는 오류가 발생해 추가되지 않으므로 고유한 값만 남습니다.
  • 오류 무시: 중복 key로 발생하는 오류를 넘기려면 On Error Resume Next 문이 반드시 필요하며, 이 덕분에 작업이 중단되지 않고 계속 진행됩니다.
  • For ~ Next 문과 InStr: 컬렉션 개체 없이도 InStr 함수로 이미 등장한 값인지 확인하고, 새로운 값일 때만 결과 셀에 표시하며 문자열 변수에 계속 누적하는 방법입니다.
  • 정렬 추가: 프로시저 마지막에 Sort 메서드를 한 줄 추가하면 결과를 정렬할 수 있으며, 오름차순은 xlAscending, 내림차순은 xlDescending을 사용합니다.

사전 준비

얼마 전 강의에서 수식과 기본 기능을 이용하여 '중복된 항목 제거'하는 법에 대해 알아보았습니다. 4가지 방법으로 해결했었죠(수식 2가지 + 기본 기능 2가지).

VBA를 이용하여 해결할 수도 있습니다. VBA에 대해 알아야 하지만 훨씬 다양하고 복잡한 작업도 유연하게 처리할 수 있습니다. 어떻게 활용하는 지는 다른 강의에서 다루기로 하고, 이번 시간에는 기본기를 익히는 데 집중하도록 합니다.

이 강의는 아래 동영상 강의 내용과 보완 관계에 있습니다. 동영상과 함께 보시면 이해하기 더욱 쉽습니다.

워크시트 상태에서 ALT + F11 키를 눌러 Visual Basic Editor를 띄웁니다. [삽입] - [모듈] 메뉴를 선택해서 모듈 시트를 한 장 삽입하고 코딩을 시작합니다.

로딩 중...

코딩 준비

방법 1: 컬렉션 개체 이용

중복된 값이 있는 여러 항목 중에서 고유한 값만 추출할 때, 컬렉션 개체Collection object를 많이 사용합니다.

컬렉션 개체는 변수를 선언할 때 'New'라는 키워드를 붙여야 합니다다.

Dim oWords As New Collection

컬렉션 개체에 구성원을 추가할 때에는 Add, 제거할 때에는 Remove 메서드를 사용합니다. 실제 코드를 보도록 하죠.

Sub getUniqueWords()
    ''' 변수 선언        
    Dim shtWord As Worksheet
    Dim rTbl As Range           
    Dim rWrite As Range
    Dim oWords As New Collection    ''' 컬렉션 개체
    Dim vX As Variant    ''' 컬렉션 개체의 각 구성원에 접근
    Dim rX As Range
    Dim iX As Integer
    
    On Error Resume Next    ''' 반드시 필요
    Set shtWord = Worksheets("연습")
    Set rTbl = shtWord.Range("B3").CurrentRegion
    Set rTbl = rTbl.Offset(1).Resize(rTbl.Rows.Count - 1)
        ''' B열에서 제목을 제외한 영역을 rTbl 변수에 재지정

    Set rWrite = rTbl.Cells(1).Offset(, 8)    
        ''' 결과를 표시할 위치(J4 셀)
    Range(rWrite, rWrite.End(xlDown)).Clear
        ''' 결과를 표시할 영역 주변 정리
    
    ''' 컬렉션 개체에 항목을 겹치지 않게 추가하는 과정
    ''' 세부 설명은 아래에서
    For Each rX In rTbl.Cells
        oWords.Add rX, rX
    Next

    ''' J4 셀부터 결과 표시(J5, J6,...)
    For Each vX In oWords
        rWrite.Offset(iX) = vX
        iX = iX + 1
    Next
End Sub

CODE

컬렉션 개체에 항목을 추가할 때에는 Add 메서드를 이용합니다. 이 때 다음과 같은 형식을 사용합니다.

oWords.Add item:=rX, key:=rX
(또는 oWords.Add rX, rX)

항목을 추가할 때, item과 key를 사용하는데, 만약 같은 key 값이 이미 있다면 오류가 발생하여 실행이 중단됩니다. 하지만 앞에서 On Error Resume Next 문을 추가해 두었으므로 작업이 계속 진행되고, 결과적으로 중복되지 않는 항목들이 컬렉션 개체에 저장됩니다.

프로시저 내부에 커서를 둔 채, [실행] 아이콘을 클릭하면 지정한 위치에 결과가 표시됩니다.

로딩 중...

방법 2: For ~ Next 문 이용

중복된 항목을 제거하려면 반드시 컬렉션 개체를 사용해야 하는 걸까요? 그렇지는 않습니다. 다른 방법도 가능합니다. 앞에서 작성한 코드를 조금 변형합니다. InStr 함수를 사용한 부분을 눈여겨 보세요.

InStr은 '한 문자열이 다른 문자열 내에서 처음 나타나는 위치'를 구해주는 VBA 함수로, 다음과 같은 형태로 사용합니다.

InStr ([시작], 문자열1 , 문자열2 , [비교])
[ ] 인수는 생략 가능
Sub getUniqueWords_2()
    Dim shtWord As Worksheet
    Dim rTbl As Range
    Dim rWrite As Range
    Dim rX As Range
    Dim iX As Integer
    Dim sWord As String     ''' 문자형 변수 추가
    
    On Error Resume Next
    Set shtWord = Worksheets("연습")
    Set rTbl = shtWord.Range("B3").CurrentRegion
    Set rTbl = rTbl.Offset(1).Resize(rTbl.Rows.Count - 1)
    Set rWrite = rTbl.Cells(1).Offset(, 9)
    Range(rWrite, rWrite.End(xlDown)).Clear

    For Each rX In rTbl.Cells
        If InStr(sWord, rX) = 0 Then
            ''' 이 조건이 True라는 것은 새로운 값이 등장했다는 뜻

            rWrite.Offset(iX) = rX    ''' J4 셀부터 결과 표시
            iX = iX + 1
            sWord = sWord & rX
                ''' 다음 비교를 위해 sWord에 rX 값을 계속 추가
        End If
    Next
End Sub

CODE

만약 결과값을 오름차순으로 정렬하려면 다음 한 줄을 프로시저 마지막에 추가하면 됩니다. 여기서부터는 VBA를 얼마나 알고 있느냐에 따라 활용도가 갈립니다.

Range(rWrite, rWrite.End(xlDown)).Sort key1:=rWrite, order1:=xlAscending, Header:=xlNo

내림차순으로 한다면 xlAscending 대신 xlDescending을 사용하면 됩니다.

이 밖에도 다른 방법들이 있을 수 있습니다. 응용력을 발휘하면 수식이나 엑셀 기본 기능으로는 할 수 없는 일들을 처리할 수 있습니다. 기회가 되면 다른 강의에서 다뤄보도록 하죠.