VBA 배열

Written by

Editorial Team

Reviewed by

Steve Rynearson

Translated by

Younjung Kim

Last updated on 4월 14, 2023

VBA에서 배열은 여러 값을 담을 수 있는 단일 변수입니다. 배열을 셀의 범위와 같이 생각할 수 있습니다. 각 셀에 값을 저장할 수 있듯이 배열의 각 항목에도 값을 저장할 수 있습니다. 배열은 1차원(단일 열로 생각), 2차원(여러 행과 열로 생각) 또는 다차원일 수 있습니다. 배열 값은 배열 내 위치(인덱스 번호)로 액세스할 수 있습니다.

VBA 배열 핵심 정리

배열

설명
VBA 코드
배열 변수 생성하기
Dim arr(1 To 3) As Variant
arr(1) = “one”
arr(2) = “two”
arr(3) = “three”
Excel의 셀에서 배열 값 채워넣기
Dim arr(1 To 3) As Variant
Dim cell As Range, i As Integer
i = LBound(arr)
For
Each cell In Range(“A1:A3”)
i = i + 1
arr(i) = cell.value
Next cell
모든 항목 읽기
Dim i as Long
For i = LBound(arr) To UBound(arr)
MsgBox arr(i)
Next i
Erase
Erase arr
배열을 문자열로 변환하기
Dim sName As String
sName = Join(arr, “:”)
배열 크기 키우기
ReDim Preserve arr(0 To 100)
배열 값 설정하기
arr(1) = 22

VBA 배열 예제 빠르게 살펴보기

세부 내용을 살펴보기 전에 전체 내용이 예제를 빠르게 한번 보겠습니다:

Sub ArrayExample()
    Dim strNames(1 to 4) as String

    strNames(1) = "Shelly"
    strNames(2) = "Steve"
    strNames(3) = "Neema"
    strNames(4) = "Jose"

    msgbox strNames(3)
End Sub

여기서는 크기가 4인(네 개의 값을 담을 수 있음) 1차원 문자열 배열인 strNames를 만들고 네 개의 값을 할당했습니다. 마지막으로 세 번째 값을 메시지 박스에 표시합니다.

배열을 사용함으로써 4개의 변수 선언 대신 1개의 변수선언을 했습니다. 배열을 사용하여 작은 이점을 얻었습니다.

 

배열의 진정한 힘을 보여줄 예제를 살펴보겠습니다:

Sub ArrayExample2()
    Dim strNames(1 To 60000) As String
    Dim i As Long

    For i = 1 To 60000
        strNames(i) = Cells(i, 1).Value
    Next i
End Sub

여기서는 60,000개의 값을 담을 수 있는 배열을 만들었으며 워크시트의 A 열의 값으로 배열의 값을 빠르게 채웠습니다.

배열의 장점 – 속도

배열은 Excel 워크시트와 비슷하다고 생각할 수 있습니다:

  • 각 셀(또는 배열의 항목)은 고유한 값을 포함할 수 있습니다.
  • 각 셀(또는 배열의 항목)은 행과 열 위치로 액세스할 수 있습니다.
    • 워크시트 예. cells(1,4).value = “1행, 4열”
    • 배열 예. arrVar(1,4) = “1행, 4열”

그렇다면 왜 배열을 사용할까요? 그냥 Excel에서 셀에 직접 값을 읽고 쓰면 되지 않을까요? 바로 속도 때문입니다!
So why bother with Arrays?  Why not just read and write values directly to cells in Excel?  One word: Speed!

Excel 셀에 읽기/쓰기는 상대적으로 느린 프로세스입니다. 배열로 작업하면 훨씬 빠릅니다!

배열 만들기/선언하기(Dim)

참고: 배열은 여러 개의 “차원”을 가질 수 있습니다. 간단하게 설명하기 위해 1차원 배열로만 작업하는 것으로 시작하겠습니다. 튜토리얼의 뒷부분에서 다차원 배열에 대해 소개하겠습니다.

일반배열

일반 배열은 크기를 변경할 수 없는 배열입니다. 반대로 동적 배열은 크기를 변경할 수 있습니다. 이 둘을 선언하는 방법은 조금 다릅니다. 먼저 일반 배열을 살펴보겠습니다.

