SortedList là một thư viện nằm trong “Syst" />
RaoVat24h
Excel Office

Bài 17. SortedList

Advertisement

SortedList là một thư viện nằm trong “System.Collections” của .NET Framework.
SortedList lưu trữ các Items theo Keys tương ứng thành cặp, được sắp xếp theo các Keys, cho phép truy cập tới Item theo Key hoặc chỉ mục (index) ứng với Item đó.
Yêu cầu: Hệ thống phải cài đặt .NET Framework v1.1 trở lên.

1. Khai báo SortedList

1.1. Kiểu khai báo sớm
(Không có Tooltip khi gọi SortedList, phải thiết lập trong Tools/References)
– Trong cửa sổ VBA, Tools menu, References.
– Tìm và check vào mục “mscorlib.dll” trong cửa sổ References – VBAProject.
Khai báo trong code:

Dim oSList  As New SortedList


1.2. Kiểu khai báo muộn
(Không có Tooltip khi gọi SortedList, không cần thiết lập trong Tools/References).
Khai báo trong code:

Dim oSList As Object
Set oSList = CreateObject("System.Collections.SortedList")


2. Các thuộc tính

2.1. Count

oSList.Count


Trả về số lượng phần tử (Items) thực sự tồn tại trong SortedList.
Ví dụ:

Sub CountProperty()
    'oSList.Count'
    Dim oSList As Object, i As Long
    Set oSList = CreateObject("System.Collections.SortedList")
    For i = 1 To 5
        oSList.Add "Key-" & i, i
    Next i
    oSList.Add "Key-", Array(2, 5)
    MsgBox oSList.Count    '6'
End Sub


2.2. Capacity

oSList.Capacity


Trả về số lượng các phần tử hoặc đặt (thiết lập) số lượng các phần tử mà SortedList có thể lưu trữ.
+ Các lỗi xảy ra đặt số lượng các phần tử cho SortedList:
– Khi giá trị của Capacity nhỏ hơn số lượng phần từ đã tồn tại trong SortedList (count).
– Khi giá trị của Capacity trả về SortedList có kích thước vượt dung lượng bộ nhớ có thể dùng của hệ thống (OutOfMemoryException).
+ Capacity luôn luôn lớn hơn hoặc bằng Count. Nếu Count vượt quá Capacity trong khi thêm các phần tử, Capacity  sẽ tự động tăng lên bằng cách tái phân bổ lại mảng nội bộ trước khi sao chép các phần tử cũ và thêm các phần tử mới.
+ Có thể giảm Capacity bằng cách dùng phương thức TrimToSize hoặc bằng cách thiết lập giá trị Capacity cụ thể (nhưng phải đảm bảo >=  Count, nếu không sẽ xảy ra lỗi). Khi giá trị của Capacity được xác định cụ thể, mảng nội bộ cũng được phân bổ lại để đáp ứng dung lượng đã xác định.
Ví dụ:

Sub CapacityProperty()
    'oSList.Capacity'
    Dim oSList As Object, vCnt As Long, vCty As Long, i As Long
    Set oSList = CreateObject("System.Collections.SortedList")
    For i = 1 To 5
        oSList.Add "Key-" & i, i
    Next i
    vCnt = oSList.Count       '5'
    vCty = oSList.capacity    '16'
    oSList.capacity = 5
    MsgBox oSList.capacity    '5'
End Sub


2.3. Item

oSList.Item(Key)
'Hoặc:'
   oSList(Key)


Trả về giá trị của Item theo Key chỉ định trong SortedList, hoặc gán giá trị mới cho Item theo Key của Item đó.
– Nếu gán một giá trị cho một Item theo một Key chưa tồn tại trong SortedList thì SortedList tự động thêm Key đó, và Item đó có giá trị vừa đưa vào.
Ví dụ:

Sub ItemProperty()
    'oSList.Item(Key) '
    'oSList(Key) '
    Dim oSList As Object, i As Long
    Set oSList = CreateObject("System.Collections.SortedList")
    For i = 1 To 5
        oSList.Add "Key-" & i, ""
    Next i
    oSList.Item("Key-1") = 100
    MsgBox oSList("Key-1") '100'
    oSList("KeyA") = 20
    MsgBox oSList.Count     '6'
