Bài viết: Tổng quan về Scripting.Dictionary

Liên hệ QC

kyo

Nguyễn Khắc Duy
Thành viên danh dự
Tham gia
4/6/06
Bài viết
901
Được thích
2,714
Với những ai yêu thích Excel nói chung và yêu thích VBA nói riêng thì chắc hẳn cũng đã biết qua các khái niệm về mảng, về công thức điều kiện, vòng lặp,..., những thứ rất quen thuộc mà gần như là sử dụng thường xuyên trong từng bài toán lập trình. Tuy nhiên, có lẽ sẽ rất ít người biết về Dictionary, một công cụ đầy sức mạnh xuất hiện trên VBA từ rất lâu rồi. Sẽ có nhiều người thắc mắc khi thấy các "cao thủ" trên GPE trổ tài sử dụng Dic và không hiểu gì vì những điều mới lạ vừa nhìn thấy cũng như rất ít tư liệu tiếng Việt về Dic trên GPE nói riêng và trên Internet nói chung. Do đó, kyo viết lại bài này dựa trên tư liệu tiếng Anh của Experts-exchange và trên GPE với mong muốn đóng góp ít nhiều, giúp cho các thành viên mới có được cái nhìn tổng quan hơn về Dictionary.

I. Dictionary là gì?


1. Định nghĩa
Là một phần trong thư viện Microsoft Scripting Runtime (scrrun.dll), Dictonary class là một công cụ đầy sức mạnh và linh hoạt. Nó cho phép người sử dụng tạo một object với số lượng item tùy ý,và mỗi item được nhận dạng dựa trên một key duy nhất. Dic có thể nhận các dữ liệu thuộc các kiểu dữ liệu khác nhau mà thường thấy là kiểu chuỗi (string), số (integer, long,…) hay thậm chí là một sự kết hợp giữa cả hai kiểu dữ liệu.


2. Ưu điểm của Dictionary

- Có thể thêm vào số lượng item tùy ý với những kiểu dữ liệu khác nhau.
- Các item và key của Dictionary rất dễ truy xuất, sửa chữa và bổ sung.
- Dictionary cho phép bạn xóa tất cả các item tồn tại trong Dic mà không cần phải phá hủy chính nó.
- Và cuối cùng, các item chỉ có thể được gọi duy nhất bằng cách là thông qua một key mà key đó là bắt buộc và là duy nhất (không thể có 2 key trùng nhau). Điều này tạo thuận lợi cho các bài toán trích lọc danh sách duy nhất và đây cũng chính là ưu điểm lớn nhất của Dictionary.


3. Cách sử dụng Dictionary

1/ Cách khai báo
Vì Dictionary không phải là một phần của thư viện VBA, do đó, để sử dụng nó, chúng ta cần phải khai báo. Bạn có thể khai báo bằng cả hai cách sau:

Cách 1: Để sử dụng cách 1, trước tiên bạn phải vào Tools -> References và lựa chọn Microsoft Scripting Runtime từ trên danh sách để cài đặt -> nhấn OK.

36824663042_6292801510_o.jpg

Sau đó, gõ dòng lệnh:
PHP:
Dim MyDictionary As Scripting.Dictionary 
Set MyDictionary = New Scripting.Dictionary


Cách 2: Gõ dòng lệnh:
PHP:
Dim MyDictionary As Object 
Set MyDictionary = CreateObject("Scripting.Dictionary")

Cách 1 sẽ cho tốc độ nhanh hơn cách 2. Tuy nhiên, cách 2 lại thuận tiện hơn cách 1 khi chia sẻ file cho người sử dụng khác, do với máy tính khác nhau sẽ có nhiều người sử dụng các phiên bản khác nhau. Cách 1 chỉ phù hợp khi chính bạn sử dụng, còn cách 2 phù hợp hơn cho việc chia sẻ.

2/ Các phương thức và thuộc tính:

a. Các phương thức:

- Phương thức Add: Phương thức Add dùng để thêm item vào Dictionary.
PHP:
MyDictionary.Add Key, Item
Item có nhận dữ liệu thuộc bất kì kiểu dữ liệu gì. Key cũng nhận như item nhưng ngoại trừ kiểu dữ liệu mảng (array). Key phải là duy nhất, nếu bạn thêm item với cùng một key, bạn sẽ gặp lỗi.

- Phương thức Exists: Phương thức Exists sẽ kiểm tra xem Key có tồn tại hay không? Nếu Key tồn tại, kết quả sẽ là True và không tồn tại thì kết quả sẽ là False.

- Phương thức Items: Phương thức Items sẽ trả về giá trị mảng một chiều mà phần tử đầu tiên là phần tử 0 (dù cho bạn có sử dụng Option Base 1).
PHP:
MyArray = MyDictionary.Items 
MsgBox Join(MyArray, ";")

- Phương thức Keys: Phương thức Keys sẽ trả về giá trị mảng một chiều mà phần tử đầu tiên là phần tử 0 (dù cho bạn có sử dụng Option Base 1).
PHP:
MyArray = MyDictionary.Keys 
MsgBox Join(MyArray, ";")

- Phương thức Remove: Phương thức Remove sẽ xóa một item thông qua một Key. Nếu Key không tồn tại, bạn sẽ gặp lỗi.
PHP:
MyDictionary.Remove "SomeKey"

- Phương thức RemoveAll: Phương thức RemoveAll sẽ xóa toán bộ những gì có trong Dictionary (nhưng không xóa chính nó).
PHP:
MyDictionary.RemoveAll
b. Các thuộc tính:
- Thuộc tính CompareMode: Dictionary có thể phân biệt dạng chữ được hay không phụ thuộc vào thuộc tính CompareMode. Giá trị mặc định của thuộc tính là 0 (vbBinaryCompare) giúp phân biệt chữ hoa chữ thường trong Key, còn giá trị 1 (vbTextCompare) thì không phân biệt.
PHP:
MyDictionary.CompareMode = vbBinaryCompare  'phân biệt 
MyDictionary.CompareMode = vbTextCompare  'không phân biệt

