Trợ giúp giải thích chi tiết Code dùng Scripting.Dictionary

Liên hệ QC

hoahuongduong1986

Thành viên thường trực
Tham gia
14/11/18
Bài viết
346
Được thích
40
Dear Các Anh Chị,
Em thấy Scripting.Dictionary rất hay và đã dành time tìm hiểu các code mà các anh chị trên diễn đàn trợ giúp mọi người. Nhưng nói thật em dốt quá, đọc mãi em chưa hiểu ý nghĩa các đoạn Code chỉ hiểu láng máng rất ít mặc dù dùng nó chỉ có một số cái như add.dic, check tồn tại, Key, exists....nhưng khi vào một bài cụ thể thì lại không hiểu nổi. Nay em paste một Code này khá điển hình nhờ các anh chị và các bạn dành time diễn dải ý nghĩa các đoạn chính của Code được không ạ ? Kỳ thực rất muốn học để tự làm mà thấy khó quá ạ. Em cảm ơn ạ.


Sub Locgomsolieu()
.....
Set dic = CreateObject("Scripting.Dictionary")
dic.CompareMode = vbTextCompare

With ThisWorkbook.Worksheets("DATA")
LastR = .Cells(.Rows.Count, 1).End(xlUp).Row
Contents = .Range("a2:c" & LastR).Value
End With

For r = 1 To UBound(Contents, 1)
If dic.Exists(Contents(r, 1)) Then
Set dic2 = dic.Item(Contents(r, 1))
If dic2.Exists(Contents(r, 2)) Then
dic2.Item(Contents(r, 2)) = dic2.Item(Contents(r, 2)) + Contents(r, 3)
Else
dic2.Add Contents(r, 2), Contents(r, 3)
End If

Else
Set dic2 = CreateObject("Scripting.Dictionary")
dic2.CompareMode = vbTextCompare
dic2.Add Contents(r, 2), Contents(r, 3)
dic.Add Contents(r, 1), dic2
End If
Next

Worksheets.Add
[a1:b1].Value = Array("Code", "Product - Qty")
ParentKeys = dic.Keys
[a2].Resize(UBound(ParentKeys) + 1, 1).Value = Application.Transpose(ParentKeys)


For r = 0 To UBound(ParentKeys)
Set dic2 = dic.Item(ParentKeys(r))
ChildKeys = dic2.Keys
WriteStr = ""
For r2 = 0 To dic2.Count - 1
WriteStr = WriteStr & Chr(10) & ChildKeys(r2) & " - " & Format(dic2.Item(ChildKeys(r2)), "#,###") & " Trd"
Next
WriteStr = Mid(WriteStr, 2)
Cells(r + 2, 2) = WriteStr
Next
[a1].Sort Key1:=[a1], Order1:=xlAscending, Header:=xlYes
With [b:b]
.ColumnWidth = 40
.WrapText = True
End With
Columns.AutoFit
Rows.AutoFit
Set dic2 = Nothing
Set dic = Nothing

MsgBox "Done"

End Sub
 

File đính kèm

  • Gop du lieu.xlsm
    27.7 KB · Đọc: 13
Dear Các Anh Chị,
Em thấy Scripting.Dictionary rất hay và đã dành time tìm hiểu các code mà các anh chị trên diễn đàn trợ giúp mọi người. Nhưng nói thật em dốt quá, đọc mãi em chưa hiểu ý nghĩa các đoạn Code chỉ hiểu láng máng rất ít mặc dù dùng nó chỉ có một số cái như add.dic, check tồn tại, Key, exists....nhưng khi vào một bài cụ thể thì lại không hiểu nổi. Nay em paste một Code này khá điển hình nhờ các anh chị và các bạn dành time diễn dải ý nghĩa các đoạn chính của Code được không ạ ? Kỳ thực rất muốn học để tự làm mà thấy khó quá ạ. Em cảm ơn ạ.
Ham học hỏi là điều tốt, nhưng giao tiếp với cộng đồng "nửa Ta nửa Tây" thì khó mà gặp được "mọi người".
Chỉ một số "chít chát" hiểu bạn mới tham gia thôi.
 