End Sub


3. Các phương thức


3.1. Add

oSList.Add Key, Item


Thêm một Item vào SortedList theo Key chỉ định.
Key: Phải duy nhất trong SortedList và khác null. Key nhận kiểu dữ liệu hoặc là số hoặc là chuỗi.
Item: Nhận kiểu dữ liệu bất kỳ (kiểu số hoặc chuỗi, null), giá trị của Items có thể trùng nhau,có thể là một trị đơn, hoặc một mảng (array).
Chỉ số đầu tiên của Key/ Item trong SortedList bằng 0.
Khi một Item được thêm vào, nó được chèn vào SortedList theo thứ tự sắp xếp chính xác theo Keys, và chỉ mục (Index) của nó được thiết lập tương ứng phù hợp theo Key.

Ví dụ:

Sub AddMethod()
    'oSList.Add Key, Item '
        'Key: OR number OR string, <>null'
        'Item: number, string, array'
        'First index = 0    '
    Dim oSList As Object
    Set oSList = CreateObject("System.Collections.SortedList")
    oSList.Add "5", 20
    oSList.Add "KeyA", "Item2"
    oSList.Add "KeyB", ""
    oSList.Add "KeyC", Array(12, 40)
End Sub


3.2. Clear

oSortedList.Clear


Xóa toàn bộ các Items trong SortedList.
Ví dụ:

Sub ClearMethod()
    'oSList.Clear'
    Dim oSList As Object, i As Long
    Set oSList = CreateObject("System.Collections.SortedList")
    For i = 1 To 5
        oSList.Add i, ""
    Next i
    oSList.Clear
    MsgBox oSList.Count    '0'
End Sub


3.3. Clone

oSortedList.Clone


Tạo một bản sao từ SortedList đã có.
Ví dụ:

Sub CloneMethod()
    'oSList.Clone'
    Dim oSList As Object, i As Long, newSList As Object
    Set oSList = CreateObject("System.Collections.SortedList")
    For i = 1 To 5
        oSList.Add i, ""
    Next i
    Set newSList = oSList.Clone
    MsgBox newSList.Count   '5'
End Sub


3.4. Contains / ContainsKey

 oSList.Contains(Key)
 oSList.ContainsKey(Key)


Kiểm tra sự tồn tại của một Key trong SortedList. Trả về True nếu Key đã tồn tại trong SortedList, ngược lại trả về False.
Lưu ý: Key chỉ định kiểm tra phải cùng kiểu dữ liệu (số hoặc chuỗi) với kiểu dữ liệu của Key đã có trong SortedList, nếu không xảy ra lỗi.
Ví dụ:

Sub ContainsMethod()
    'oSList.Contains(Key)'
    Dim oSList As Object, i As Long, sKey As String
    Set oSList = CreateObject("System.Collections.SortedList")
    For i = 1 To 5
        oSList.Add "Key-" & i, i
    Next i
    sKey = "Key-2"
    MsgBox oSList.Contains(sKey)   'True'
End Sub


Sub ContainsKeyMethod()
    'oSList.ContainsKey(Key)'
    Dim oSList As Object, i As Long, sKey As String
    Set oSList = CreateObject("System.Collections.SortedList")
    For i = 1 To 5
        oSList.Add "Key-" & i, i
    Next i
    sKey = "Key-5"
    MsgBox oSList.ContainsKey(sKey)   'True'
End Sub


3.5. ContainsValue

oSList.ContainsKey(Key)


Kiểm tra sự tồn tại giá trị của một Item trong SortedList. Trả về True nếu giá trị đó đã tồn tại trong SortedList, ngược lại trả về False.
Ví dụ:

Sub ContainsValueMethod()
    'oSList.ContainsKey(Key)'
    Dim oSList As Object
    Set oSList = CreateObject("System.Collections.SortedList")
    oSList.Add "KeyA", 2
    oSList.Add "KeyB", ""
    oSList.Add "KeyC", "Item3"
    MsgBox oSList.ContainsValue(2)    'True'
    MsgBox oSList.ContainsValue("")   'True'
    MsgBox oSList.ContainsValue("Item4")   'False'
