• 최초 작성일: 2004-12-14
  • 최종 수정일: 2022-07-10
  • 조회수: 93,841 회
  • 작성자: 엑셀러 권현욱
  • 강의 제목: 레인지 개체 생성 (4) ㅡ Union, Intersect 메서드

엑셀러 권현욱

들어가기 전에

지난 시간에 잭 니클라우스의 얘기를 소개해 드렸습니다. 스펜서 존슨의 <선물>이라는 책에도 비슷한 구절이 나옵니다.

"멋진 미래의 모습은 어떠한지 그림을 그려라.
현실적인 계획을 세워 그것을 달성할 수 있게 하라.
계획을 지금 이 순간 행동으로 옮겨라."

크리스마스 이브가 열흘 앞으로 다가왔습니다. 이른 감이 없지 않지만, 미리 메리 크리스마스~~(^^)



레인지 오브젝트 네 번째 시간으로 Union, Intersect 메서드에 대해 살펴보겠습니다. 이번 강좌도 <VBA로 엑셀에 날개달기>(권현욱 저, 디지털북스 출판)에서 발췌하여 싣습니다.

Union 메서드

수학을 배울 때, 집합에는 합집합, 교집합, 부분집합, 차집합, 여집합, 공집합, 유한집합, 무한집합 등 여러 종류가 있다고 들으셨을 겁니다(참으로 많기도 하지요?).

Union 메서드는 집합 중에서도 합집합과 비슷한 개념입니다. 서로 떨어져 있는 여러 영역(Range 오브젝트)의 합집합 영역에 접근할 때 사용합니다. 다음과 같은 데이터에서 합집합에 해당하는 영역은 어디일까요?

로드 중...

합집합에 해당하는 영역은?

크게 어려움 없이 대답할 수 있을 겁니다. A1:E16 그리고 G11:J16 영역이 되겠지요.

로드 중...

눈으로 보았을 때는 알겠는데 이것을 VBA로는 어떻게 접근할 수 있을까요? 바로 Union 메서드를 이용하면 됩니다.

Sub Union_Method()
    Dim shtSheet As Worksheet
    Dim rngFirst As Range
    Dim rngSecond As Range
    Dim rngUnion As Range

    Set shtSheet = Sheets("Sheet6")
    Set rngFirst = shtSheet.Range("A1").CurrentRegion
    Set rngSecond = shtSheet.Range("G11").CurrentRegion
    Set rngUnion = Application.Union(rngFirst, rngSecond)

    rngUnion.Select
    MsgBox "두 영역의 합집합 : " & Selection.Address(rowabsolute:=False, _
                columnabsolute:=False)
End Sub

CODE

아, 상당히 복잡해 보입니다. 하지만 복잡한 것과 복잡해 보이는 것과는 차이가 있습니다. 위 코드는 지금까지 우리가 VBA 기초 강의 시간에 다루었던 것에 비해 길이가 조금 길어서 복잡해 보이는 것이지 실제로 복잡한 것은 아닙니다. 실제로 복잡한 것의 진수(?)를 보여 드릴까요?

"그가 생각하는 것을 나도 생각한다고 그가 생각하리라는 것을 나는 생각한다." (John F. Nash Jr.)

지정한 두 셀(A1, G11 셀)의 CurrentRegion을 rngFirst와 rngSecond 변수에 담은 다음, 이것을 Union 메서드를 이용하여 합쳤습니다.

그렇다면 질문이 하나 있는데요... 이딴거는 배워서 어디다 써 먹나요?

좋은 질문입니다. 이것을 조금 응용해 보죠. A1:A100 영역 중에서 짝수 행 데이터만을 선택한 다음 녹색으로 칠하는 예제를 만들어 볼까요.

로드 중...

A1:A100 영역 정도밖에 되지 않으니 그나마 다행이지, 작업할 영역이 A1:A1000이나 A1:A10000쯤 된다고 생각해 보세요. Ctrl 키를 누른 채 마우스를 눌러대려면 손가락에 쥐가 납니다. 하지만 우리는 다음과 같은 간단한 코드 몇 줄로 해결할 수 있습니다(이래도 VBA 안 배운다고 버팅기는 분이 있을래나).