Upvote 0
Dear Các Anh Chị,
Em thấy Scripting.Dictionary rất hay và đã dành time tìm hiểu các code mà các anh chị trên diễn đàn trợ giúp mọi người. Nhưng nói thật em dốt quá, đọc mãi em chưa hiểu ý nghĩa các đoạn Code chỉ hiểu láng máng rất ít mặc dù dùng nó chỉ có một số cái như add.dic, check tồn tại, Key, exists....nhưng khi vào một bài cụ thể thì lại không hiểu nổi. Nay em paste một Code này khá điển hình nhờ các anh chị và các bạn dành time diễn dải ý nghĩa các đoạn chính của Code được không ạ ? Kỳ thực rất muốn học để tự làm mà thấy khó quá ạ. Em cảm ơn ạ.


Sub Locgomsolieu()
.....
Set dic = CreateObject("Scripting.Dictionary")
dic.CompareMode = vbTextCompare

With ThisWorkbook.Worksheets("DATA")
LastR = .Cells(.Rows.Count, 1).End(xlUp).Row
Contents = .Range("a2:c" & LastR).Value
End With

For r = 1 To UBound(Contents, 1)
If dic.Exists(Contents(r, 1)) Then
Set dic2 = dic.Item(Contents(r, 1))
If dic2.Exists(Contents(r, 2)) Then
dic2.Item(Contents(r, 2)) = dic2.Item(Contents(r, 2)) + Contents(r, 3)
Else
dic2.Add Contents(r, 2), Contents(r, 3)
End If

Else
Set dic2 = CreateObject("Scripting.Dictionary")
dic2.CompareMode = vbTextCompare
dic2.Add Contents(r, 2), Contents(r, 3)
dic.Add Contents(r, 1), dic2
End If
Next

Worksheets.Add
[a1:b1].Value = Array("Code", "Product - Qty")
ParentKeys = dic.Keys
[a2].Resize(UBound(ParentKeys) + 1, 1).Value = Application.Transpose(ParentKeys)


For r = 0 To UBound(ParentKeys)
Set dic2 = dic.Item(ParentKeys(r))
ChildKeys = dic2.Keys
WriteStr = ""
For r2 = 0 To dic2.Count - 1
WriteStr = WriteStr & Chr(10) & ChildKeys(r2) & " - " & Format(dic2.Item(ChildKeys(r2)), "#,###") & " Trd"
Next
WriteStr = Mid(WriteStr, 2)
Cells(r + 2, 2) = WriteStr
Next
[a1].Sort Key1:=[a1], Order1:=xlAscending, Header:=xlYes
With [b:b]
.ColumnWidth = 40
.WrapText = True
End With
Columns.AutoFit
Rows.AutoFit
Set dic2 = Nothing
Set dic = Nothing

MsgBox "Done"

End Sub
Anh định giải thích ở khúc mô? Anh có thể trích dẫn.
 
Upvote 0
Dear Các Anh Chị,
Em thấy Scripting.Dictionary rất hay và đã dành time tìm hiểu các code mà các anh chị trên diễn đàn trợ giúp mọi người. Nhưng nói thật em dốt quá, đọc mãi em chưa hiểu ý nghĩa các đoạn Code chỉ hiểu láng máng rất ít mặc dù dùng nó chỉ có một số cái như add.dic, check tồn tại, Key, exists....nhưng khi vào một bài cụ thể thì lại không hiểu nổi. Nay em paste một Code này khá điển hình nhờ các anh chị và các bạn dành time diễn dải ý nghĩa các đoạn chính của Code được không ạ ? Kỳ thực rất muốn học để tự làm mà thấy khó quá ạ. Em cảm ơn ạ.


