들어가며
엑셀에서 가장 중요한 개체를 하나 꼽으라면 단연 '레인지(Range) 개체'라고 할 수 있습니다. 다른 개체가 덜 중요해서가 아니라 우리가 워크북 개체(파일)를 열고 워크시트에서 작업하는 공간이 레인지 개체이기 때문입니다. 레인지 개체를 통하지 않고서는 할 수 있는 일이 별로 없다고 해도 과언이 아닙니다. 레인지 개체를 만나러 출발합시다.
이 콘텐츠는 <엑셀 VBA 파워 코딩의 정석>(권현욱 저, 디지털북스 출간)에서 편집, 인용한 것입니다.
중간 정리
지금까지 배운 내용을 세 문장으로 정리하면 이렇습니다.
- 모든 개체는 적어도 하나 이상의 프로퍼티나 메서드를 가진다.
- 프로퍼티는 개체의 성질머리(형용사), 메서드는 오브젝트를 움직이도록 만드는 수단(동사)이다.
- 개체에는 일반 '개체'와 '컬렉션 개체' 이렇게 두 가지 종류가 있다(cf. 개별 타이어 vs 타이어).
강의를 하다 보면 한 가지 개념을 여러 가지 표현으로 바꿔서 소개하거나 한글/영어 표현을 일관성 없이(?) 섞어 쓸 때가 있습니다. 같은 개념을 상황에 따라 표현만 다르게 사용하는 것이며, 대표적으로 아래와 같은 것들이 있습니다. 헷갈리지 마시기 바랍니다.
- 프로시저 vs 서브 프로시저
- 개체 vs 오브젝트
- 속성 vs 프로퍼티
- 메서드 vs 방법
"이게 프로퍼티인지 메서드인지를 어떻게 구분하죠?"라고 묻는 분들이 있습니다. 그렇죠. 색깔로 구분할 수도 없고 머리에 뿔이 나 있는 것도 아닐 테니까요.
제가 드리는 답변은 "굳이 구분할 필요 없다"입니다. 경험이 쌓이면 직관적으로 어느 정도 구분할 수 있지만 지금도 헷갈리는 것들이 있습니다. Excel 도움말에서도 어떤 버전에서는 프로퍼티라고 했다가 다른 버전에서는 메서드라고 하는 것이 있는 걸 보면 Microsoft 엔지니어들도 사정은 크게 다르지 않은가 봅니다.
둘을 구분할 필요는 없지만 확실하게 알 수 있는 방법은 있습니다. VBA에서는 개체를 프로퍼티나 메서드와 연결할 때 '개체.메서드'처럼 점(.)으로 연결합니다. 이 점(.)을 '도트 연산자'라고 부릅니다. 코딩할 때 개체 다음에 도트 연산자를 입력하면 그 시점에서 사용할 수 있는 하위 목록이 나타납니다. 목록 앞에 있는 아이콘의 모양을 보면 프로퍼티인지 메서드인지 여부를 알 수 있습니다.
연두색 책(사전?) 모양이 있으면 메서드, 손가락 아이콘이 있으면 프로퍼티입니다.
레인지 개체
Range 개체는 VBA로 프로그래밍을 할 때 가장 빈번하게 사용되는 중요한 개체입니다. 엑셀에 입력되는 대부분의 데이터들이 Range 오브젝트에 보관됩니다. 레인지 오브젝트의 개념만 잘 이해하면 나머지 오브젝트에 대한 것은 거저먹기나 마찬가지입니다.
Range 개체는 워크시트 오브젝트의 하위 개체로, 한 개 또는 복수 개의 셀들로 이루어집니다. Range 개체에 접근하는 방법은 여러 가지가 있습니다. 다음은 그중 대표적인 몇 가지입니다.
- Range 속성
- Cells 속성
- Offset 속성
- Resize 속성
레인지 개체의 여러 가지 속성 중에서 Range와 Cells 속성이 가장 많이 사용되고 중요합니다. 두 속성에는 각각 어떤 장단점이 있는지, 어떤 경우에 사용하면 좋은지 살펴보겠습니다.
Range 속성
다음 코드를 실행하면 Sheet1의 A1 셀에 숫자 100을 입력합니다.
Sub writeData_1()
Worksheets("Sheet1").Range("A1").Value = 100
End Sub
이것은 (1) Worksheets("Sheet1")이라는 워크시트 개체에서, (2) Range("A1")이라는 레인지 개체의, (3) Value 속성값을 100으로 지정하라는 명령입니다.
Range 개체의 디폴트(default) 속성값은 Value입니다. 자동차를 살 때에도 기본으로 딸려 나오는 것이 있고 옵션으로 추가하는 것이 있습니다. 디폴트 속성은 속성명을 따로 붙이지 않아도 붙인 것으로 자동 처리해 줍니다. 즉, 맨 뒤에 있는 'Value'는 생략해도 됩니다.
이 시점에서 헷갈리는 부분이 나옵니다.
"두 번째에 있는 Range는 속성이라고 했는데 어떻게 뒤에 또 Value 속성이 오죠? 속성이 속성을 가질 수도 있는 건가요?"
예리한 질문입니다. (2) Range는 '속성이면서 개체'입니다. Range("A1")이라고 하는 순간 레인지 개체가 만들어지고, 여기에(즉, 레인지 개체에) Value 속성을 사용한 형태입니다.
이번에는 여러 셀에 동일한 값을 넣어볼까요. Range("A1:A10")처럼 값을 입력할 영역을 지정하고 넣을 값을 적어주면 됩니다. 숫자가 아닌 문자열을 입력하려면 큰 따옴표로 둘러싸 주어야 한다는 점에 유의하세요.
Sub writeData_1()
Worksheets("Sheet1").Range("A1:A10").Value = "엑셀 VBA"
End Sub
이번에는 불연속적인 여러 개의 셀에 값을 넣는 방법에 대해 살펴봅니다.
Sub writeData_2()
Range("A1,A3,A5,A7,A9,B2,B4,B6,B8,B10") = "엑셀 VBA"
End Sub
각 셀을 콤마(,)로 구분하여 적어주면 됩니다. 이 코드에서는 Range 개체 앞에 시트명을 따로 적지 않았습니다. 시트명을 생략하면 디폴트 값으로 현재 시트(ActiveSheet)를 작업 대상으로 합니다. 그리고 앞에서 언급한 것처럼 Range 개체의 기본 속성인 Value를 생략했습니다.
Cells 속성
Cells 속성을 사용해도 셀에 접근할 수 있습니다. 다음 코드를 실행하면 현재 시트의 B5 셀에 숫자 '100'을 입력합니다. Cells 속성은 Cells(행, 열)의 형식으로 표기합니다. Range 속성의 표현 방법과는 순서가 반대이므로 주의하시기 바랍니다.
Cells(5,2) = 100
Cells 속성으로 셀 범위(하나 이상의 셀)에 접근하고자 할 때에는 Range와 조합해서 사용합니다. Cells 속성(Range 속성도 마찬가지) 앞에 아무것도 붙이지 않았으므로 현재 워크시트를 대상으로 합니다.
Range(Cells(3, 2), Cells(10, 5)).Select
다음은 MySheet의 A2 셀에 'VBA Programming'이라는 문자열을 입력하는 코드입니다. 행과 열 표기 순서가 Range 속성과 반대라는 점만 이해하면 어려울 것은 없습니다.
Worksheets("MySheet").Cells(2, 1).Value = "VBA Programming"
여기서 한 가지 주의할 점이 있습니다. 만약 Cells(3, 2)라고 하면 어느 셀을 지정한다고 생각하십니까? 아마도 지금까지 공부를 제대로 해 온 분이라면,
"그것도 질문이라고... 행 방향으로 3, 열 방향으로 2만큼 이동한 곳의 셀이니까 당연히 B3 셀이죠!"
아마 이렇게 답하시겠죠? 하지만 정답은, '그럴 수도 있고 아닐 수도 있다!'입니다. 먼 소린지 알 듯 모를 듯하죠? 어떤 범위 내에서 명령을 사용하느냐에 따라 달라진다는 뜻입니다. 만약 Cells 속성 앞에 아무것도 없이 그냥 Cells(3, 2)라고 하면 3행과 2열이 만나는 B3 셀을 의미합니다.
하지만 앞에 레인지 개체가 붙어 있으면 사정은 달라집니다. 다음과 같은 코드가 있다면 어느 셀에 100이라는 값을 넣어주게 될까요?
Range("B2:E9").Cells(3, 2) = 100
Range("B2:E9").Cells(3, 2)라는 것은 B2:E9 영역 내에서 행 방향으로 3번째, 열 방향으로 2번째에 있는 셀을 말합니다. 따라서 C4 셀에 숫자 100을 입력하게 됩니다. 이해가 되시나요?
Cells 속성은 어떤 경우에 쓰면 좋을까?
지금까지 Range 속성과 Cells 속성에 대해 살펴보았습니다. 그런데 Cells 속성의 경우, 정의된 이름을 사용할 수 없고, 셀 범위를 설정할 때에도 단독으로는 사용할 수 없으며 Range 속성과 조합해서 써야 합니다.
잘못된 사용 예 (X) | 올바른 사용 예 (O) |
Cells("지역별_매출").Select | Range("지역별_매출").Select |
Cells(Cells(2, 1), Cells(5, 7)).Select | Range(Cells(2, 1), Cells(5, 7)).Select |
그렇다면 불편하게만 보이는 Cells 속성은 뭐 하러 만들어 놓았을까요? Cells 속성의 가장 큰 장점은 인수에 숫자값을 사용할 수 있다는 것입니다. 다음과 같은 구구단 테이블을 만든다고 생각해 보세요.
만약 Range 속성만으로 이런 것을 만들어야 한다면? 머리가 조금 아파 옵니다. For ~ Next 반복문과 Cells 속성을 조합하면 간단히 해결할 수 있습니다. 핵심적인 코드는 겨우 5줄밖에 안 됩니다.
아직 우리는 반복문을 배우지 않았으므로 다음 코드를 명확히 이해할 수는 없습니다. Cells 속성이 사용되었다는 것만 확인하고 나머지는 눈치(?)로 흐름을 파악하실 수 있을 겁니다.
Sub 구구단_테이블()
Dim i As Integer
Dim j As Integer
For i = 2 To 9
For j = 1 To 9
Cells(j + 1, i - 1) = i & " X " & j & " = " & i * j
Next j
Next i
End Sub
나가며
축하합니다. 이제 여러분은 VBA 코딩의 가장 중요한 개체와 그 개체에 접근하는 2가지 속성을 알게 되었습니다. 이것만으로도 많은 일을 처리할 수 있습니다. 일단 오늘은 여기까지 하시고, 진도를 더 나가기보다 지금까지 배운 내용을 되짚어보는 시간을 가져보시기 바랍니다. 수고하셨습니다.
'VBA' 카테고리의 다른 글
[VBA 입문] 08강. 레인지 개체(3) ㅡ 사용된 영역에 접근하기 (92) | 2023.10.01 |
---|---|
[VBA 입문] 07강. 레인지 개체(2) ㅡ 행/열 단위로 범위 확장하기 (118) | 2023.09.30 |
[VBA 입문] 05강. 워크시트 개체 (80) | 2023.09.27 |
[VBA 입문] 04강. 워크북 개체 (110) | 2023.09.27 |
[VBA 입문] 03강. Excel VBA 필수 개념 4가지 (107) | 2023.09.27 |