참고: 배열의 크기가 변하지 않는다면 일반 배열을 사용하세요.

일반 배열 변수를 선언하는 것은 일반 변수를 선언하는 것과 매우 유사하지만 배열의 크기를 정의해야 한다는 점이 다릅니다. 배열의 크기를 설정하는 방법에는 여러 가지가 있습니다.

배열의 시작 위치와 끝 위치를 포함하여 선언할 수 있습니다:

Sub StaticArray1()

    '위치가 1,2,3,4인 배열을 생성합니다
    Dim arrDemo1(1 To 4) As String
    
    '위치가 4,5,6,7인 배열을 생성합니다
    Dim arrDemo2(4 To 7) As Long
    
    '위치가 0,1,2,3인 배열을 생성합니다
    Dim arrDemo3(0 To 3) As Long

End Sub

또는 배열의 크기만 입력하여 배열을 선언할 수도 있습니다:

Sub StaticArray2()

    '위치가 0,1,2,3인 배열을 생성합니다
    Dim arrDemo1(3) As String

End Sub

주목하세요! 기본적으로 배열은 위치 0에서 시작한다는 것을 알 수 있습니다. 따라서 Dim arrDemo1(3)은 위치가 0,1,2,3인 배열을 생성합니다.

모듈 상단에 Option Base 1을 선언하면 배열이 위치0 대신 위치 1에서 시작하도록 할 수도 있습니다:

Option Base 1

Sub StaticArray3()

    'Creates array with positions 1,2,3
    Dim arrDemo1(3) As String

End Sub

여러 방법 중에서도 배열의 시작과 끝 위치를 포함하여 배열을 선언하는 것이 가독성이 좋은 코드를 작성하는데 도움이 됩니다.

동적 배열

Dynamic Arrays 동적 배열은 크기를 변경할 수 있는(배열을 생성할 때 크기를 정의할 필요가 없는) 배열입니다.

동적 배열을 선언하는 방법에는 두 가지가 있습니다.

Variant 배열

동적 배열을 선언하는 첫 번째 방법은 배열을 Variant 타입으로 설정하는 것입니다.

Dim arrVar() As Variant

Variant 배열을 사용하면 배열 크기를 정의할 필요가 없습니다. 크기가 자동으로 조정됩니다. 배열은 위치 0에서 시작한다는 점만 기억하세요(모듈 상단에 옵션 베이스 1을 추가할 경우에는 위치 1부터 시작합니다).

Sub VariantArray()
    Dim arrVar() As Variant
    
    '배열의 크기가 0~3인 배열변수를 정의합니다
    arrVar = Array(1, 2, 3, 4)
    
    '배열의 크기를 0~4로 변경하고 값을 변경합니다
    arrVar = Array("1a", "2a", "3a", "4a", "5a")

    '배열의 4번 인덱스의 값을 표시합니다
    MsgBox arrVar(4)

End Sub

Variant 이외의 동적 배열

Variant 이외의 동적 배열을 사용하면 배열에 값을 할당하기 전에 배열 크기를 정의해야 합니다. 배열을 만드는 과정도 조금 다릅니다:

Sub DynamicArray1()
    Dim arrDemo1() As String

    '배열의 크기를 인덱스 1~4로 조정합니다
    ReDim arrDemo1(1 To 4)
    
End Sub

처음에 배열 크기를 생략하고 선언한다는 점을 제외하면 정적 배열과 비슷한 방법으로 배열을 선언합니다:

Dim arrDemo1() As String

이제 배열 크기를 설정하고 싶을 때 ReDim 명령을 사용하여 배열 크기를 조정합니다:

'배열의 크기를 인덱스 1~4로 조정합니다
ReDim arrDemo1(1 To 4)

ReDim은 배열의 크기를 조정합니다. 아래에서 ReDim과 ReDim Preserve의 차이점을 확인하세요.

ReDim vs. ReDim Preserve

ReDim 명령을 사용하면 배열의 기존 값을 모두 지웁니다. 반면에 ReDim Preserve를 사용하면 배열의 기존 값을 보존할 수 있습니다:

'배열의 크기를 인덱스 1~4로 조정합니다 (기존 값을 보존합니다)
ReDim Preserve arrDemo1(1 To 4)

배열 선언 간소화