Sub Locgomsolieu()
.....
Set dic = CreateObject("Scripting.Dictionary")
dic.CompareMode = vbTextCompare

With ThisWorkbook.Worksheets("DATA")
LastR = .Cells(.Rows.Count, 1).End(xlUp).Row
Contents = .Range("a2:c" & LastR).Value
End With

For r = 1 To UBound(Contents, 1)
If dic.Exists(Contents(r, 1)) Then
Set dic2 = dic.Item(Contents(r, 1))
If dic2.Exists(Contents(r, 2)) Then
dic2.Item(Contents(r, 2)) = dic2.Item(Contents(r, 2)) + Contents(r, 3)
Else
dic2.Add Contents(r, 2), Contents(r, 3)
End If

Else
Set dic2 = CreateObject("Scripting.Dictionary")
dic2.CompareMode = vbTextCompare
dic2.Add Contents(r, 2), Contents(r, 3)
dic.Add Contents(r, 1), dic2
End If
Next

Worksheets.Add
[a1:b1].Value = Array("Code", "Product - Qty")
ParentKeys = dic.Keys
[a2].Resize(UBound(ParentKeys) + 1, 1).Value = Application.Transpose(ParentKeys)


For r = 0 To UBound(ParentKeys)
Set dic2 = dic.Item(ParentKeys(r))
ChildKeys = dic2.Keys
WriteStr = ""
For r2 = 0 To dic2.Count - 1
WriteStr = WriteStr & Chr(10) & ChildKeys(r2) & " - " & Format(dic2.Item(ChildKeys(r2)), "#,###") & " Trd"
Next
WriteStr = Mid(WriteStr, 2)
Cells(r + 2, 2) = WriteStr
Next
[a1].Sort Key1:=[a1], Order1:=xlAscending, Header:=xlYes
With [b:b]
.ColumnWidth = 40
.WrapText = True
End With
Columns.AutoFit
Rows.AutoFit
Set dic2 = Nothing
Set dic = Nothing

MsgBox "Done"

End Sub
Tôi nghĩ bạn nên xem bài viết của anh @befaint ở chủ đề này.
 
Upvote 0
Anh định giải thích ở khúc mô? Anh có thể trích dẫn.
Dạ vâng ạ. Nhờ Chị giải thích giúp em 3 đoạn dưới đây ạ.


For r = 1 To UBound(Contents, 1)
If dic.Exists(Contents(r, 1)) Then
Set dic2 = dic.Item(Contents(r, 1))
If dic2.Exists(Contents(r, 2)) Then
dic2.Item(Contents(r, 2)) = dic2.Item(Contents(r, 2)) + Contents(r, 3)
Else
dic2.Add Contents(r, 2), Contents(r, 3)
End If

Else
Set dic2 = CreateObject("Scripting.Dictionary")
dic2.CompareMode = vbTextCompare
dic2.Add Contents(r, 2), Contents(r, 3)
dic.Add Contents(r, 1), dic2
End If
Next



For r = 0 To UBound(ParentKeys)
Set dic2 = dic.Item(ParentKeys(r))
ChildKeys = dic2.Keys
WriteStr = ""
For r2 = 0 To dic2.Count - 1
WriteStr = WriteStr & Chr(10) & ChildKeys(r2) & " - " & Format(dic2.Item(ChildKeys(r2)), "#,###") & " Trd"
Next
WriteStr = Mid(WriteStr, 2)
Cells(r + 2, 2) = WriteStr
Next
Bài đã được tự động gộp:

Tôi nghĩ bạn nên xem bài viết của anh @befaint ở chủ đề này.
Nhìn có vẻ khá hay và chi tiết từng bước ạ. Em sẽ cố gắng hiểu nó ạ. Em cảm ơn ạ.
 
Lần chỉnh sửa cuối:
Upvote 0
Mình chưa dùng kiểu dic này lấy dic kia làm item bao giờ. Chắc phải xem file mới hiểu tác giả đang làm gì
 
