Dùng Dictionary thay thế cho Sumifs có được không ah!

Liên hệ QC

Lequocvan

Thành viên thường trực
Tham gia
21/8/07
Bài viết
364
Được thích
128
Donate (Paypal)
Donate
Donate (Momo)
Donate
Giới tính
Nam
Nghề nghiệp
Agribank
Em vẫn dùng Sumifs để tính tổng theo 3 điều kiện nhưng với dữ liệu ngày càng tăng số dòng lên, thì tốc độ tính toán chậm! mà em chưa thạo về Dictionary nên mong các Thầy chỉ giúp ah!
 

File đính kèm

  • GPE - hoi Su phu cach dung dictionary.xlsb
    532.9 KB · Đọc: 28
Em vẫn dùng Sumifs để tính tổng theo 3 điều kiện nhưng với dữ liệu ngày càng tăng số dòng lên, thì tốc độ tính toán chậm! mà em chưa thạo về Dictionary nên mong các Thầy chỉ giúp ah!
- Chậm là do công thức của bạn dùng tham chiếu cả cột (1.048.576 dòng) trong khi sử dụng chưa đến 100.000 dòng.
Dùng Dictionary thay thế cho Sumifs có được không ah!
- Dùng Dictionary được ah!
 
Lần chỉnh sửa cuối:
Upvote 0
Em vẫn dùng Sumifs để tính tổng theo 3 điều kiện nhưng với dữ liệu ngày càng tăng số dòng lên, thì tốc độ tính toán chậm! mà em chưa thạo về Dictionary nên mong các Thầy chỉ giúp ah!
Liên quan gì đến Dictionary chứ. Bạn cứ sử dụng cú pháp If .... Then ....End if lồng vào nhau để cộng có điều kiện nhé
 
Upvote 0
Dạ đúng, em nhìn lại công thức Sumifs mới thấy, chuẩn luôn cả cột. Sư phụ Bate làm giúp em phần Dictionary với ah!
 
Upvote 0
Lý do tại sao bạn cho rằng Dictionary có thể cải thiện cái "tốc độ tính toán chậm" của SumIfs?

Có thể làm được bằng cách cache dữ liệu của Dictionary. Nhưng rất nguy hiểm, chỉ cần bạn thao tác gì đó mà bảng tính không nhận ra hoặc hiểu lầm thì kết quả sẽ sai.
 
Upvote 0
tập tành

Sub GPE_sudungDictionary()
Dim tg As Double
tg = Timer
Dim Dic As Object
Dim Source_Arr As Variant
Dim Result_Arr As Variant
Dim i As Integer
Dim key As String


Set Dic = CreateObject("Scripting.Dictionary")
Sheet2.[C16:R10000].ClearContents
Source_Arr = Sheet1.[e1:k10000]
Result_Arr = Sheet2.[B14:R53]

For i = 1 To 10000
If Source_Arr(i, 1) = "" Then Exit For
key = Source_Arr(i, 1) & "#" & Source_Arr(i, 2) & "#" & Source_Arr(i, 6)
If Not Dic.exists(key) Then
Dic.Add key, Source_Arr(i, 7)
Else
Dic.Item(key) = Dic.Item(key) + Source_Arr(i, 7)
End If
Next

For i = 1 To 40
For j = 1 To 17
key = Result_Arr(i, 1) & "#" & Format(Result_Arr(1, j), "00") & "#" & Result_Arr(2, j)
If Dic.exists(key) Then Result_Arr(i + 2, j) = Dic.Item(key)
Next
Next

Sheet2.[B14:R53] = Result_Arr

Set Dic = Nothing


tg = Timer - tg
MsgBox tg
End Sub
 
Upvote 0
Em áp lại cách Sumifs thì hết trên dưới 40sGPE1.png

Còn áp code của Let's thì không chuẩn xác vì cột F (Tr) lại gồm 2 ký tự, dạng text, 0 thì '00 cơ ah!
 
