클래스모듈 - 이 부문은 그대로 복사해서 사용해도 잘 작동한다(msdn에서 가져온 것임)
Public Value As Variant
Public NextItem As ListItem
Dim liHead As ListItem
Function Search(ByVal varItem As Variant, _
ByRef liCurrent As ListItem, ByRef liPrevious As ListItem) _
As Boolean
Dim fFound As Boolean
fFound = False
Set liPrevious = Nothing
Set liCurrent = liHead
Do While Not liCurrent Is Nothing
With liCurrent
If varItem > .Value Then
Set liPrevious = liCurrent
Set liCurrent = .NextItem
Else
Exit Do
End If
End With
Loop
' You can't compare the value in liCurrent to the sought
' value unless liCurrent points to something.
If Not liCurrent Is Nothing Then
fFound = (liCurrent.Value = varItem)
End If
Search = fFound
End Function
Public Sub Add(varValue As Variant)
Dim liNew As New ListItem
Dim liCurrent As ListItem
Dim liPrevious As ListItem
liNew.Value = varValue
' Find where to put the new item. This function call
' fills in liCurrent and liPrevious.
Call Search(varValue, liCurrent, liPrevious)
If Not liPrevious Is Nothing Then
Set liNew.NextItem = liPrevious.NextItem
Set liPrevious.NextItem = liNew
Else
' Inserting at the head of the list:
' Set the new item to point to what liHead currently
' points to (which might just be Nothing). Then
' make liHead point to the new item.
Set liNew.NextItem = liHead
Set liHead = liNew
End If
End Sub
Public Function Delete(varItem As Variant) As Boolean
Dim liCurrent As ListItem
Dim liPrevious As ListItem
Dim fFound As Boolean
' Find the item. This function call
' fills in liCurrent and liPrevious.
fFound = Search(varItem, liCurrent, liPrevious)
If fFound Then
If Not liPrevious Is Nothing Then
' Deleting from the middle or end of the list.
Set liPrevious.NextItem = liCurrent.NextItem
Else
' Deleting from the head of the list.
Set liHead = liCurrent.NextItem
End If
End If
Delete = fFound
End Function
Public Sub DebugList()
' Print the list to the Immediate window.
Dim liCurrent As ListItem
Set liCurrent = liHead
Do While Not liCurrent Is Nothing
Debug.Print liCurrent.Value
Set liCurrent = liCurrent.NextItem
Loop
End Sub
Source : http://msdn.microsoft.com/en-us/library/aa227565(VS.60).aspxPublic NextItem As ListItem
Dim liHead As ListItem
Function Search(ByVal varItem As Variant, _
ByRef liCurrent As ListItem, ByRef liPrevious As ListItem) _
As Boolean
Dim fFound As Boolean
fFound = False
Set liPrevious = Nothing
Set liCurrent = liHead
Do While Not liCurrent Is Nothing
With liCurrent
If varItem > .Value Then
Set liPrevious = liCurrent
Set liCurrent = .NextItem
Else
Exit Do
End If
End With
Loop
' You can't compare the value in liCurrent to the sought
' value unless liCurrent points to something.
If Not liCurrent Is Nothing Then
fFound = (liCurrent.Value = varItem)
End If
Search = fFound
End Function
Public Sub Add(varValue As Variant)
Dim liNew As New ListItem
Dim liCurrent As ListItem
Dim liPrevious As ListItem
liNew.Value = varValue
' Find where to put the new item. This function call
' fills in liCurrent and liPrevious.
Call Search(varValue, liCurrent, liPrevious)
If Not liPrevious Is Nothing Then
Set liNew.NextItem = liPrevious.NextItem
Set liPrevious.NextItem = liNew
Else
' Inserting at the head of the list:
' Set the new item to point to what liHead currently
' points to (which might just be Nothing). Then
' make liHead point to the new item.
Set liNew.NextItem = liHead
Set liHead = liNew
End If
End Sub
Public Function Delete(varItem As Variant) As Boolean
Dim liCurrent As ListItem
Dim liPrevious As ListItem
Dim fFound As Boolean
' Find the item. This function call
' fills in liCurrent and liPrevious.
fFound = Search(varItem, liCurrent, liPrevious)
If fFound Then
If Not liPrevious Is Nothing Then
' Deleting from the middle or end of the list.
Set liPrevious.NextItem = liCurrent.NextItem
Else
' Deleting from the head of the list.
Set liHead = liCurrent.NextItem
End If
End If
Delete = fFound
End Function
Public Sub DebugList()
' Print the list to the Immediate window.
Dim liCurrent As ListItem
Set liCurrent = liHead
Do While Not liCurrent Is Nothing
Debug.Print liCurrent.Value
Set liCurrent = liCurrent.NextItem
Loop
End Sub
위에서 작성된 클래스를 일반 모듈에서 사용하려면 다음과 같이 한다.
일반모듈
Sub TestList()
Dim liTest As New ListItem '여기서 ListItem은 클래스모듈 이름이다
For i = 2 To 1000 '2부터 1000까지 리스트에 추가한다.
liTest.Add i
Next
Call liTest.DebugList 'ListItem 클래스의 DebugList 메서드를 호출한다. 즉 리스트를 화면인쇄한다.
Debug.Print "=== 끝 ^_^ ==="
End Sub
Dim liTest As New ListItem '여기서 ListItem은 클래스모듈 이름이다
For i = 2 To 1000 '2부터 1000까지 리스트에 추가한다.
liTest.Add i
Next
Call liTest.DebugList 'ListItem 클래스의 DebugList 메서드를 호출한다. 즉 리스트를 화면인쇄한다.
Debug.Print "=== 끝 ^_^ ==="
End Sub
배열의 크기가 long 이상의 크기(2,147,483,647)를 초과하면 오버플로가 발생하여 에러가 나듯이, 이 VBA 리스트도 상당히 큰 갯수를 추가하면 스택 오버플로가 발생하여 에러가 나는 것 같다. (정확히 어는 숫자를 초과해야 하는지는 테스트 해보지 않아서 확실하지 않다) 또한 정확한 테스트는 해보지 않았지만, 실행하면서 느끼는 체감으로는 아이템 갯수가 늘어나면 배열보다 더 느려지고 처리시간이 많이 걸리는 것 같다.
어떻게 하면 VBA에서 매우 큰 갯수(예를들면 6천억개)의 데이터 아이템을 넣을 수 있는 자료구조를 만들어 사용할 수 있을까?
댓글 없음:
댓글 쓰기