Upvote 0
Dạ vâng ạ. Nhờ Chị giải thích giúp em 3 đoạn dưới đây ạ.


For r = 1 To UBound(Contents, 1)
If dic.Exists(Contents(r, 1)) Then
Set dic2 = dic.Item(Contents(r, 1))
If dic2.Exists(Contents(r, 2)) Then
dic2.Item(Contents(r, 2)) = dic2.Item(Contents(r, 2)) + Contents(r, 3)
Else
dic2.Add Contents(r, 2), Contents(r, 3)
End If

Else
Set dic2 = CreateObject("Scripting.Dictionary")
dic2.CompareMode = vbTextCompare
dic2.Add Contents(r, 2), Contents(r, 3)
dic.Add Contents(r, 1), dic2
End If
Next



For r = 0 To UBound(ParentKeys)
Set dic2 = dic.Item(ParentKeys(r))
ChildKeys = dic2.Keys
WriteStr = ""
For r2 = 0 To dic2.Count - 1
WriteStr = WriteStr & Chr(10) & ChildKeys(r2) & " - " & Format(dic2.Item(ChildKeys(r2)), "#,###") & " Trd"
Next
WriteStr = Mid(WriteStr, 2)
Cells(r + 2, 2) = WriteStr
Next
Bài đã được tự động gộp:


Nhìn có vẻ khá hay và chi tiết từng bước ạ. Em sẽ cố gắng hiểu nó ạ. Em cảm ơn ạ.

mình có chú thích từng câu lệnh hy vọng giúp bạn hiểu được phần nào. :)

For r = 1 To UBound(Contents, 1) ' r chay tu 1 toi phan tu cuoi cung cua mang Contents
If dic.Exists(Contents(r, 1)) Then 'kiem tra su ton tai giá tri Contents(r, 1) trong dic
Set dic2 = dic.Item(Contents(r, 1)) 'neu giá tri Contents(r, 1) dang co trong dic thi goi dict2
If dic2.Exists(Contents(r, 2)) Then 'kiem tra su ton tai giá tri Contents(r, 2) trong dic2
dic2.Item(Contents(r, 2)) = dic2.Item(Contents(r, 2)) + Contents(r, 3) ' dic2.Item(Contents(r, 2)) = dic2(Contents(r, 2)): neu giá tri Contents(r, 2) co trong dict2 thi cong gop vao item cua dict2
Else
dic2.Add Contents(r, 2), Contents(r, 3) ' neu giá tri Contents(r, 2) chua co trong dic2 thi them gia tri này vao dic2 voi item la Contents(r, 3)
End If

Else
Set dic2 = CreateObject("Scripting.Dictionary") 'neu gia tri Contents(r, 1) chua co trong dict thì tao dic2 moi.
dic2.CompareMode = vbTextCompare 'ko phan biet chu hoa va chu thuong
dic2.Add Contents(r, 2), Contents(r, 3) 'add key cua dic2 la Contents(r, 2) va item cua dic2 là Contents(r, 3)
dic.Add Contents(r, 1), dic2 'add key cua dic la Contents(r, 1) và item cua dict là dic2
End If
Next

For r = 0 To UBound(ParentKeys) ' cho r chay tu 0 den phan tu cuoi cung cua mang keys cua dic
Set dic2 = dic.Item(ParentKeys(r)) 'goi dic2
ChildKeys = dic2.keys ' gan ChildKeys la mang keys cua dic2
WriteStr = ""
For r2 = 0 To dic2.Count - 1 'r2 chay tu 0 den phan tu cuoi cung cua mang keys cua dic2
WriteStr = WriteStr & Chr(10) & ChildKeys(r2) & " - " & Format(dic2.Item(ChildKeys(r2)), "#,###") & " Trd" 'Chr(10) de xuong dong, ChildKeys(r2) de lay gia tri key cua dic2, dic2.Item(ChildKeys(r2)) de lay gia tri item cua dic2
Next
WriteStr = Mid(WriteStr, 2) 'chi lay gia tri sau dáu cách và ký tu xuong dòng
Cells(r + 2, 2) = WriteStr 'gan ket qua vao excel
Next
 
