Bài 14. Hashtable (1 người xem)

  • Thread starter Thread starter befaint
  • Ngày gửi Ngày gửi
Liên hệ QC

Người dùng đang xem chủ đề này

befaint

|||||||||||||
Tham gia
6/1/11
Bài viết
14,545
Được thích
19,753
Bài 14. Hashtable

(Danh sách các bài viết về VBA xem ở đây Index - Các bài viết về VBA)

Hashtable là một thư viện nằm trong “System.Collections” của .NET Framework. Cho phép lưu trữ dữ liệu ở dạng mảng với Key riêng duy nhất, cho phép chèn và tìm kiếm đối tượng (Item) rất nhanh, kể cả với dữ liệu có kích cỡ lớn.
Yêu cầu: Hệ thống phải cài đặt .NET Framework.

1. Khai báo Hashtable
1.1. Kiểu khai báo sớm
(Không có Tooltip khi gọi Hashtable, 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:
PHP:
Dim HTbl As New Hashtable
upload_2017-9-7_1-44-9.png

1.2. Kiểu khai báo muộn
(Không có Tooltip khi gọi Hashtable, không cần thiết lập trong Tools/References).
Khai báo trong code:
PHP:
Dim HTbl As Object
Set HTbl = CreateObject("System.Collections.Hashtable")

2. Các phương thức
2.1. Add
PHP:
HTbl.Add Key, Item
Thêm một Item vào Hashtable.
Key: Bắt buộc. Key nhận kiểu dữ liệu là số hoặc chuỗi bất kỳ. Yêu cầu Key phải duy nhất trong Hashtable, nếu Key đó đã tồn tại thì xảy ra lỗi.
Item: Bắt buộc. Item nhận kiểu dữ liệu là số hoặc chuỗi bất kỳ, giá trị đơn hoặc một mảng (array).
Ví dụ:
PHP:
Sub AddMethod()
    Dim HTbl As Object
    Set HTbl = CreateObject("System.Collections.Hashtable")
    'HTbl.Add Key, Item'
    'Key: number + string, Duy nhat. Gap loi khi Key da ton tai trong HTbl'
    'Item: number + string'
    HTbl.Add 10, 100
    HTbl.Add "KeyA", 200
    HTbl.Add "KeyB", "TextB"
    HTbl.Add 20, 5
    HTbl.Add "KeyC", ""
    HTbl.Add "KeyD", Array(20, 25)
End Sub

2.2. Count
PHP:
HTbl.Count
Trả về số Items có trong Hashtable.
Ví dụ:
PHP:
Sub CountMethod()
    Dim HTbl As Object
    Set HTbl = CreateObject("System.Collections.Hashtable")
    'HTbl.Count'
    Dim i As Long
    For i = 1 To 10
        HTbl.Add "Key" & i, i
    Next i
    MsgBox HTbl.Count '10'
End Sub

2.3. Item
PHP:
HTbl.Item (Key)
'Hoặc:'
HTbl(Key)
Gọi tới Item của Hashtable theo Key chỉ định.
Nếu Key chỉ định đưa vào chưa tồn tại trong Hashtable thì không xảy ra lỗi và kết quả trả về là rỗng.
Ví dụ:
PHP:
Sub ItemMethod()
    Dim HTbl As Object
    Set HTbl = CreateObject("System.Collections.Hashtable")
    'HTbl.Item(Key)'
    'HTbl(Key)'
    HTbl.Add 10, 100
    HTbl.Add "KeyA", 200
    HTbl("KeyA") = 500
    MsgBox HTbl.Item(10)        '100'
    MsgBox HTbl.Item("KeyA")    '500'
End Sub

2.4. Remove
PHP:
HTbl.Remove(Key)
Xóa một Item trong Hashtable theo Key chỉ định ứng với Item đó.
Ví dụ:
PHP:
Sub RemoveMethod()
    Dim HTbl As Object
    Set HTbl = CreateObject("System.Collections.Hashtable")
    'HTbl.Remove(Key)'
    Dim i As Long
    For i = 1 To 10
        HTbl.Add "Key" & i, i
    Next i
    HTbl.Remove ("Key4")
    MsgBox HTbl.Count   '9'
End Sub

2.5. ContainsKey
PHP:
HTbl.ContainsKey(Key)
Kiểm tra sự tồn tại của một Key trong Hashtable. Trả về True nếu Key đó tồn tại, ngược lại trả về False.
Ví dụ:
PHP:
Sub ContainsKeyMethod()
    Dim HTbl As Object
    Set HTbl = CreateObject("System.Collections.Hashtable")
    'HTbl.ContainsKey(Key)'
    HTbl.Add 10, 100
    HTbl.Add "KeyA", 200
    MsgBox HTbl.Containskey(10)     'True'
    MsgBox HTbl.Containskey("KeyA") 'True'
    MsgBox HTbl.Containskey("KeyX") 'False'
End Sub

2.6. ContainsValue
PHP:
HTbl.ContainsValue(Value)
Kiểm tra sự tồn tại giá trị của Item trong Hashtable. Trả về True nếu giá trị đó đã tồn tại, ngược lại trả về False.
Ví dụ:
PHP:
Sub ContainsValueMethod()
    Dim HTbl As Object
    Set HTbl = CreateObject("System.Collections.Hashtable")
    'HTbl.ContainsValue(Value)'
    HTbl.Add 10, 100
    HTbl.Add "KeyA", "TextA"
    MsgBox HTbl.ContainsValue(100)     'True'
    MsgBox HTbl.ContainsValue("TextA") 'True'
    MsgBox HTbl.ContainsValue("TextB") 'False'
End Sub

3. Ứng dụng
- Lọc loại trùng
- …
3.1. Hàm lọc loại trùng trong một cột

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

File đính kèm

Lần chỉnh sửa cuối:
Giải thuật băm:
Theo tôi nhớ (*) thì giải thuật băm quan trọng ở lúc bị đụng hàng (collision). Dictionary dùng kỹ thuật liên kết để chứa các cụm (bucket) key. Hashtable dùng phương pháp băm tiếp (rehash) và chứa vào tree. Các số lớn bị đụng nhiều hơn có lẽ do kỹ thuật băm dính líu đến cái khúc đầu khúc cuối gì đó (endian) của con số.

(*) đọc ở đâu đó, quên mất rồi. Nếu không đúng thì xin lỗi. Dạo sau này tôi chuyển qua chơi dữ liệu thống kê cho nên không buồn nghiên cứu code nhiều nữa.
 
Upvote 0
Anh chị xem giúp em code tổng hợp số liệu từ nhiều sheet cho vào một sheet sử dụng Hashtable có gì sai mà không chạy
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Anh chị xem giúp em code tổng hợp số liệu từ nhiều sheet cho vào một sheet sử dụng Hashtable có gì sai mà không chạy
Bảng băm chỉ dùng cho trình độ khá chuyên môn về lập trình.
Nếu bạn chỉ muốn lập trình VBA thì nên quên nó đi.
Nếu bạn muốn nghiên cứu thuật toán lập trình thì nên vào các diễn đàn chuyên môn như C#, vv...
 
Upvote 0
Bảng băm chỉ dùng cho trình độ khá chuyên môn về lập trình.
Nếu bạn chỉ muốn lập trình VBA thì nên quên nó đi.
Nếu bạn muốn nghiên cứu thuật toán lập trình thì nên vào các diễn đàn chuyên môn như C#, vv...

Vâng tại vì em có đọc thấy nói tốc độ xử lý của Has không phụ thuộc Item nên muốn thử thay Dic xem có khác biệt nhiều không. Code ban đầu là sử dụng Dic, em đọc và thay thế bằng Has thì báo lỗi. Mà em thấy lỗi ở chỗ dòng
dArr(Rws, C) = sArr(i, 33) lý do là vì không hiểu sao C của em luôn bằng 0
Mà C của em gọi Item qua key là tên sheet
C = Htbl_Col.Item(Val(Ws.Name)
Có thể giải thích giúp em vì sao không?
 
Upvote 0
Web KT

Bài viết mới nhất

Back
Top Bottom