위의 모든 내용을 읽은 후 배열 개념에 대한 거부감을 느끼셨을 수도 있을 것 같습니다. 이후 내용에 대해서는 간단하게 설명하기 위해 주로 일반 배열로 작업하겠습니다.

배열 값 설정하기

배열 값을 설정하는 것은 간단합니다.

정적 배열을 사용하면 각 위치별 배열 항목을 한 번에 하나씩 정의해야 합니다:

Sub ArrayExample()
    Dim strNames(1 to 4) as String

    strNames(1) = "Shelly"
    strNames(2) = "Steve"
    strNames(3) = "Neema"
    strNames(4) = "Jose"
End Sub

Variant 배열을 사용하면 한 줄에 전체 배열을 정의할 수 있습니다(주로 작은 배열에 유용합니다):

Sub ArrayExample_1Line()
    Dim strNames() As Variant

    strNames = Array("Shelly", "Steve", "Neema", "Jose")

End Sub

존재하지 않는 배열 위치에 대한 값을 정의하려고 하면 Subscript Out of Range 오류(아래 첨자 사용이 잘못되었습니다)가 발생합니다:

strNames(5) = "Shannon"

아래의 ‘범위를 배열값으로 할당하기’ 섹션에서는 루프를 사용하여 많은 수의 값을 배열에 빠르게 할당하는 방법을 보여드리겠습니다.

배열 값 가져오기

위에서 설명드린 내용과 비슷한 방법으로 배열 값을 가져올 수 있습니다. 아래 예제에서는 셀에 배열 값을 입력하겠습니다:

    Range("A1").Value = strNames(1)
    Range("A2").Value = strNames(2)
    Range("A3").Value = strNames(3)
    Range("A4").Value = strNames(4)

범위를 배열값으로 할당하기

범위를 배열값으로 할당하려면 반복문을 사용할 수 있습니다:

Sub RangeToArray()
    Dim strNames(1 To 60000) As String
    Dim i As Long

    For i = 1 To 60000
        strNames(i) = Cells(i, 1).Value
    Next i
End Sub

이렇게 하면 A1:A60000 범위를 반복하여 셀 값을 배열에 할당합니다.

배열값을 범위에 출력하기

반복문을 사용하여 배열을 범위 내의 셀 값으로 채울 수 있습니다:

    For i = 1 To 60000
        Cells(i, 1).Value = strNames(i)
    Next i

T’범위를 배열값으로 할당하기’ 예제와는 반대로 작동합니다: 배열 값을 A1:A60000 범위에 할당합니다.

2차원 / 다차원 배열

지금까지는 단일 차원(1차원) 배열로만 작업했습니다. 하지만 배열은 최대 32개의 차원을 가질 수 있습니다.

1차원 배열은 Excel 셀의 단일 행 또는 열, 2D 배열은 여러 행과 열이 있는 전체 Excel 워크시트, 3D 배열은 각각 여러 행과 열이 있는 여러 장이 포함된 전체 통합 문서와 같다고 생각하면 됩니다(3D 배열을 루빅스 큐브와 같다고 생각할 수도 있습니다).

다차원 배열 예제

이제 다양한 차원의 배열로 작업하는 예제를 보여드리겠습니다.

1차원 배열 예제

이 프로시저는 앞의 배열 예제들을 하나의 프로시저로 결합하여 실제로 배열을 사용하는 방법을 보여줍니다.

Sub ArrayEx_1d()
    Dim strNames(1 To 60000) As String
    Dim i As Long
 
    '값을 배열에 할당합니다
    For i = 1 To 60000
        strNames(i) = Cells(i, 1).Value
    Next i
    
    '배열값을 범위에 출력합니다
    For i = 1 To 60000
        Sheets("Output").Cells(i, 1).Value = strNames(i)
    Next i
End Sub

2차원 배열 예제

이 프로시저에는 2차원 배열의 예가 포함되어 있습니다:

Sub ArrayEx_2d()
    Dim strNames(1 To 60000, 1 To 10) As String
    Dim i As Long, j As Long
 
    '값을 배열에 할당합니다
    For i = 1 To 60000
        For j = 1 To 10
            strNames(i, j) = Cells(i, j).Value
        Next j
    Next i
    
    '배열값을 범위에 출력합니다
    For i = 1 To 60000
        For j = 1 To 10
            Sheets("Output").Cells(i, j).Value = strNames(i, j)
        Next j
    Next i
