Đếm số lần xuất hiện của dữ liệu bằng Dictionary (1 người xem)

Liên hệ QC

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

thaitran.lshb5

Thành viên mới
Tham gia
2/3/22
Bài viết
1
Được thích
0
Các anh chị cho em hỏi ví dụ em có dãy sau, làm thế nào để Dùng dictionary đếm được Bút bi xuất hiện 2 lần ạ. sau đó điền số lần xuất hiện ở cột bên cạnh. em cảm ơn anh/chị rất nhiều.
Bút bi2
Bút Chì1
Bút bi2
 
Các anh chị cho em hỏi ví dụ em có dãy sau, làm thế nào để Dùng dictionary đếm được Bút bi xuất hiện 2 lần ạ. sau đó điền số lần xuất hiện ở cột bên cạnh. em cảm ơn anh/chị rất nhiều.
Bút bi2
Bút Chì1
Bút bi2
Dùng hàm CountIf là đếm được rồi, mắc mớ gì phải dùng dictionary chứ
 
Upvote 0
Các anh chị cho em hỏi ví dụ em có dãy sau, làm thế nào để Dùng dictionary đếm được Bút bi xuất hiện 2 lần ạ. sau đó điền số lần xuất hiện ở cột bên cạnh. em cảm ơn anh/chị rất nhiều.
Bút bi2
Bút Chì1
Bút bi2
Đưa cái dữ liệu dài và to lên chứ vài dòng thế này ngồi gõ cho bạn bao nhiêu dòng code cũng thấy chán.Nếu không bạn tìm hiểu Dictonary đến đâu rồi viết ra sai chỗ nào đưa lên đây.
 
Upvote 0
Dùng hàm CountIf là đếm được rồi, mắc mớ gì phải dùng dictionary chứ
CountIf ai lại chả biết. Phải đít son mới trộ người chung quanh được chứ.

Xuống nước chưa chắc đã nổi chưa. Nhưng nghe người ta nói bơi bướm thì cũng ráng đòi học bơi bướm trước hết.
 
Upvote 0
CountIf ai lại chả biết. Phải đít son mới trộ người chung quanh được chứ.

Xuống nước chưa chắc đã nổi chưa. Nhưng nghe người ta nói bơi bướm thì cũng ráng đòi học bơi bướm trước hết.
Nếu dữ,liệu lớn dùng Dic thì cũng được anh ơi.Nếu dùng hàm mảng countif có khi làm file chậm ì ạch.Vấn đề là dữ liệu lớn đến mức nào.Tầm trên 10k dòng là chậm,lắm rồi.
 
Upvote 0
Nếu dữ,liệu lớn dùng Dic thì cũng được anh ơi.Nếu dùng hàm mảng countif có khi làm file chậm ì ạch.Vấn đề là dữ liệu lớn đến mức nào.Tầm trên 10k dòng là chậm,lắm rồi.
Đới với các bạn, thích code cho nên chậm/nhanh là một tiêu điểm.
Đối với tôi, tin cậy vào code mới là tiêu điểm chính. Code mà người nhận về có thể hiểu, có thể chỉnh sửa những chỗ dễ mới có giá trị.
 
Upvote 0
Muốn dic thì có dic:
Mã:
Option Explicit
Sub dem()
Dim lr&, i&, rng, dic As Object, key
Set dic = CreateObject("Scripting.Dictionary")
lr = Cells(Rows.Count, "A").End(xlUp).Row
rng = Range("A1:B" & lr).Value
For i = 1 To UBound(rng)
    If Not dic.exists(rng(i, 1)) And Not IsEmpty(rng(i, 1)) Then
        dic.Add rng(i, 1), 1
    Else
        dic(rng(i, 1)) = dic(rng(i, 1)) + 1
    End If
Next
For i = 1 To UBound(rng)
    For Each key In dic.keys
        If key = rng(i, 1) Then
            rng(i, 2) = dic(key)
            Exit For
        End If
    Next
Next
Range("A1:B" & lr).Value = rng
End Sub
 

File đính kèm

Upvote 0
Thứ tự ưu tiên khi dữ liệu lớn (chủ đề này):
1. Pivot table
2. Advanced filter Unique only (hoặc Remove duplicate) + CountIf
3. VBA (Dict)

Muốn dic thì có dic:

Range("A1:B" & lr).Value = rng

Chơi ghi đè lên dữ liệu gốc thì chơi với ai.
 