Upvote 0
- Bài này dùng 1 Dic là được, cho nó 2 cột phụ trong mảng rồi xét.
- Kết quả cho vào 1 sheet mới bằng Insert Sheet nhìn thấy rườm rà, sao không tạo sẵn 1 sheet cho khỏe code. Ví dụ tạo 1 sheet đặt tên là GPE cũng đâu có bao lâu?
 

File đính kèm

  • Gop du lieu.xlsm
    44.8 KB · Đọc: 10
Upvote 0
- Bài này dùng 1 Dic là được, cho nó 2 cột phụ trong mảng rồi xét.
Bài này vốn dĩ là một bài hết sức gượng ép để dùng đít sần.
Có cỡ vài trăm khoá là dựng vài trăm cái đít sần.

- Kết quả cho vào 1 sheet mới bằng Insert Sheet nhìn thấy rườm rà, sao không tạo sẵn 1 sheet cho khỏe code. Ví dụ tạo 1 sheet đặt tên là GPE cũng đâu có bao lâu?
Vấn đề này nằm ngoài câu chuyện đít sần.
Vả lại, theo tôn chỉ GPE: "cái gì có thể nhờ code được bằng VBA thì không nên làm thủ công"
Rườm rà là việc của người code, không phải của người nhận code.
 
Upvote 0
- Bài này dùng 1 Dic là được, cho nó 2 cột phụ trong mảng rồi xét.
- Kết quả cho vào 1 sheet mới bằng Insert Sheet nhìn thấy rườm rà, sao không tạo sẵn 1 sheet cho khỏe code. Ví dụ tạo 1 sheet đặt tên là GPE cũng đâu có bao lâu?
Em cảm ơn anh ạ.
Bài đã được tự động gộp:

mình có chú thích từng câu lệnh hy vọng giúp bạn hiểu được phần nào. :)

For r = 1 To UBound(Contents, 1) ' r chay tu 1 toi phan tu cuoi cung cua mang Contents
If dic.Exists(Contents(r, 1)) Then 'kiem tra su ton tai giá tri Contents(r, 1) trong dic
Set dic2 = dic.Item(Contents(r, 1)) 'neu giá tri Contents(r, 1) dang co trong dic thi goi dict2
If dic2.Exists(Contents(r, 2)) Then 'kiem tra su ton tai giá tri Contents(r, 2) trong dic2
dic2.Item(Contents(r, 2)) = dic2.Item(Contents(r, 2)) + Contents(r, 3) ' dic2.Item(Contents(r, 2)) = dic2(Contents(r, 2)): neu giá tri Contents(r, 2) co trong dict2 thi cong gop vao item cua dict2
Else
dic2.Add Contents(r, 2), Contents(r, 3) ' neu giá tri Contents(r, 2) chua co trong dic2 thi them gia tri này vao dic2 voi item la Contents(r, 3)
End If

Else
Set dic2 = CreateObject("Scripting.Dictionary") 'neu gia tri Contents(r, 1) chua co trong dict thì tao dic2 moi.
dic2.CompareMode = vbTextCompare 'ko phan biet chu hoa va chu thuong
dic2.Add Contents(r, 2), Contents(r, 3) 'add key cua dic2 la Contents(r, 2) va item cua dic2 là Contents(r, 3)
dic.Add Contents(r, 1), dic2 'add key cua dic la Contents(r, 1) và item cua dict là dic2
End If
Next

