• 최초 작성일: 2000-12-12
  • 최종 수정일: 2026-09-30
  • 조회수: 9 회
  • 작성자: 권현욱 (엑셀러)
  • 강의 제목: 몇 가지 질문들

들어가기 전에

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

질문이 많이 멀려있어서 이번 강좌에서는 답변을 겸해서 진행을 해야할까 봅니다. 질문에 대해 제때 답변을 못드리면 꼭 무슨 빚을 진 것 처럼 마음 한켠이 영 찜찜합니다. 따라서 '메일 보낸 지가 언젠데 아직 답을 안주는 것이야?' 하고 짜증내거나 항의하는 분이 없으시기를… ^^;

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

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

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


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

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

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

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

몇 가지 질문들

핵심 요약: Union과 변수 선언

Union으로 떨어진 범위를 하나로 묶어 순환할 수 있고, 개체 변수는 Range 같은 구체적인 형식으로 선언하며, 셀 주소는 String 변수에 담습니다.

  • Union: 연속되지 않은 여러 범위를 하나의 범위처럼 다룹니다.
  • 변수 선언: Object보다 Range, Worksheet처럼 구체적인 형식이 빠르고 바람직합니다.
  • Address: 셀 주소는 Range가 아니라 String 형식입니다.

질문 1: 양수는 양수끼리, 음수는 음수끼리 더하기

안녕하십니까?
선생님의 강의를 보고 엑셀에 많은 관심이 생겼습니다.
감사를 드리며 질문 하나 올립니다.

(문)여러 범위를 지정하여 같은 범위 안에서 양수는 양수끼리, 음수는 음수끼리
더하고 싶은데 방법이 없는지요?

질문에 나온 것과 같이 서로 떨어져 있는 두 범위(왼쪽 3열, 오른쪽 2열)에 숫자가 들어 있다고 가정합니다(소수점 이하는 둘째 자리까지만 표시했습니다).

열1열2열3열4열5
90.4087.3531.9032.3221.69
41.0585.3284.9482.61-15.00
12.14-50.0033.6480.263.02
35.0138.39-47.00-35.0098.89
-100.0011.9510.8696.4851.57
89.297.21-87.008.84-103.00
59.7696.3062.8753.651.87

버튼을 눌러 보세요. 그러면 위에 있는 두 점선 부분에 대해 원하시는 계산을 할 것입니다.

이렇게 해서 나온 결과값이 맞나 안맞나 손바닥만한 전자계산기를 두드려가며 검산하는 분이 저쪽에 몇 분 보이는군요. ^^ 아직도 Excel을 사용하시는 분 중에 Excel로 작업한 계산 결과를 못 믿어서(사실은 못 믿는다는 것보다는 제대로 Excel을 다루지 못한다는 표현이 맞겠지만…) 이것을 쬐그만 계산기로 일일이 재확인하는 분이 많이 계십니다. 비극적인 일이지요. ^^; Excel 자체가 고성능 전자계산기, 그것도 수도 없이 많은 고성능 전자계산기의 복합체인 것을…

사실 Exceller도 전자계산기로 계산을 할 때가 가끔 있지만 그것은 아주 간단한 연산을 할 때, 화면상에서 왔다갔다하는 것이 번거롭게 여겨질 때 그러는 것이지 Excel의 결과를 못 믿어서 그런 것은 아닙니다. 어쨌거나 코드를 보도록 하지요.