End Sub

3차원 배열 예제

이 프로시저에는 여러 시트로 작업하기 위한 3D 배열의 예가 포함되어 있습니다:

Sub ArrayEx_3d()
    Dim strNames(1 To 60000, 1 To 10, 1 To 3) As String
    Dim i As Long, j As Long, k As Long
 
    '값을 배열에 할당합니다
    For k = 1 To 3
        For i = 1 To 60000
            For j = 1 To 10
                strNames(i, j, k) = Sheets("Sheet" & k).Cells(i, j).Value
            Next j
        Next i
    Next k
    
    '배열 값을 범위에 출력합니다
    For k = 1 To 3
        For i = 1 To 60000
            For j = 1 To 10
                Sheets("Output" & k).Cells(i, j).Value = strNames(i, j, k)
            Next j
        Next i
    Next k
End Sub

배열 길이/크기

지금까지 다양한 유형의 배열을 소개드리면서 배열을 선언하고 배열 값을 가져오고 설정하는 방법을 배웠습니다. 지금부터는 배열로 작업할 때 필요한 다른 주제에 대해 알아보겠습니다.

UBound 와 LBound 함수

배열의 길이/크기를 구하는 첫 번째 단계는 UBound와 LBound 함수를 사용해 배열의 상한과 하한을 구하는 것입니다:

Sub UBoundLBound()
    Dim strNames(1 To 4) As String
    
    MsgBox UBound(strNames)
    MsgBox LBound(strNames)
End Sub

두 함수의 결과의 차이에 1을 더하면 배열의 길이를 구할 수 있습니다:

GetArrLength = UBound(strNames) - LBound(strNames) + 1

배열의 길이를 구하는 함수

다음은 단일 차원 배열의 길이를 구하는 함수입니다:

Public Function GetArrLength(a As Variant) As Long
   If IsEmpty(a) Then
      GetArrLength = 0
   Else
      GetArrLength = UBound(a) - LBound(a) + 1
   End If
End Function

2D 배열의 크기를 계산해야 하나요?  배열의 크기 계산하기 튜토리얼을 확인해 보세요.

배열 반복하기

배열을 반복하는 방법에는 두 가지가 있습니다. 첫 번째는 배열의 인덱스에 해당하는 정수를 반복하는 방법입니다. 배열 크기를 알고 있다면 직접 지정할 수 있습니다:

Sub ArrayExample_Loop1()
    Dim strNames(1 To 4) As String
    Dim i As Long

    strNames(1) = "Shelly"
    strNames(2) = "Steve"
    strNames(3) = "Neema"
    strNames(4) = "Jose"
    
    For i = 1 To 4
        MsgBox strNames(i)
    Next i
End Sub

배열 크기를 모르는 경우(배열이 동적 배열인 경우) 이전 섹션에서 설명드린 LBound 및 UBound 함수를 사용할 수 있습니다:

Sub ArrayExample_Loop2()
    Dim strNames(1 To 4) As String
    Dim i As Long

    strNames(1) = "Shelly"
    strNames(2) = "Steve"
    strNames(3) = "Neema"
    strNames(4) = "Jose"
    
    For i = LBound(strNames) To UBound(strNames)
        MsgBox strNames(i)
    Next i
End Sub

For Each 반복문 사용하기

두 번째 방법은 For Each 반복문을 사용하는 것입니다. 배열의 각 항목을 반복합니다:

Sub ArrayExample_Loop3()
    Dim strNames(1 To 4) As String
    Dim Item

    strNames(1) = "Shelly"
    strNames(2) = "Steve"
    strNames(3) = "Neema"
    strNames(4) = "Jose"
    
    For Each Item In strNames
        MsgBox Item
    Next Item
End Sub

For Each Array 반복문은 1차원 배열뿐만 아니라 다차원 배열에서도 작동합니다.

2차원 배열에대한 반복문

UBound 및 LBound 함수를 사용하여 다차원 배열을 반복할 수도 있습니다. 이 예제에서는 2차원 배열을 반복하겠습니다. UBound 및 LBound 함수를 사용하여 배열의 어느 차원에서 상한과 하한을 찾을지 지정할 수 있습니다(1차원의 경우 1, 2차원의 경우 2).