End Sub


3.6. GetByIndex

oSList.GetByIndex(Index)


Trả về giá trị của một Item trong SortedList theo chỉ mục (Index) chỉ định.
Ví dụ:

Sub GetByIndexMethod()
    'oSList.GetByIndex(Index) //Index = 0 : Count-1 / Return: Item'
    Dim oSList As Object, i As Long, sKey
    Set oSList = CreateObject("System.Collections.SortedList")
    For i = 1 To 5
        oSList.Add "Key-" & i, "Value-" & i
    Next i
    sKey = oSList.GetByIndex(0)
    MsgBox sKey     '"Value-1"'
End Sub


3.7. GetKey

oSList.GetKey(Index)


Trả về một Key có trong SortedList theo chỉ mục (Index) chỉ định.
Index: Có giá trị từ 0 tới Count-1.
Ví dụ:

Sub GetKeyMethod()
    'oSList.GetKey(Index) //Index = 0 : Count-1 '
    Dim oSList As Object, i As Long, sKey
    Set oSList = CreateObject("System.Collections.SortedList")
    For i = 1 To 5
        oSList.Add "Key-" & i, i
    Next i
    sKey = oSList.GetKey(0)
    MsgBox sKey     '"Key-1"'
End Sub


3.8. GetKeyList

oSList.GetKeyList


Trả về một đối tượng IList (System.Collections.IList) chứa toàn bộ Keys có trong SortedList.
Ví dụ:

Sub GetKeyListMethod()
    'oSList.GetKeyList '
    'Return an IList object (System.Collections.IList) containing the keys in the SortedList object.'
    Dim oSList As Object, i As Long, KeyList As Object
    Set oSList = CreateObject("System.Collections.SortedList")
    For i = 1 To 5
        oSList.Add "Key-" & i, i
    Next i
    Set KeyList = oSList.GetKeyList
    MsgBox KeyList.Item(0)     '"Key-1"'
End Sub


3.9. GetValueList

oSList.GetValueList


Trả về một đối tượng IList (System.Collections.IList) chứa toàn bộ Items có trong SortedList.
Ví dụ:

Sub GetValueListMethod()
    'oSList.GetValueList '
    'Return an IList object (System.Collections.IList) containing the values in the SortedList object.'
    Dim oSList As Object, i As Long, ValueList As Object
    Set oSList = CreateObject("System.Collections.SortedList")
    For i = 1 To 5
        oSList.Add "Key-" & i, i
    Next i
    Set ValueList = oSList.GetValueList
    MsgBox ValueList.Item(4)     '5'
End Sub


3.10. IndexOfKey

oSList.IndexOfKey(Key)


Trả về vị trí của Key chỉ định trong SortedList (FirstIndex = 0).
Nếu Key chỉ định không có trong SortedList thì kết quả trả về -1.

Các phần tử trong SortedList được sắp xếp chính xác theo Keys. Khi một phần tử được thêm, nó được chèn vào SortedList theo thứ tự sắp xếp chính xác, và lập chỉ mục (Index) điều chỉnh cho phù hợp. Khi một phần tử được loại bỏ, việc lập chỉ mục cũng điều chỉnh cho phù hợp. Do đó, chỉ mục của cặp Key/ Item cụ thể có thể thay đổi khi các phần tử được thêm vào hoặc xoá khỏi SortedList.
Ví dụ:

Sub IndexOfKeyMethod()
    'oSList.IndexOfKey(Key)
    Dim oSList As Object, idex As Long
    Set oSList = CreateObject("System.Collections.SortedList")
    oSList.Add "1", ""
    oSList.Add "Z", ""
    oSList.Add "A", ""
    idex = oSList.IndexOfKey("1")   'idex=0'
    MsgBox idex
    idex = oSList.IndexOfKey("Z")   'idex=2'
    MsgBox idex
    idex = oSList.IndexOfKey("A")   'idex=1'
    MsgBox idex
End Sub