Upvote 0
Ở đây chỉ đếm thôi chứ không có làm con toán tổng hợp gì khác. Không cần đến đít son hay đít sần.
Tôi nhớ có một bạn lý luận "cái gì cũng đít, đầu óc quy về một hướng, lười tính các giải thuật khác". Một bạn khác lý luận "tại sao phải tính giải thuật khác khi đã tin tưởng đít là hiệu quả nhất".

Giải thuật:
1. xuất range vào một mảng.
2. sắp xếp mảng
3. đọc và dùng Find hay Match để tìm lần xuất hiện đầu tiên và cuối của mã.
4. tính ra số lần xuất hiện.

Nếu số dòng khá lớn so với số mã (tức là số lặp lại khá nhiều) thì giải thuật này khá hiệu quả.
 
Upvote 0
Ở đây chỉ đếm thôi chứ không có làm con toán tổng hợp gì khác. Không cần đến đít son hay đít sần.
...
Bởi vậy tôi để Dict trong ngoặc.
3. đọc và dùng Find hay Match để tìm lần xuất hiện đầu tiên và cuối của mã.
Dùng Match của WorsheetFunction để tìm trong mảng (Array)? Không phải tôi chê, mà là mới thấy lần đầu. Lý do là tôi không dùng VBA cho trường hợp này nên không tưởng tượng nổi.
 
Upvote 0
Ở đây chỉ đếm thôi chứ không có làm con toán tổng hợp gì khác. Không cần đến đít son hay đít sần.
Tôi nhớ có một bạn lý luận "cái gì cũng đít, đầu óc quy về một hướng, lười tính các giải thuật khác". Một bạn khác lý luận "tại sao phải tính giải thuật khác khi đã tin tưởng đít là hiệu quả nhất".

Giải thuật:
1. xuất range vào một mảng.
2. sắp xếp mảng
3. đọc và dùng Find hay Match để tìm lần xuất hiện đầu tiên và cuối của mã.
4. tính ra số lần xuất hiện.

Nếu số dòng khá lớn so với số mã (tức là số lặp lại khá nhiều) thì giải thuật này khá hiệu quả.
Bước số 2 xắp xếp mảng dùng thư viện gì anh ơi.
 
Upvote 0
Bước số 2 xắp xếp mảng dùng thư viện gì anh ơi.
Cái này 1 chiều chắc dùng:
PHP:
CreateObject("System.Collections.ArrayList")
Bài đã được tự động gộp:

Thứ tự ưu tiên khi dữ liệu lớn (chủ đề này):
1. Pivot table
2. Advanced filter Unique only (hoặc Remove duplicate) + CountIf
3. VBA (Dict)



Chơi ghi đè lên dữ liệu gốc thì chơi với ai.
Chỗ số 2 thì dùng trực tiếp Countif luôn anh.
 
Lần chỉnh sửa cuối:
Upvote 0
Muốn dic thì có dic:
Mã:
Option Explicit
Sub dem()
Dim lr&, i&, rng, dic As Object, key
Set dic = CreateObject("Scripting.Dictionary")
lr = Cells(Rows.Count, "A").End(xlUp).Row
rng = Range("A1:B" & lr).Value
For i = 1 To UBound(rng)
    If Not dic.exists(rng(i, 1)) And Not IsEmpty(rng(i, 1)) Then
        dic.Add rng(i, 1), 1
    Else
        dic(rng(i, 1)) = dic(rng(i, 1)) + 1
    End If
Next
For i = 1 To UBound(rng)
    For Each key In dic.keys
        If key = rng(i, 1) Then
            rng(i, 2) = dic(key)
            Exit For
        End If
    Next
Next
Range("A1:B" & lr).Value = rng
End Sub
Mã:
    For Each key In dic.keys
        If key = rng(i, 1) Then
            rng(i, 2) = dic(key)
            Exit For
        End If
Cái này có vẻ thừa.Dùng làm gì vậy anh.
 
Lần chỉnh sửa cuối:
Upvote 0
Bước số 2 xắp xếp mảng dùng thư viện gì anh ơi.
Cái hay của tư duy lập trình là chỗ này.
Nếu bạn để ý, tôi vẫn thường nói: công việc khác thì tách code ra thành một cụm (Sub/Function) khác.