Sub ArrayExample_Loop4()
    Dim strNames(1 To 4, 1 To 2) As String
    Dim i As Long, j As Long

    strNames(1, 1) = "Shelly"
    strNames(2, 1) = "Steve"
    strNames(3, 1) = "Neema"
    strNames(4, 1) = "Jose"
    
    strNames(1, 2) = "Shelby"
    strNames(2, 2) = "Steven"
    strNames(3, 2) = "Nemo"
    strNames(4, 2) = "Jesse"
    
    For j = LBound(strNames, 2) To UBound(strNames, 2)
        For i = LBound(strNames, 1) To UBound(strNames, 1)
            MsgBox strNames(i, j)
        Next i
    Next j
End Sub

기타 배열에 대한 작업

배열 지우기

전체 배열을 지우려면 Erase 문을 사용합니다:

Erase strNames

다음은 사용 예제입니다:

Sub ArrayExample()
    Dim strNames(1 to 4) as String

    strNames(1) = "Shelly"
    strNames(2) = "Steve"
    strNames(3) = "Neema"
    strNames(4) = "Jose"

    Erase strNames
End Sub

또는 배열의 항목들을 지우고 배열의 크기를 다시 조정하기 위해 ReDim문을 사용할 수도 있습니다:

ReDim strNames(1 to 2)

이렇게 하면 배열의 크기가 2로 조정되어 인덱스 3과 4가 삭제됩니다.

배열 개수 계산하기

배열의 각 차원에 있는 인덱스의 개수를 계산하려면 위에서 설명한 UBound 및 LBound 함수를 사용할 수 있습니다.

배열을 반복하여 입력된 항목(또는 특정 기준을 충족하는 항목)의 수를 계산할 수도 있습니다.

이 예제는 객체 배열을 반복하고 배열에서 발견된 비어 있지 않은 항목의 수를 계산합니다:

Sub ArrayLoopandCount()
    Dim strNames(1 To 4) As String
    Dim i As Long, n As Long

    strNames(1) = "Shelly"
    strNames(2) = "Steve"
    
    For i = LBound(strNames) To UBound(strNames)
        If strNames(i) <> "" Then
            n = n + 1
        End If
    Next i
    
    MsgBox n & "개의 비어있지 않은 항목이 있습니다."
End Sub

중복 제거하기

배열에서 중복을 제거하고 싶을 수 있습니다. 안타깝게도 VBA에는 이 작업을 수행할 수 있는 내장 기능은 없습니다. 대신 저희가 배열에서 중복을 제거하는 함수를 만들었습니다(이 튜토리얼에 포함하기에는 너무 길기 때문에 링크를 방문하여 자세히 알아보십시오).

필터

VBA 필터 함수를 사용하면 배열을 필터링할 수 있습니다. 필터링된 값으로만 새 배열을 생성하는 방식으로 수행됩니다. 아래는 간단한 예제이지만, 다양한 요구 사항에 맞는 더 많은 예제를 보려면 링크를 방문하여 확인해 주세요.

Sub Filter_Match()
 
    '배열을 정의합니다
    Dim strNames As Variant
    strNames = Array("Steve Smith", "Shannon Smith", "Ryan Johnson")
 
    '배열을 필터링하여 새로운 배열을 생성합니다
    Dim strSubNames As Variant
    strSubNames = Filter(strNames, "Smith")
    
    '필터링된 배열의 개수를 계산합니다
    MsgBox "Found " & UBound(strSubNames) - LBound(strSubNames) + 1 & " names."
 
End Sub

IsArray 함수

변수가 배열인지 확인하려면 IsArray 함수를 사용해야합니다:

Sub IsArrayEx()

    '인덱스 상한이 3인 배열을 생성합니다
    Dim arrDemo1(3) As String
    
    '일반 문자열 변수를 생성합니다
    Dim str As String
    
    MsgBox IsArray(arrDemo1)
    MsgBox IsArray(str)

End Sub

배열 합치기

Join 함수를 사용하면 전체 배열을 하나의 문자열로 합칠 수 있습니다:

Sub Array_Join()
    Dim strNames(1 To 4) As String
    Dim joinNames As String

    strNames(1) = "Shelly"
    strNames(2) = "Steve"
    strNames(3) = "Neema"
    strNames(4) = "Jose"
    
    joinNames = Join(strNames, ", ")
    MsgBox joinNames
End Sub

문자열을 배열로 분할하기

VBA Split 함수는 텍스트 문자열을 원래 문자열의 값을 포함하는 배열로 분할합니다. 예제를 살펴보겠습니다:

Sub Array_Split()
    Dim Names() As String
    Dim joinedNames As String
    
    joinedNames = "Shelly,Steve,Nema,Jose"
    Names = Split(joinedNames, ",")

    MsgBox Names(1)
End Sub

여기서는 쉼표 구분 기호(,”)를 사용하여 “Shelly,Steve,Nema,Jose”라는 텍스트 문자열을 배열(크기 4)로 분할합니다.

배열을 상수로 사용하기

배열은 VBA에서 상수로 선언할 수 없습니다. 그러나 함수에서 배열을 생성하여 이 문제를 해결할 수 있습니다:

' ConstantArray를 정의합니다
Function ConstantArray()
    ConstantArray = Array(4, 12, 21, 100, 5)
End Function

' ConstantArray 의 값을 검색합니다
Sub RetrieveValues()
    MsgBox ConstantArray(3)
End Sub

배열 복사하기

VBA를 사용하여 배열을 복사하는 내장된 방법은 없습니다. 대신 반복문을 사용하여 한 배열의 값을 다른 배열에 할당해야 합니다.

Sub CopyArray()

    Dim Arr1(1 To 100) As Long
    Dim Arr2(1 To 100) As Long
    Dim i As Long
    
    '첫번째 배열을 생성합니다
    For i = 1 To 100
        Arr1(i) = i
    Next i
    
    '첫번째 배열의 값을 두번째 배열에 입력합니다
    For i = 1 To 100
        Arr2(i) = Arr1(i)
    Next i
    
    MsgBox Arr2(74)

End Sub

배열의 행/열 바꾸기

배열의 행/열을 바꿀 수 있는 내장된 VBA 함수는 없습니다. 대신 저희가 2차원 배열의 행/열을 바꾸는함수를 작성했습니다. 자세한 내용은 링크를 클릭하여 문서를 읽어보세요.

배열을 반환하는 함수 만들기

VBA 개발자들이 흔히 하는 질문은 배열을 반환하는 함수를 만드는 방법입니다. 대부분의 문제는 Variant 배열을 사용하면 해결됩니다. 이 주제에 대한 기사를 작성했습니다: VBA 함수로 배열 반환하기

Access VBA에서 배열 사용하기

위의 대부분의 배열 예제는 Excel VBA에서와 마찬가지로 Access VBA에서도 정확히 동일하게 작동합니다. 한 가지 큰 차이점은 Access 데이터를 사용하여 배열을 채우려는 경우 Range 개체가 아닌 RecordSet 개체를 반복해야 한다는 것입니다.

Sub RangeToArrayAccess()
   On Error Resume Next
   Dim strNames() As String
   Dim i As Long
   Dim iCount As Long
   Dim dbs As Database
   Dim rst As Recordset
   Set dbs = CurrentDb
   Set rst = dbs.OpenRecordset("tblClients", dbOpenDynaset)
   With rst
      .MoveLast
      .MoveFirst
      iCount = .RecordCount
      ReDim strNames(1 To iCount)
      For i = 1 To iCount
         strNames(i) = rst.Fields("ClientName")
         .MoveNext
      Next i
   End With
   rst.Close
   Set rst = Nothing
   Set dbs = Nothing
End Sub

 

Array Tutorials
Array Mega-Guideyes
Get Array Size
Clear Array
Filter Array
Transpose Array
Function Return Array
Remove Duplicates
vba-free-addin

VBA 코드 예시 추가 기능

본 웹사이트에 있는 모든 코드 예시에 쉽게 접근해보세요.

메뉴로 이동하여 클릭만 하면 코드는 모듈에 바로 입력됩니다. .xlam 추가 기능.

(설치가 필요 없습니다!)

무료 다운로드

VBA 코드 예시로 돌아가기