Sub MyCalculation()
    Dim rngCell As Range
    Dim dblPlus As Double
    Dim dblMinus As Double
    Dim Msg As String

    For Each rngCell In Union(Range("MyRange1"), Range("MyRange2"))
    '//Range 오브젝트에 접근하는 데에는 몇 가지 방법이 있습니다. 가장 빈번하게 사용되는
    '//것이 Range Method와 Cells Method일 것입니다. 그런데 위에서 보니까 Union이라는
    '//새로운 방법이 하나 나왔군요. 이것은 연속적이지 않은 여러 범위를 지정할 때
    '//사용하는 방법입니다.

        If rngCell.Value >= 0 Then
            dblPlus = dblPlus + rngCell.Value
        ElseIf rngCell.Value < 0 Then
            dblMinus = dblMinus + rngCell.Value
        End If
        '//그 다음은 아주 간단하지요? 각 셀을 돌면서 셀 값이 양수이면 dblPlus 변수에,
        '//셀의 값이 음수이면 dblMinus 변수에 차곡차곡 담아둡니다.

    Next rngCell
    Msg = "선택하신 범위 내에서" & vbCr & vbCr
    Msg = Msg & "양수의 합계는  " & Format(dblPlus, "#,##0") & " 이고," & vbCr
    Msg = Msg & "음수의 합계는  " & Format(dblMinus, "#,##0") & " 입니다"
    MsgBox Msg, vbExclamation, "계산 완료//Exceller"
    '//순환이 끝났으면 변수에 저장된 값을 화면에 뿌려줍니다.
End Sub

질문 2: Object 변수와 Range 변수의 차이

변수를 선언해서 쓰는데 Object 변수는 이해하기가 어렵다는 질문입니다. Dim rngCell As Range를 Dim rngCell As Object로 바꿔도, Dim recRectangle As Rectangle을 Dim recRectangle As Object로 바꿔도 실행이 되는데 어떤 차이가 있는지 궁금하다고 하셨습니다.

변수의 타입과 선언방법만 잘 구분할 수 있어도 초보는 면할 수 있습니다. Integer, Long, Currency, Date 등과 같이 대부분의 변수는 선언을 할 때,

Dim I As Integer
Dim lngRow As Long
Dim curMoney As Currency
I=10
lngRow=ActiveCell.Row
curMoney=1000000

이런 식으로 사용하는데 비해 오브젝트 변수는

Set rngCell = Range("MyRange")
Set ovlMyOval = ActiveSheet.Ovals("MyOval1")

이런 식으로 변수에 값을 지정할 때 Set을 사용합니다.

Object 변수를 선언할 때

Dim rngCell As Object
Dim shtSheet As Object

이렇게 선언하는 것보다는 아래와 같이 선언하는 것이 더 효율적이고 바람직합니다.

Dim rngCell As Range
Dim shtSheet As Worksheet

기술적인(?) 용어로 설명을 하자면, 위의 것 RunTime으로 오브젝트에 접근하는 오브젝트에 접근하는 Generic(일반적인)한 방법이고, 아래의 것은 DesignTime 으로 오브젝트에 접근하는 Specific한 방법입니다. 따라서 아래의 방법이 더 수행속도가 빠르고 효율적이지요. 직접 확인해 보아야 직성이 풀리시지요? ^^

Method1/Method2 버튼을 누르세요.

Sub Method1()
    Dim rngCell As Object
    Dim i As Long
    Dim sngStart As Single
    sngStart = Timer
    For i = 1 To 10000
        Set rngCell = Range("A1")
        rngCell.Value = i
    Next i
    Range("Test") = Timer - sngStart
End Sub

Sub Method2()
    Dim rngCell As Range
    Dim i As Long
    Dim sngStart As Single
    sngStart = Timer
    For i = 1 To 10000
        Set rngCell = Range("A1")
        rngCell.Value = i
    Next i
    Range("Test2") = Timer - sngStart
End Sub

Method1은 Object로, Method2는 Range로 선언한 경우입니다. 실행해 보면 경과시간이 각각 약 2.58초, 2.48초로 나타나 약 0.1초의 차이를 보였습니다(당시 컴퓨터 기준).

아주 간단한 작업임에도 불구하고 수행속도에서 차이를 보이지요? 코드는 간단하니까 모듈시트를 살펴보시기 바랍니다.

Object로 선언하는 방식은 실행 시점에야 개체를 확인하는 후기 바인딩, Range·Worksheet처럼 구체적인 형식으로 선언하는 방식은 코드를 작성하는 시점에 확인하는 조기 바인딩입니다. 조기 바인딩은 속도가 빠를 뿐 아니라 코드 작성 중 자동 완성(IntelliSense)의 도움을 받을 수 있어 실수를 줄여 줍니다. 요즘 컴퓨터에서는 속도 차이가 크게 체감되지 않는 경우가 많지만 이 장점은 그대로입니다.