Ví dụ dưới đây sẽ không gây ra lỗi, nhưng nếu CompareMode = 1 thì chắc chắn bạn sẽ gặp lỗi vì "gpe" và "GPE" là giống nhau.
PHP:
With MyDictionary
      .CompareMode = vbBinaryCompare
      .Add "gpe", "lower"
      .Add "GPE", "UPPER"
End With

- Thuộc tính Count: Thuộc tính Count sẽ trả về giá trị số lượng item có trong Dictionary. Nếu không có item trong Dic, thuộc tính này sẽ trả về giá trị 0.

- Thuộc tính Item: Thuộc tính Item giúp truy xuất hoặc thiết lập giá trị cho một Key nào đó.
PHP:
With MyDictionary
         .Item("SomeKey") = "gpe"
         MsgBox "Giá trị của SomeKey là " & .Item("SomeKey")
End With

Nếu bạn sử dụng thuộc tính Item để đưa một item vào một Key không tồn tại, Dictionary sẽ thêm mới Key không tồn tại đó, đồng thời cũng thêm item vào Key đó luôn. Cũng vậy, nếu bạn truy xuất một item qua một Key không tồn tại, Dictionary sẽ thêm một item rỗng vào chính Key đó. Do đó, sử dụng thuộc tính Item với một Key không tồn tại sẽ không gây ra lỗi.

- Thuộc tính Key: Thuộc tính Key được dùng để thay đổi giá trị của một Key có sẵn. Tuy nhiên, giá trị Key mới phải là giá trị duy nhất trong Dictionary cũng như giá trị Key mà bạn muốn thay đổi cũng phải tồn tại trong Dictionary. Nếu một trong hai điều kiện trên không đúng, chắc chắn lỗi sẽ xảy ra.
PHP:
MyDictionary.Key("SomeKey") = "SomeOtherKey"
3/ Một số lỗi thường gặp

a. vbBinaryCompare hay vbTextCompare

Mặc định, CompareMode = vbBinaryCompare, tức là "key" # "KEY". Còn trong trường hợp ngược lại, "key" = "KEY". Tuy nhiên, cũng chính từ điều này mà đã nảy sinh ra một số rắc rối không cần thiết. Vẫn có nhiều người lẫn lộn giữa vbBinaryCompare và vbTextCompare dẫn đến kết quả không ra như ý muốn. Do đó, bạn cần phải chú ý để thiết lập cho phù hợp.
b. Kiểu dữ liệu của Key

PHP:
With MyDictionary
         .Add 1, "number"
         .Item("1") = "text"
End With

Dòng số 2, kiểu dữ liệu của Key là dạng số trong khi dòng số 3, kiểu dữ liệu của Key là dạng chuỗi dẫn đến hai Key của ví dụ trên là khác nhau. Muốn cho cả hai Key đó giống nhau cũng như là để gán lại item cho Key, tức chỉ là kiểu chuỗi chẳng hạn, bạn phải sử dụng câu lệnh .Add CStr(1), "number” thay cho dòng số 2 ở bên trên.

4/ Ví dụ tham khảo
Trích từ bài tập của chú Mỹ (ptm0412) trong chuyên đề bài tập VBA. Đây là một dạng khá thông dụng dùng để sử dụng Dic vì mục đích của nó chính là trích lọc ra giá trị duy nhất, tức giá trị "Nhân viên" dùng để biết được nhân viên đó đem lại doanh thu là bao nhiêu.

36855962891_9a95f6e2b4_b.jpg

Bài giải

36824662652_b77a7a61d8_b.jpg
PHP:
Sub Cau1()
Dim Dic1 As Object, iRow As Long, i As Long
Dim Arr() As Variant, TmpArr As Variant
With Sheets("Cau1") .Range("E4:H10").ClearContents 
Set Dic1 = CreateObject("Scripting.Dictionary")
    TmpArr = Sheet1.Range("b2:g21").Value
    ReDim Arr(1 To UBound(TmpArr, 1), 1 To 6)
    For iRow = 1 To UBound(TmpArr, 1)
        If Not IsEmpty(TmpArr(iRow, 2)) And Not Dic1.exists(TmpArr(iRow, 2)) Then
            i = i + 1
             Dic1.Add TmpArr(iRow, 2), i
             Arr(i, 1) = TmpArr(iRow, 1)
             Arr(i, 2) = TmpArr(iRow, 2)
            If TmpArr(iRow, 3) <> "" Then
                Arr(i, 3) = TmpArr(iRow, 6)
            Else
                Arr(i, 4) = TmpArr(iRow, 6)
            End If
        Else
            If TmpArr(iRow, 3) <> "" Then
                Arr(Dic1.Item(TmpArr(iRow, 2)), 3) = Arr(Dic1.Item(TmpArr(iRow, 2)), 3) + TmpArr(iRow, 6)
            Else
                             Arr(Dic1.Item(TmpArr(iRow, 2)), 4) = Arr(Dic1.Item(TmpArr(iRow, 2)), 4) + TmpArr(iRow, 6)
                            End If
        End If
    Next
 iRow.Range("e4").Resize(i, 4).Value = Arr
End With
End Sub

kyo.

Những bài viết có liên quan:

1/ Hiểu biết thêm về phương thức Evaluate - Understanding Evaluate Method
2/ Tham số hình thức và tham số thực sự
3/ Sử dụng Name trong VBA
 
Lần chỉnh sửa cuối:
Upvote 0
Web KT
Back
Top Bottom