Sub Union_Method_2()
    Dim i As Integer
    Dim rngUnion As Range
    Set rngUnion = Cells(2, 1)

    For i = 2 To 100 Step 2
        Set rngUnion = Union(rngUnion, Cells(i, 1))
    Next i
    rngUnion.Select
    Selection.Interior.ColorIndex = 10

    MsgBox "짝수 행 셀에만 녹색을 칠하였습니다"
End Sub

CODE

에이~~ 이것도 그다지 실용적이지 못한 것 같은데요?

(정색을 하고 가까이 다가서며) 과연 그럴까요?

(뜻밖의 강한 반응에 순간 움찔하다 다시 정신을 수습하며) 그게 아니라, 실무에서 그렇게 딥다 색칠만 하는 경우가 어디 있어요!

앞의 예제도 실용성이 없다고 생각하는 분들을 위해 한 가지 예를 더 보죠. 다음과 같은 성적표가 있다고 할 때 등급이 '합격'인 사람만 녹색으로 표시하는 예제입니다.

로드 중...

이렇게 하기 위해 사용한 코드는 아래와 같습니다.

Sub Union_Method_3()
    Dim rngCell As Range
    Dim rngAverage As Range
    Dim rngSource As Range
    Dim rngUnion As Range    

    Set rngAverage = Range("평균")
    Set rngSource = Range("Source")

    With rngSource
        .Interior.ColorIndex = xlNone
        .Font.ColorIndex = 1
    End With
    MsgBox "기존 서식을 지웠습니다. 이제 합격자들에 대해 표시를 합니다."

    For Each rngCell In rngAverage
        With rngCell
            If .Offset(0, 1) = "합격" Then
                If rngUnion Is Nothing Then
                    Set rngUnion = Range(.Offset(0, -4), .Offset(0, 1))
                Else
                    Set rngUnion = Union(rngUnion, Range(.Offset(0, -4), .Offset(0, 1)))
                End If
            End If
        End With
    Next rngCell
    rngUnion.Select

    With Selection
        .Interior.ColorIndex = 10
        .Font.ColorIndex = 2
    End With
End Sub

CODE

Intersect 메서드

Union과는 반대로 Intersect 메서드를 사용하면 두 개 이상의 영역 중에서 서로 겹쳐지는 영역의 주소를 알아낼 수 있습니다. 수학으로 치면 교집합에 해당하는 영역을 구해줍니다.

로드 중...

수학의 교집합

Intersect 메서드를 이용하면 위의 교집합에 해당하는 영역에 접근할 수 있습니다.

로드 중...

Intersect를 사용하면 교집합 영역(회색)에 접근 가능

위 그림에서 회색 영역에 접근하기 위해 사용한 코드는 이렇습니다.

Sub CurrentRegion_Property()
    Dim rngFirst As Range
    Dim rngSecond As Range
    Dim rngIntersect As Range
    Dim i As Integer    

    Set rngFirst = ActiveSheet.Range("A1:D8")
    Set rngSecond = ActiveSheet.Range("C5:G12")

    rngFirst.Select
    MsgBox "첫번째 영역입니다"

    rngSecond.Select
    MsgBox "두번째 영역입니다. 이제 교차영역을 표시합니다"

    Set rngIntersect = Application.Intersect(rngFirst, rngSecond)
    rngIntersect.Select

    For i = 1 To 1000
        rngIntersect.Interior.ColorIndex = Rnd * 56
    Next i
End Sub

CODE

코드가 이해되지 않는다고 너무 스트레스 받지 마시기 바랍니다. 지금 단계에서는 전체적인 흐름과 구조를 익히는 것이 중요합니다.

어느 곳에 어떻게 활용할 것인가 하는 것은 결국은 응용력의 문제이며, 응용력은 평소에 자신이 처한 상황을 얼마나 문제의식을 가지고 깊이 있게 고민해 보았느냐에 따라 결정됩니다. 그래서 VBA는 신입사원이나 업무에 익숙하지 않은 분들보다 해당 업무에 노련한 분들이 더 빨리 배우는 경우를 많이 보았습니다. 자신의 업무에 어떻게 응용할 것인지에 대해 많이 고민해 보세요.