Khi tôi có một (vài) Subs/Functions trong thư viện rồi thì tôi không phải quan tâm chuyện này. Ở diễn đàn này có cả đống bài nói về code sort array.
Nếu Code sort của tôi xịn, nó có thể tự mò môi trường mà sử dụng giải thuật sort thích đáng. Điển hình là dùng #IF-#ELSE

Chú thêm: một lần code kha khá của tôi sẽ có ít nhất là 2 modules. Một module chính chưa code làm công việc chính. Và Module ThuVien chứa code thư viện import từ File "ThuVien Loai v0n.BAS". Loai là chủng loại công việc, v0n là phiên bản.
 
Upvote 0
Cái hay của tư duy lập trình là chỗ này.
Nếu bạn để ý, tôi vẫn thường nói: công việc khác thì tách code ra thành một cụm (Sub/Function) khác.

Khi tôi có một (vài) Subs/Functions trong thư viện rồi thì tôi không phải quan tâm chuyện này. Ở diễn đàn này có cả đống bài nói về code sort array.
Nếu Code sort của tôi xịn, nó có thể tự mò môi trường mà sử dụng giải thuật sort thích đáng. Điển hình là dùng #IF-#ELSE

Chú thêm: một lần code kha khá của tôi sẽ có ít nhất là 2 modules. Một module chính chưa code làm công việc chính. Và Module ThuVien chứa code thư viện import từ File "ThuVien Loai v0n.BAS". Loai là chủng loại công việc, v0n là phiên bản.
Thế thì đầu tư lắm viết 1 Function Sort làm thư viện riêng rồi sử dụng trong mọi môi trường.Vâng em cảm ơn anh nhé.Thực ra trên diễn đàn cũng có bài code về xắp xếp nhưng em hay dùng trong thư viện của Win.Chắc phải sưu tầm và tìm hiểu thêm để viết 1 code hoàn thiện.
 
Upvote 0
Cái này dùng dictionary 1 phát ăn ngay, sao các bác triển khai rộng thế nhỉ?
Có thể chủ thớt đang nghiên cứu về dic, muốn dùng dic giải quyết vấn đề này thế thôi.
Dữ liệu lớn thì dùng dic là chuẩn chỉ rồi.
Mã:
    For Each key In dic.keys
        If key = rng(i, 1) Then
            rng(i, 2) = dic(key)
            Exit For
        End If
Cái này có vẻ thừa.Dùng làm gì vậy anh.
Duyệt qua mảng 2 lần.
Lần 1 để nạp giá trị duy nhất vào key và số đếm vào item
Lần 2 (là cái bạn hỏi) để so sánh với key và lấy item ra.
 
Upvote 0
Thế thì đầu tư lắm viết 1 Function Sort làm thư viện riêng rồi sử dụng trong mọi môi trường.Vâng em cảm ơn anh nhé.Thực ra trên diễn đàn cũng có bài code về xắp xếp nhưng em hay dùng trong thư viện của Win.Chắc phải sưu tầm và tìm hiểu thêm để viết 1 code hoàn thiện.
1. Một ngày bạn lên đây viết code cho vài người. Chẳng lẽ chính mình lại không muốn đầu tư?
2. Ở đây có nhiều người đầu tư viết code sort xịn lắm.
 
Upvote 0
Cái này dùng dictionary 1 phát ăn ngay, sao các bác triển khai rộng thế nhỉ?
Có thể chủ thớt đang nghiên cứu về dic, muốn dùng dic giải quyết vấn đề này thế thôi.
Dữ liệu lớn thì dùng dic là chuẩn chỉ rồi.

Duyệt qua mảng 2 lần.
Lần 1 để nạp giá trị duy nhất vào key và số đếm vào item
Lần 2 (là cái bạn hỏi) để so sánh với key và lấy item ra.
Nhưng tại sao lại có thêm cái vòng lặp For each ở trong làm gì vậy anh.
 
Upvote 0
Nhưng tại sao lại có thêm cái vòng lặp For each ở trong làm gì vậy anh.
Trong phần giải thích mình đã nói rõ rồi mà : "Lần 2 (là cái bạn hỏi) để so sánh với key và lấy item ra."
"For each key in dic.keys" để duyệt qua từng key trong dic.
 
Upvote 0
Trong phần giải thích mình đã nói rõ rồi mà : "Lần 2 (là cái bạn hỏi) để so sánh với key và lấy item ra."
"For each key in dic.keys" để duyệt qua từng key trong dic.
Tại sao phải duyệt qua khi gán được luôn giá trị nhỉ.
 