3.11. IndexOfValue

oSList.IndexOfValue(Item)


Trả về vị trí của Item chỉ định trong SortedList (FirstIndex = 0).
Nếu Item chỉ định không có trong SortedList thì kết quả trả về -1.
Ví dụ:

Sub IndexOfValueMethod()
    'oSList.IndexOfValue(Item)'
    Dim oSList As Object, idex As Long
    Set oSList = CreateObject("System.Collections.SortedList")
    oSList.Add "1", 20
    oSList.Add "Z", 20
    oSList.Add "A", "Item3"
    idex = oSList.IndexOfValue(20)          'idex=0'
    MsgBox idex
    idex = oSList.IndexOfValue("Item3")     'idex=1'
    MsgBox idex
    idex = oSList.IndexOfValue("Item4")
    MsgBox idex                             'idex=-1'
End Sub


3.12. Remove

oSList.Remove Key


Xóa một phần tử trong SortedList theo Key chỉ định. Nếu Key chưa tồn tại trong SortedList thì không xảy ra lỗi.

Khi một phần tử được loại bỏ, việc lập chỉ mục (Index) của các phần tử được điều chỉnh cho phù hợp. Do đó, chỉ mục của cặp Key/ Item cụ thể có thể thay đổi khi các phần tử được thêm vào hoặc xoá khỏi SortedList.
Ví dụ:

Sub RemoveMethod()
    'oSList.Remove Key'
    Dim oSList As Object
    Set oSList = CreateObject("System.Collections.SortedList")
    oSList.Add "Key-1", ""
    oSList.Add "Key-2", ""
    oSList.Remove "Key-1"
    MsgBox oSList.GetKey(0)     ' "Key-2" '
End Sub


3.13. RemoveAt

oSList.RemoveAt Index


Xóa một Item trong SortedList theo chỉ số Index chỉ định.
Index: Có giá trị từ 0 tới Count-1.
Ví dụ:

Sub RemoveAtMethod()
    'oSList.RemoveAt Index //Index = 0 : Count-1 '
    Dim oSList As Object
    Set oSList = CreateObject("System.Collections.SortedList")
    oSList.Add "1", ""
    oSList.Add "Z", ""
    oSList.Add "A", ""
    oSList.RemoveAt 1
    MsgBox oSList.GetKey(1)     ' "Z" '
End Sub


3.14. SetByIndex

oSList.SetByIndex Index, Item


Thay đổi giá trị của Item trong SortedList theo chỉ mục (Index) chỉ định.
Ví dụ:

Sub SetByIndexMethod()
    'oSList.SetByIndex Index, Item //Index = 0 : Count-1 '
    Dim oSList As Object
    Set oSList = CreateObject("System.Collections.SortedList")
    oSList.Add 0, 100
    oSList.Add 1, 500
    oSList.Add 2, 10
    oSList.SetByIndex 0, "Item-1"
    MsgBox oSList.GetByIndex(0)
End Sub


3.15. ToString

oSList.ToString


Trả về tên đối tượng hiện hành, tức là “System.Collections.SortedList”.
Ví dụ:

Sub ToStringMethod()
    'oSList.ToString '
    Dim oSList As Object
    Set oSList = CreateObject("System.Collections.SortedList")
    MsgBox oSList.ToString        '"System.Collections.SortedList"'
End Sub


3.16. TrimToSize

oSList.TrimToSize


Thiết lập số phần tử tồn tại thực tế có trong SortedList.
Khi sử dụng phương thức TrimToSize thì Capacity = Count.

Để thiết lập lại SortedList về trạng thái ban đầu, ta sử dụng phương thức Clear trước khi gọi TrimToSize. Việc cắt một SortedList trống sẽ đặt Capacity của SortedList về giá trị mặc định.
Ví dụ:

Sub TrimToSizeMethod()
    'oSList.TrimToSize '
    Dim oSList As Object
    Set oSList = CreateObject("System.Collections.SortedList")
    oSList.Add "Key-1", 1
    oSList.Add "Key-2", 2
    MsgBox "Count = " & oSList.Count & vbNewLine & _
            "Capacity = " & oSList.capacity   '2-16'
    oSList.TrimToSize
    MsgBox "Count = " & oSList.Count & vbNewLine & _
            "Capacity = " & oSList.capacity   '2-2'
