본문 바로가기

코딩/엑셀,VBA

[엑셀/VBA] 정적 배열, 동적 배열(ReDim, ReDim Preserve)

반응형

 

 

  이번 포스팅은 엑셀 VBA의 정적 배열과 동적 배열에 관한 내용이다. 2 종류의 배열에 대해 요약하자면 정적배열은 크기가 정해진 배열을 말한다. 초기에 배열을 선언할 때, 배열의 총 사이즈를 정한다. 동적배열은 크기가 정해지지 않은 배열이다. 코드를 동작시키며 이름그대로 동적으로 배열의 크기를 변화시킬 수 있다.

 

  아래는 예시를 통해 정적배열과 동적배열의 사용법에 대해 정리해보고자 했다.

 

 

1. 정적 배열

 

 

1) 1차원 배열 

 

  서론에서 설명했지만 정적배열은 크기가 정해진 배열이다. 1차원 배열의 변수선언은 아래와 같이 할 수 있다.

 

#배열 선언법1

Dim 변수명(시작 Index To 끝 Index) as 변수Type


  아래 예시 코드 디버깅을 통해 1차원 배열 변수선언을 확인해보도록 하겠다.

  

<코드>

Sub 정적배열()
    
    Dim a(0 To 10) As Integer
       
End Sub

 

<결과>

a(0 To 10) Array

 

  a(0 To 10)의 의미는 배열 a의 index가 10까지라는 의미이다. 혼동할 수 있는데 10이라는 의미는 배열의 크기가 10칸이라는 말이 아니다. 0부터 index가 시작하므로 0~11 총 11개의 data를 담을 수 있는 1차원 배열인 것이다. 

 

  위 코드의 표현법은 아래의 표현방식으로 대체할 수 있다.

 

#배열 선언법2

Dim 변수명(배열 Size) as 변수형

 

 

<코드>

Dim a(10) As Integer

 

 

  만약 Index의 시작지점을 바꾸고 싶다면 아래와 같이 시작점이 0이 아닌 숫자로 변경해보자. 아래 코드처럼 2 To 10으로 바꾸면 Index의 시작값은 2가되고 끝 Index가 10인 배열이 생성된다. 

 

 

<코드>

Dim a(2 To 10) As Integer

 

 

<결과>

a(2 To 10) Array

 

 

 

 

2) 2차원 배열

 

 

  2차원 배열 선언은 차원이 하나 늘어난 것뿐 1차원 배열과 선언 방법은 크게 다르지 않다. 아래 예시를 통해 정리해보았다.

 

 

<코드>

Sub 정적배열()

    Dim a(0 To 3, 0 To 3) As Integer 
    
End Sub

 

<결과>

a(0 To 3, 0 To 3) 2차원 Array

 

 

  결과를 보면 알겠지만 첫번째 차원의 인덱스가 0~3, 두번째 차원의 인덱스가 0~3이므로 4*4 = 총 16개 사이즈를 가진 배열이 생성되었다. 1차원 배열과 마찬가지로 위 코드는 아래 a(3, 3)으로 선언하는 것으로 대체할 수 있다. 배열의 시작 index를 변경하는 방법은

1차원 배열과 다르지 않으니 내용 생략.

 

 

<코드>

Dim a(3, 3) As Integer

 

  

 

2. 동적배열 예시

 

 

  동적배열은 크기가 정해지지 않은 배열이다. 따라서 배열 선언시 괄호 안의 ( ) 내용을 비워서 선언한다. 대신 필요에 따라 배열의 차원과 크기를 정해줄 때 Redim 이라는 코드를 쓴다.

 

#동적 배열 선언법

Dim 변수명( ) as 변수Type

Redim 변수명(차원 및 Size 지정)

 

  위 표현법으로는 이해하기 어려울 수 있으니 아래 코드를 통해 이해해보자.

 

 

<코드>

Sub 동적배열()

    Dim a() As Integer #정수형인 동적배열 선언
    
    #a는 1차원 배열로 정의
    ReDim a(0 To 5) #ReDim a(5)와 동일
       
    
End Sub

 

<결과>

동적배열을 1차원 배열(크기 5)로 지정

 

 

  동적 배열 사용법은 변수 선언시 차원과 사이즈를 지정하지 않고 선언했다가 필요에 따라 ReDim을 통해 재정의하는 것이다. 따라서, 차원과 SIze는 프로그램 진행 상황에 따라 바뀔 수도 있다. 위 코드에서 2차원으로 변경하는 코드를 한줄 추가해보도록 하겠다.

 

 