Upvote 0
Em vẫn dùng Sumifs để tính tổng theo 3 điều kiện nhưng với dữ liệu ngày càng tăng số dòng lên, thì tốc độ tính toán chậm! mà em chưa thạo về Dictionary nên mong các Thầy chỉ giúp ah!
Nếu là tôi thì bài này tôi PivotTable chứ không code không công thức gì ráo
 
Upvote 0
Em cũng nghĩ ngay từ đầu với PivotTable rồi ah! nhưng vẫn muốn thử thêm cách khác ah!
 
Upvote 0
Em cũng nghĩ ngay từ đầu với PivotTable rồi ah! nhưng vẫn muốn thử thêm cách khác ah!
PivotTable là vô địch về tốc độ cũng như tính chính xác. Bạn không nên bỏ qua "đồ ngon" mà lại đi chọn "đồ dở" vậy chứ. VBA hay công thức, không có cái nào có thể qua mặt PVT về tốc độ đâu
Chúng ta chỉ nên dùng VBA hay công thức trong trường hợp không có Layout PVT nào phù hợp với báo cáo mà ta cần
 
Upvote 0
Em cũng nghĩ ngay từ đầu với PivotTable rồi ah! nhưng vẫn muốn thử thêm cách khác ah!
Đối với bạn thì nó chỉ là "thử"
Đối với ngừoi viết code, nếu code không hơn được SumIfs và PivotTable thì tẽn tò, phí công phí sức.

(khoảng vài chục ngàn dòng trở lên thì dùng PowerPivot. Code được hiệu quả hơn PowerPivot thì đừng phí thời gian ở đây nữa, vì mỗi giờ khắc của ngừoi code này trj giá bạc triệu)
 
Upvote 0
em đang học code mà, cảm ơn các Sư phụ!
 
Upvote 0
em đang học code mà, cảm ơn các Sư phụ!
Code chỉ là dịch từ giải thuật ra ngôn ngữ lập trình thôi.
Giải thuật tùm lum thì học chỉ là cách múa kiếm để tăng bắp thịt. Rồi dùng mớ bắp thịt ấy để lấy le với gái và hù dọa con nít. Từ đầu đến cuối chả trọn lấy một chiêu.
Bài này giải thuật không dính líu với đít sần đít sọt gì cả., học chỉ uổng công.
 
Lần chỉnh sửa cuối:
Upvote 0
Code chỉ là dịch từ giải thuật ra ngôn ngữ lập trình thôi.
Giải thuật tùm lum thì học chỉ là cách múa kiếm để tăng bắp thịt. Rồi dùng mớ bắp thịt ấy để lấy le với gái và hù dọa con nít. Từ đầu đến cuối chả trọn lấy một chiêu.
Bài này giải thuật không dính líu với đít sần đít sọt gì cả., học chỉ uổng công.
Bạn có thể gợi ý giải thuật trong trường hợp nầy ?
 
Upvote 0
Anh thử cái này mới vừa học xong
Nếu dùng công thức trong VBA thì cũng chẳng tăng tốc gì đươc đâu bạn à. Nó hoàn toàn tương đương với động tác:
- Gõ công thức trên bảng tính
- Kéo fill cho toàn bảng tính
- Copy dữ liệu và Paste Values
--------------------------------
Bài này dùng Dictionary không phải không được nhưng tôi thắc mắc vì tác giả có nói:
em đang học code mà, cảm ơn các Sư phụ!
"Học" mà sao chọn đề tài khó nhai vậy? Với 3 mảng cần lọc duy nhất rồi cộng dồn, đâu phải chuyện dễ
???!!!
 