End Sub


4. Ứng dụng
Lọc loại trùng, sort mảng, …

4.1. Một số hàm


Hàm lọc loại trùng 1 cột của Range

'// Loc loai trung mot cot'
Function UniqueColumnSortedList(ByVal Rng As Range) As Variant
    If Rng.Count = 1 Then UniqueColumnSortedList = Rng.Value: Exit Function
    Dim oSList As Object, i As Long, j As Long, Arr(), Result(), sKey As Variant
    Set oSList = CreateObject("System.Collections.SortedList")
    Arr = Rng.Value
    For i = LBound(Arr, 1) To UBound(Arr, 1)
        sKey = Arr(i, 1)
        If sKey <> "" Then
            If oSList.ContainsKey(sKey) = False Then
                oSList.Add sKey, ""
                j = j + 1
                ReDim Preserve Result(1 To j)
                Result(j) = sKey
            End If
        End If
    Next i
    UniqueColumnSortedList = Result
End Function


Hàm lọc loại trùng và sort mảng 1 chiều

'// Loc loai trung va sort mang 1 chieu'
Function Sort1DSortedList(ByVal Source1D, Optional ByVal IsNumber As Boolean = True, _
                        Optional ByVal Order As Boolean = True) As Variant
'IsNumber: True - Du lieu kieu so, False - Du lieu kieu chuoi'
'Order: True - Sort A-Z, False - Sort Z-A'
    If IsArray(Source1D) = False Then Exit Function
    Dim oSList As Object, iTemArr
    Set oSList = CreateObject("System.Collections.SortedList")
    For Each iTemArr In Source1D
        If IsNumber = False Then
            iTemArr = CStr(iTemArr)
        Else
            If IsNumeric(iTemArr) = False Then GoTo NextCode
        End If
        If oSList.ContainsKey(iTemArr) = False Then
                oSList.Add iTemArr, ""
        End If
NextCode:
    Next iTemArr
    Sort1DSortedList = GetKeysSortedList(oSList, Order)
End Function


Hàm lấy toàn bộ Keys trong SortedList vào mảng 1 chiều

'// Lay Keys trong SortedList vao array 1D'
Function GetKeysSortedList(oSList As Object, Optional ByVal Order As Boolean = True)
'Order: True - Sort A-Z, False - Sort Z-A'
    Dim Result(), i As Long, index As Long, numKeys As Long
    numKeys = oSList.Count
    ReDim Result(1 To numKeys)
    For i = 1 To numKeys
        If Order = True Then index = i - 1 Else index = numKeys - i
        Result(i) = oSList.GetKey(index)
    Next i
    GetKeysSortedList = Result
End Function


Hàm lấy toàn bộ Items trong SortedList vào mảng 1 chiều

'// Lay Items trong SortedList vao array 1D'
Function GetItemsSortedList(oSList As Object, Optional ByVal Order As Boolean = True)
'Order: True - Sort A-Z, False - Sort Z-A'
    Dim Result(), i As Long, index As Long, numItems As Long
    numItems = oSList.Count
    ReDim Result(1 To numItems)
    For i = 1 To numItems
        If Order = True Then index = i - 1 Else index = numItems - i
        Result(i) = oSList.Item(oSList.GetKey(index))
    Next i
    GetItemsSortedList = Result
End Function


Rate this post

DienDan.Edu.Vn

DienDan.Edu.Vn Cám ơn bạn đã quan tâm và rất vui vì bài viết đã đem lại thông tin hữu ích cho bạn.
DienDan.Edu.Vn! là một website với tiêu chí chia sẻ thông tin,... Bạn có thể nhận xét, bổ sung hay yêu cầu hướng dẫn liên quan đến bài viết. Vậy nên đề nghị các bạn cũng không quảng cáo trong comment này ngoại trừ trong chính phần tên của bạn.
Cám ơn.

Đăng bình luận

(+84) (918) 369.468