For r = 0 To UBound(ParentKeys) ' cho r chay tu 0 den phan tu cuoi cung cua mang keys cua dic
Set dic2 = dic.Item(ParentKeys(r)) 'goi dic2
ChildKeys = dic2.keys ' gan ChildKeys la mang keys cua dic2
WriteStr = ""
For r2 = 0 To dic2.Count - 1 'r2 chay tu 0 den phan tu cuoi cung cua mang keys cua dic2
WriteStr = WriteStr & Chr(10) & ChildKeys(r2) & " - " & Format(dic2.Item(ChildKeys(r2)), "#,###") & " Trd" 'Chr(10) de xuong dong, ChildKeys(r2) de lay gia tri key cua dic2, dic2.Item(ChildKeys(r2)) de lay gia tri item cua dic2
Next
WriteStr = Mid(WriteStr, 2) 'chi lay gia tri sau dáu cách và ký tu xuong dòng
Cells(r + 2, 2) = WriteStr 'gan ket qua vao excel
Next
Cảm ơn sự trợ giúp rất chi tiết của bạn. Mình sẽ đọc để tham khảo !
 
Upvote 0
mình có chú thích từng câu lệnh hy vọng giúp bạn hiểu được phần nào. :)

For r = 1 To UBound(Contents, 1) ' r chay tu 1 toi phan tu cuoi cung cua mang Contents
If dic.Exists(Contents(r, 1)) Then 'kiem tra su ton tai giá tri Contents(r, 1) trong dic
Set dic2 = dic.Item(Contents(r, 1)) 'neu giá tri Contents(r, 1) dang co trong dic thi goi dict2
If dic2.Exists(Contents(r, 2)) Then 'kiem tra su ton tai giá tri Contents(r, 2) trong dic2
dic2.Item(Contents(r, 2)) = dic2.Item(Contents(r, 2)) + Contents(r, 3) ' dic2.Item(Contents(r, 2)) = dic2(Contents(r, 2)): neu giá tri Contents(r, 2) co trong dict2 thi cong gop vao item cua dict2
Else
dic2.Add Contents(r, 2), Contents(r, 3) ' neu giá tri Contents(r, 2) chua co trong dic2 thi them gia tri này vao dic2 voi item la Contents(r, 3)
End If

Else
Set dic2 = CreateObject("Scripting.Dictionary") 'neu gia tri Contents(r, 1) chua co trong dict thì tao dic2 moi.
dic2.CompareMode = vbTextCompare 'ko phan biet chu hoa va chu thuong
dic2.Add Contents(r, 2), Contents(r, 3) 'add key cua dic2 la Contents(r, 2) va item cua dic2 là Contents(r, 3)
dic.Add Contents(r, 1), dic2 'add key cua dic la Contents(r, 1) và item cua dict là dic2
End If
Next

For r = 0 To UBound(ParentKeys) ' cho r chay tu 0 den phan tu cuoi cung cua mang keys cua dic
Set dic2 = dic.Item(ParentKeys(r)) 'goi dic2
ChildKeys = dic2.keys ' gan ChildKeys la mang keys cua dic2
WriteStr = ""
For r2 = 0 To dic2.Count - 1 'r2 chay tu 0 den phan tu cuoi cung cua mang keys cua dic2
WriteStr = WriteStr & Chr(10) & ChildKeys(r2) & " - " & Format(dic2.Item(ChildKeys(r2)), "#,###") & " Trd" 'Chr(10) de xuong dong, ChildKeys(r2) de lay gia tri key cua dic2, dic2.Item(ChildKeys(r2)) de lay gia tri item cua dic2
Next
WriteStr = Mid(WriteStr, 2) 'chi lay gia tri sau dáu cách và ký tu xuong dòng
Cells(r + 2, 2) = WriteStr 'gan ket qua vao excel
Next
anh @đungtb2 ơi giải thích giúp em đoạn này vs ah:
Set dic2 = dic.Item(Contents(r, 1)) bình thường em chỉ thấy set dic =creatobject("............"). viết như thế có nghĩa là Dic2 bằng giá trị gì ah?
 
Upvote 0
Web KT

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

Back
Top Bottom