Upvote 0
Cái này dùng dictionary 1 phát ăn ngay, sao các bác triển khai rộng thế nhỉ?
Tại bạn quen dùng đít cho nên nó thành ra dễ, cái từ "một phát ăn ngay" là chủ quan.
Đối với người biết dùng đủ công cụ thì nó chỉ là một công cụ.

Có thể chủ thớt đang nghiên cứu về dic, muốn dùng dic giải quyết vấn đề này thế thôi.
Đó là chuyện của thớt. Ở đây, ai cũng biết tôi thích chia sẻ với người khác.

Dữ liệu lớn thì dùng dic là chuẩn chỉ rồi.
Chưa thấy chứng minh. Vả lại, chứng minh cũng khó vì từ "chuẩn" ở đây chưa được tiêu chuẩn hóa. Định nghĩa thế nào là chuẩn?

Nếu từ chuẩn được định nghĩa là dễ hiểu, dễ chỉnh sửa theo quan niệm chung của lập trình (không phải quan niệm đặc thù của GPE) thì với các máy tốt dùng ADODB có thể dễ hơn, dễ đưa vào code thư viện hơn.
 
Upvote 0
Cụ thể thế nào bạn đưa vào code luôn đi
Code đít sần căn bản.

Giả sử các mã cần tổng hợp chứa ở a1:a5, và kết quả ghi vào b1.

Sub t()
Set dc = CreateObject("scripting.dictionary")
For Each v In [a1:a5].Value
dc(v) = dc(v) + 1
Next v
[b1].Resize(dc.Count) = Application.Transpose(dc.keys)
[b1].Resize(dc.Count).Offset(0, 1) = Application.Transpose(dc.items)
End Sub
 
Upvote 0
Cụ thể thế nào bạn đưa vào code luôn đi
Theo mạch code của bác thì nó chỉ vậy:
Mã:
Sub dem()
Dim lr&, i&, rng, dic As Object, key
Set dic = CreateObject("Scripting.Dictionary")
lr = Cells(Rows.Count, "A").End(xlUp).Row
rng = Range("A1:B" & lr).Value
For i = 1 To UBound(rng)
        dic.Item(rng(i, 1)) = 1 + dic.Item(rng(i, 1))
Next
For i = 1 To UBound(rng)
    rng(i, 2) = dic.Item(rng(i, 1))
Next
Range("A1:B" & lr).Value = rng
End Sub
 
Upvote 0
Code dùng ADO:

Sub tt()
Const CNNSTR = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=TenFile;Extended Properties=""Excel 12.0 Xml;HDR=No"""
With CreateObject("ADODB.Recordset")
.Open ("Select Max(F1), Count(1) From [Sheet1$A1:A] Where F1 Is Not Null Group By F1"), _
Replace(CNNSTR, "TenFile", ThisWorkbook.FullName)
[D1].CopyFromRecordset .DataSource
End With
End Sub

Tôi không thích ADO lắm. Nhưng đưa ra đây để chứng minh địa vị "chuẩn chỉ" của đít sần chỉ là tưởng tượng.

Chú thích: code chôm của Hai Lúa Miền Tây, sửa lại chút.
 
Upvote 0
Code dùng ADO:

Sub tt()
Const CNNSTR = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=TenFile;Extended Properties=""Excel 12.0 Xml;HDR=No"""
With CreateObject("ADODB.Recordset")
.Open ("Select Max(F1), Count(1) From [Sheet1$A1:A] Where F1 Is Not Null Group By F1"), _
Replace(CNNSTR, "TenFile", ThisWorkbook.FullName)
[D1].CopyFromRecordset .DataSource
End With
End Sub

Tôi không thích ADO lắm. Nhưng đưa ra đây để chứng minh địa vị "chuẩn chỉ" của đít sần chỉ là tưởng tượng.

Chú thích: code chôm của Hai Lúa Miền Tây, sửa lại chút.
ADO lại phải học thêm câu lệnh Sql.
 
Upvote 0
ADO lại phải học thêm câu lệnh Sql.
Đối với người khá quen thuộc với Access thì nó không khó lắm.
Mặt khác, đít sần cũng phải làm quen với các giải thuật tính tổng.
Ở bài #24 tôi có nói về chuyện "quen" rồi.
 
Upvote 0

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

Back
Top Bottom