<코드>

Sub 동적배열()

    Dim a() As Integer #정수형인 동적배열 선언
    
    #a는 1차원 배열로 정의
    ReDim a(0 To 5) #ReDim a(5)와 동일
    
    #a를 다시 2차원 배열로 정의
    ReDim a(2,2)
       
    
End Sub

 

<결과>

2차원 배열로 재정의 후 a Array 결과

 

 

 

  참고로, Redim 코드에는 Redim Preserve라는 옵션이 있다. Preserve를 붙이면 기존의 배열 내부 데이터는 유지하면서 마지막 차원의 크기만 변경할 수 있다. 이 것도 예시를 통해 이해해보자.

 

 

<코드>

Sub 동적배열()

    Dim a() As Integer #정수형인 동적배열 선언
    
    #2차원 배열(1*1)로 정의
    ReDim a(1, 1)
    
    #2차원 배열에 데이터 입력
    a(0, 0) = 1
    a(0, 1) = 2
    a(1, 0) = 3
    a(1, 1) = 4
    
    #2차원 배열(1*4)로 재정의
    ReDim a(1, 4)
    
     
End Sub

 

<결과>

ReDim a(1,4) 이 후 내부 데이터가 초기화 됨

 

 

  코드에 따르면 중간 2차원 배열에 데이터를 입력하면서 a(0,0), a(0,1), a(1,0), a(1,1)에는 숫자 데이터(1,2,3,4)가 입력되어 있어야 한다. 하지만, 마지막 결과를 보면 ReDim a(1,4)를 통해 차원과 사이즈가 재정의 되면서 내부 데이터가 0으로 초기화되었다.

 

  만약 내부데이터를 살리면서 마지막 차원만 변경하고 싶다면 ReDim Preseve 코드를 사용하면 된다.

(마지막차원 : 2차원 배열인 1*4 기준으로 설명해보면 첫번째 차원은 1, 마지막 차원이 4인 배열이다.)

 

 

<코드>

Sub 동적배열()

    Dim a() As Integer #정수형인 동적배열 선언
    
    #2차원 배열(1*1)로 정의
    ReDim a(1, 1)
    
    #2차원 배열에 데이터 입력
    a(0, 0) = 1
    a(0, 1) = 2
    a(1, 0) = 3
    a(1, 1) = 4
    
    #기존 데이터를 보존하면서 마지막 차원의 값을 1->4로 변경
    ReDim Preserve a(1, 4)
    
     
End Sub

 

<결과>

기존 데이터를 보존하면서 마지막 차원 1->4로 변경

 

  결과를 보면 알겠지만 a의 배열 차원 및 사이즈를 재정의하는 코드를 Redim Preserve를 사용해 기존에 입력 된 데이터가 보존되는 것을 확인할 수 있다.

 

 

 

3. 동적배열 활용을 통한 시트목록 저장하기

 

 

  그래서 동적 배열을 어디에 활용할 수 있을까? 라고 생각이 들어서 예시 프로그램을 작성해보았다. 아래 코드는 해당 엑셀 파일의 시트 수가 어떻든 동적배열 개념을 통해 배열에 모든 시트명을 저장한다.

 

 

<엑셀 파일 시트>

Sheet1~6

 

 

<코드>

Option Explicit #명시적 선언

Sub shtName_List()

    Dim i As Integer
    Dim Sheetcount As Integer
    Dim shtlist() As Variant #Variant 타입의 동적배열 shtlist 선언
    
    Sheetcount = ActiveWorkbook.Sheets.Count #해당 엑셀파일 시트수 세기
    
    ReDim shtlist(Sheetcount - 2) #동적 배열 크기 지정
    
    For i = 2 To Sheetcount #i=2부터인 이유는 Sheet1을 제외하기 위해서
      shtlist(i - 2) = Sheets(i).Name
    Next i
    
End Sub

 

<결과>

 

 

  결과 이미지를 보면 알겠지만 시트수에 따라 동적 배열이 Redim 코드를 통해 정의한다. 그리고 각 시트명을 배열에 저장했다.

 


참고링크1 : Redim, Redim preserve 차이 https://kdsoft-zeros.tistory.com/149

참고링크2 : 동적배열, 정적배열 https://simon-k.tistory.com/17

728x90