이 글은 VBA 에서 배열을 사용할 줄 아시는 분을 대상으로 합니다.

Collection.pptm

첨부한 슬라이드로 설명을 드립니다.


배열 중간에 뭔가 삽입해야할 때가 있습니다.



예를 들어 이렇게 3번 다음에 10번을 넣고 싶다면 어떨까요?

Option Base 1
dim i as Integer
dim myArray
dim copyArray()
myArray = Array("1번선수","2번선수","3번선수", ...생략...)

Redim Preserve myArray(Ubound(MyArray)+1)   ' 배열크기를 1 증가시키고
for  i = Ubound(myArray) to 5 step -1             ' 끝에서부터 삽입위치까지 바로 이전 배열값을 차례로 복사
myArray(i) = myArray(i-1)
next
myArray(4) = "10번선수"                            '중간에 들어갈 위치에 추가될 값 삽입

대충 이런식으로 귀찮은 과정을 거쳐야 합니다.
만약 중간에 하나를 삭제하고 싶다면 또 함수를 만들어야 합니다.

배열은 이렇게 삽입 삭제가 자유롭지 않은 고정된 변수입니다.
이것을 극복하기 위한 방법 중 하나가 VBA Collection 입니다. 
그밖에 Dictionary 도 있고 그러더군요. 여기서는 Collection에 대해 소개 드립니다.



생성 방법과 데이타 추가 방법입니다.
생성할 때 Set ~ 은 생략하고 그냥 한줄로 Dim myCol as New collection 으로 해도 되지만 
초기화가 안되니 슬라이드처럼 Set까지 두 줄로 사용하는 게 좋겠습니다.
myCol.Add "삽입데이터", 키, Before, After 가 기본 형식입니다.
myCol.Add 는 계속 끝에 새로운 데이터를 추가합니다.
배열처럼 Redim 을 해서 사이즈를 바꾸지 않아도 되죠.

중간에 어떤 값을 삽입하려면 myCol.Add "10번선수", After:=3 혹은 myCol.Add "10번선수", Before:=4 이렇게 하면 됩니다.
중간에 데이터삽입이 이렇게 자유롭습니다.

Collection 이 좋은 게 또하나 각 배열에 Key 를 지정할 수 있습니다.
myCol.Add "홍길동", "1번"
myCol.Add "강감찬", "2번"
이렇게 해놓고 myCol("2번") 하면 "강감찬" 이 리턴됩니다.


중간에 데이터 삭제는 훨씬 간단합니다.
그냥 myCol.Remove (4) 하면 4번 위치의 값이 삭제되고 '배열'이 한칸 앞으로 당겨집니다. 
Collection 의 출발 인덱스는 0이 아니라 1 입니다. "3번선수"은 3번 인덱스입니다.


배열은 Ubound 로 끝 인덱스를 가져오는데 Collection은 .Count 로 알려줍니다.

Collection 의 각 값은 배열처럼 myCol.Item(1) myCol.Item(2) 등으로 나타낼 수 있습니다.
물론 Key 로 가져올 수도 있습니다. 
사실 PHP 같은데서 Key 로 배열값을 가져와서 많이 쓰는데 VBA에서는 자주 안보이더군요.

"Key:= " 라든가 "After:=" 이런 부분을 붙이는 이유는 
[원래 myCol.Add "데이터", 키값, After위치, Before위치] 이게 기본 형식으로 지켜야 하는데 
모두다 쓰기 귀찮고, 순서가 바뀌어 섞일 수도 있어서 이렇게 쓰는 겁니다.



이제 실제로 배열에 데이터가 삽입 삭제되는지 눈으로 확인해봅시다.
원래 이렇게 배열이 되어 있을 건데 빨간 버튼을 누르면



이렇게 10번 선수가 3번 다음에 삽입됩니다.
다시 파란색 버튼을 누르면 간단히 10번선수가 사라지고 원래 배열이 됩니다.

빨간 버튼 2번 누른 뒤에 파란 버튼 2번 눌러도 결과는 같습니다.



Collection 의 주의할 점이나 단점도 있겠지요.
먼저 그냥 myCol.Add 하면 항상 끝에 데이터가 삽입되기 때문에 새로 시작하고 싶으면
Collection 전체를 삭제해주는 게 좋습니다.

myCol.Clear 가 된다고 하는데 2010에서 잘 안되더군요.
제가 확인해보니 간단히 Set myCol = Nothing 이렇게 해도 삭제가 되고
또는 일일이 데이터를 지울 수도 있습니다.

Do Until myCol.Count = 0
    myCol.Remove 1
Loop


또 한가지 Collection 안에 어떤 값이 들어있는지를 알려주는 함수는 없으므로 배열처럼 함수를 만들어 써야 합니다.
Function Contain(thisCol As Collection, checkVal As Variant) As Boolean
    On Error Resume Next
    Contain = False
    Dim it As Variant
    For Each it In thisCol
        If it = checkVal Then
            Contain = True
            Exit Function
        End If
    Next
End Function

예를 들면 myCol Collection에 "10번선수"라는 데이터가 있는지 확인하려면
 if Contain(myCol, "10번선수") then MsgBox "10번선수가 존재합니다."
이런식으로 해주면 됩니다.


지금까지 Collection 에 대해 소개드렸습니다.
C 언어에서 Linked List 와 조금 비슷한데 좀 더 편한 것 같습니다.

참, Collection 은 배열과 함께 사용할 수 있습니다.
Dim myCol() As New Collection
Redim myCol(10) 이런식으로 하면 
1부터 10까지 고정된 배열인데 각 배열에 속한 내부구성요소는 자유롭게 삭제, 삽입이 가능한 2차원 배열처럼 이용할 수 있습니다. (실제로 제가 수도쿠 게임을 만들 때 각 칸에 가능한 숫자들은 계속 변하기 때문에 배열보다는 자유롭게 삽입, 삭제가 가능한 Collection을 배열로 사용해서 아주 유용했던 적이 있습니다.)

그리고 Collection 은 배열로 변환이 가능합니다.
Collection 의 구성요소들은 Key값이 있을 때 Sorting 에는 비효율적이라고 합니다.
MergeSort 를 참고하세요.( https://github.com/austinleedavis/VBA-utilities )

Collection 소개를 마칩니다.
첨부한 슬라이드를 실행해보시기 바랍니다.

(이 글은 http://analystcave.com/vba-collection/ 의 많은 부분을 참조했습니다.)

이 글은 http://cafe.naver.com/gameppt/123116 에도 게재되었습니다.