Upvote 0
Bạn có thể gợi ý giải thuật trong trường hợp nầy ?
Bạn muốn nói cách dùng Dictionary?
Như bài #5 đã nói qua, dùng mấy cái Object này hơi tốn năng lượng cho nên giải thuật đúng đắn phải có cách cache (tạm giữ dữ liệu) nó lại. Kỹ thuật cache hơi nguy hiểm, cần phải nắm vững chu trình (life cycle) của dữ liệu (đại khái chúng bao lớn, thêm bớt ra sao...). Nếu chỉ để mò code thì không xứng đáng thử.
Nếu chỉ là code mà mỗi lần dữ liệu thay đổi lại phải chạy code để "refresh" thì ở đây, ai biết Dic đều code được, bạn không cần phải hỏi giải thuật đó.

Nếu bạn có đọc một số bài của tôi các mục về các Object phức tạp sẽ thấy tôi dùng Static để cache chúng. Điểm quan trọng của cache là nếu đầu vào thay đổi thì cái cache phải biết mà thay đổi theo. Trong các bài kia, đầu vào không thay đổi cho nên tôi giản dị hoá điều kiện đó.
(*) Nếu bạn theo dõi nhiều sẽ thấy có người dùng biến Public ở toàn cục thay vì Static. Hai kỹ thuật này gần như nhau, vì cùng dùng bộ nhớ chung (heap) để giữ trị khi thoát hàm, lúc ấy các biến trong bộ nhớ riêng (stack) bị xoá hết. Biến toàn cục tuy ít phức tạp hơn Static nhưng nó không được bảo vệ. Biến Static thuộc về hàm, chỉ có hàm chứa nó mới thấy nó, muốn truy vấn sửa đổi gì thì phải nhờ hàm chứa nó làm.
(**) Cách cẩn thận và tốn công hơn nữa là dùng Class Module và từ đó tạo Object riêng. Cái này có lẽ bạn đọc bài của các bạn như Phan Tự Hướng và Nguyễn Duy Tuân đã thấy rồi.
 
Upvote 0
Bạn muốn nói cách dùng Dictionary?
Như bài #5 đã nói qua, dùng mấy cái Object này hơi tốn năng lượng cho nên giải thuật đúng đắn phải có cách cache (tạm giữ dữ liệu) nó lại. Kỹ thuật cache hơi nguy hiểm, cần phải nắm vững chu trình (life cycle) của dữ liệu (đại khái chúng bao lớn, thêm bớt ra sao...). Nếu chỉ để mò code thì không xứng đáng thử.
Nếu chỉ là code mà mỗi lần dữ liệu thay đổi lại phải chạy code để "refresh" thì ở đây, ai biết Dic đều code được, bạn không cần phải hỏi giải thuật đó.

Nếu bạn có đọc một số bài của tôi các mục về các Object phức tạp sẽ thấy tôi dùng Static để cache chúng. Điểm quan trọng của cache là nếu đầu vào thay đổi thì cái cache phải biết mà thay đổi theo. Trong các bài kia, đầu vào không thay đổi cho nên tôi giản dị hoá điều kiện đó.
(*) Nếu bạn theo dõi nhiều sẽ thấy có người dùng biến Public ở toàn cục thay vì Static. Hai kỹ thuật này gần như nhau, vì cùng dùng bộ nhớ chung (heap) để giữ trị khi thoát hàm, lúc ấy các biến trong bộ nhớ riêng (stack) bị xoá hết. Biến toàn cục tuy ít phức tạp hơn Static nhưng nó không được bảo vệ. Biến Static thuộc về hàm, chỉ có hàm chứa nó mới thấy nó, muốn truy vấn sửa đổi gì thì phải nhờ hàm chứa nó làm.
(**) Cách cẩn thận và tốn công hơn nữa là dùng Class Module và từ đó tạo Object riêng. Cái này có lẽ bạn đọc bài của các bạn như Phan Tự Hướng và Nguyễn Duy Tuân đã thấy rồi.
Cache đã dùng nhiều lần, cách update cache học qua code của bạn, còn Class Module thì mù tịt, khi nào rảnh sẽ ngâm cứu.
Chúc bạn 1 ngày vui :):):)
 
Upvote 0
Web KT
Back
Top Bottom