질문 3: 개체변수가 설정되어 있지 않다는 오류

다음은 질문하신 분의 코드입니다.

Sub ActiA()
    Dim a As Range
    Selection.End(xlDown).Select
    a=ActiveCell.Address

    Range(Selection,Selection.End(xlDown)).Select
    MsgBox "셀 주소는 " & a & "입니다"
End Sub

실행해 보니 런타임오류 91: 개체변수 또는 With 블록의 변수가 설정되어 있지 않습니다라는 메시지가 표시된다는 질문입니다. 또한 이렇게 얻은 주소 2개로 원하는 셀에 =SUM(변수1:변수2)와 같이 사용할 수 있는지도 물으셨습니다.

이것도 변수의 형태에서 착오를 일으키셨기 때문에 발생하는 오류입니다. 셀은 (Range) 오브젝트 이지만 셀의 주소는 문자열(String)입니다. 따라서

첫째 줄의 변수 선언을 아래와 같이 고쳐 주시면 됩니다.

Dim a As Range
Selection.End(xlDown).Select
a = ActiveCell.Address

이렇게 하신 부분을…

Dim a As String
Selection.End(xlDown).Select
a = ActiveCell.Address

이렇게 고치시면 되겠습니다.

그리고 두번째 질문하신 것도 물론 가능합니다.

같은 데이터에서 이번에는 두 개의 떨어진 범위(범위1, 범위2)를 Union 메서드로 묶어 선택하고 주소와 합계, 평균을 구해 봅니다.

이것도 Union Method를 사용해 보았습니다.

Sub ActiAByExceller()
    Dim Msg As String
    Dim strAddress As String
    '//선택된 영역의 셀주소를 받기 위해 strAddress라는 문자열 변수를 선언해 주었습니다.
    '//셀 주소는 Range 오브젝트 변수가 아니라 String 변수라는 사실에 주의하시기 바랍니다.

    Union(Range("범위1"), Range("범위2")).Select
    strAddress = Selection.Address
    '//Union Method를 사용해서 불연속적인 영역을 선택하고 그 주소를 strAddress 변수에
    '//담아둡니다.

    Msg = "선택된 영역의 주소: " & strAddress & vbCr
    Msg = Msg & "                    합계:   " & Format(Application.Sum(Selection), "#,###.00") & vbCr
    Msg = Msg & "                    평균:   " & Format(Application.Average(Selection), "#,###.00")
    MsgBox Msg, vbExclamation, "계산 완료//Exceller"
End Sub

마무리

다음 시간에… (기가 막히게 네 페이지를 정확히 맞추었지요? ^^)

정리 — 질문 답변 핵심

구분 사용한 코드 역할
불연속 범위 Union(Range("MyRange1"), Range("MyRange2")) 두 범위를 하나로 묶기
양수·음수 합산 If rngCell.Value >= 0 Then 조건별 누적
개체 변수 대입 Set rngCell = Range("MyRange") 개체에는 Set 사용
주소 저장 Dim a As String 셀 주소는 문자열
합계·평균 Application.Sum(Selection) 선택 영역 계산

자주 묻는 질문 (FAQ)

Q1. Union 메서드는 무엇인가요?

연속되지 않은 여러 범위를 하나의 Range 개체로 묶어 주는 메서드입니다.

Q2. Object 변수와 Range 변수는 어떤 차이가 있나요?

Object는 실행 시점에 개체를 확인하는 일반적인 방식이고, Range는 코드 작성 시점에 확인하는 구체적인 방식이라 더 빠르고 효율적입니다.

Q3. 런타임 오류 91은 왜 발생하나요?

셀 주소는 Range가 아니라 문자열인데 Range 변수에 대입하려 했기 때문에 개체변수가 설정되지 않았다는 오류가 납니다. String으로 선언하면 해결됩니다.

마치며

Union으로 불연속 범위를 묶고, 변수는 구체적인 형식으로 선언하면 코드가 더 빠르고 안전해집니다.