FPT_online
Thành viên hoạt động
![](/diendan/data/PhoToDanhHieu/gold.gif)
![](/diendan/data/PhoToDanhHieu/gold.gif)
![](/diendan/data/PhoToDanhHieu/gold.gif)
- Tham gia
- 27/10/13
- Bài viết
- 133
- Được thích
- 16
Cách đơn giản là copy dữ liệu sheet2 nối vào sheet1. Xong Remove Duplicate là được rồiMọi người cho em hỏi em muốn dùng dictionary để lọc các mã không trùng từ sheet khác, em có ghi trong vd rồi mong mọi người chỉ giúp
Đây chỉ là ví dụ để em hiểu thêm về Dictionary thôi ạ, nên em muốn hỏi nếu làm thì sẽ làm như thế nào đó ạCách đơn giản là copy dữ liệu sheet2 nối vào sheet1. Xong Remove Duplicate là được rồi
Bước 1> Dùng vòng lập nạp dữ liệu sheet1 vào Dictionary, với key là giá trị nối chuỗi từ cột B và C <--- Có được từ điểnĐây chỉ là ví dụ để em hiểu thêm về Dictionary thôi ạ, nên em muốn hỏi nếu làm thì sẽ làm như thế nào đó ạ
Vâng để em làm thửBước 1> Dùng vòng lập nạp dữ liệu sheet1 vào Dictionary, với key là giá trị nối chuỗi từ cột B và C <--- Có được từ điển
Bước 2> Dùng vòng lập duyệt dữ liệu ở sheet2, cũng nối chuỗi cột B và C lại rồi mang đi tra vào từ điển, nếu chưa có thì thêm vào
Đại khái vậy
Mọi người cho em hỏi em muốn dùng dictionary để lọc các mã không trùng từ sheet khác, em có ghi trong vd rồi mong mọi người chỉ giúp
Sub gpe()
Dim Arr_sheet1, Arr_sheet2
Dim i&, tmp, sResult$
Arr_sheet2 = Sheet2.Range("A1").CurrentRegion
Arr_sheet1 = Sheet1.Range("A1").CurrentRegion
With CreateObject("Scripting.dictionary")
For i = 1 To UBound(Arr_sheet2, 1)
tmp = Arr_sheet2(i, 2) & Chr(0) & Arr_sheet2(i, 3)
If Len(tmp) Then If Not .Exists(tmp) Then .Add tmp, ""
Next
For i = 1 To UBound(Arr_sheet1, 1)
tmp = Arr_sheet1(i, 2) & Chr(0) & Arr_sheet1(i, 3)
If Len(tmp) Then If Not .Exists(tmp) Then sResult = sResult & Replace(tmp, Chr(0), vbTab) & vbCrLf
Next
End With
If Len(sResult) Then MsgBox sResult
End Sub
Cái này mình chạy thử thấy kết quả ra chưa đủLâu rồi không viết code, bạn test thử xem ntn
Mã:Sub gpe() Dim Arr_sheet1, Arr_sheet2 Dim i&, tmp, sResult$ Arr_sheet2 = Sheet2.Range("A1").CurrentRegion Arr_sheet1 = Sheet1.Range("A1").CurrentRegion With CreateObject("Scripting.dictionary") For i = 1 To UBound(Arr_sheet2, 1) tmp = Arr_sheet2(i, 2) & Chr(0) & Arr_sheet2(i, 3) If Len(tmp) Then If Not .Exists(tmp) Then .Add tmp, "" Next For i = 1 To UBound(Arr_sheet1, 1) tmp = Arr_sheet1(i, 2) & Chr(0) & Arr_sheet1(i, 3) If Len(tmp) Then If Not .Exists(tmp) Then sResult = sResult & Replace(tmp, Chr(0), vbTab) & vbCrLf Next End With If Len(sResult) Then MsgBox sResult End Sub
Bước 1> Dùng vòng lập nạp dữ liệu sheet1 vào Dictionary, với key là giá trị nối chuỗi từ cột B và C <--- Có được từ điển
Bước 2> Dùng vòng lập duyệt dữ liệu ở sheet2, cũng nối chuỗi cột B và C lại rồi mang đi tra vào từ điển, nếu chưa có thì thêm vào
Đại khái vậy
Sub loc()
Dim dic As Object
Dim arr(), rng(), rng2(), itemp As String, itemp1 As String
Dim lr As Long, lr2 As Long, i As Long, j As Long, k As Long
Set dic = CreateObject("Scripting.dictionary")
With Sheet1
lr = .Range("B" & Rows.Count).End(xlUp).Row
rng = .Range("B2:D" & lr)
End With
With Sheet2
lr2 = .Range("B" & Rows.Count).End(xlUp).Row
rng2 = .Range("B2:D" & lr2)
End With
ReDim arr(1 To UBound(rng, 1), 1 To 4)
For i = 1 To UBound(rng, 1)
itemp = rng(i, 1)
If itemp <> "" And Not dic.Exists(itemp) Then
k = k + 1
dic.Add itemp, k
arr(k, 2) = rng(i, 1)
End If
Next i
For i = 1 To UBound(rng2, 1)
itemp1 = rng2(i, 1)
If itemp1 <> "" And Not dic.Exists(itemp) Then
j = j + 1
dic.Add itemp, j
arr(j, 2) = rng2(i, 1)
End If
Next i
With Sheet3
.Range("A2").Resize(k + j, 4) = arr
End With
End Sub
if len(sKey)>0 then
If dic.exists(sKey)=false then
Mình vẫn chưa hiểu rõ mong bạn sửa code luôn để mình học hỏi vớiBài #8:
- Bạn chỉ lấy dữ liệu ở cột B nên chỉ cần xét cột B thôi, không cânf xét B2: D & lr.
Chỗ này cần bẫy lỗi gán range vào array khi chỉ có 1 cell (lr=2), và khi lr<2 (không có dữ liệu).
- Do hai vòng lặp độc lập nên có thể dùng lại biến itemp (không cần thêm biến itemp2).
- Xét itemp khác rỗng thì ngắt riêng rồi mới xét có trong dic hay không, tức là không nên dùng And. Có thể đặt tên biến là sKey chẳng hạn.
- Ở vòng lặp thứ hai, bạn muốn lấy tiếp kết quả vào mảng arr thì thay j=j+1 bằng k=k+1.Mã:if len(sKey)>0 then If dic.exists(sKey)=false then
- Gán kết quả xuống sheet phải kiểm tra có kết quả có hay không (k>0), nếu không sẽ lỗi ở resize(rows, columns) với rows và columns luôn >0.
. Bạn cần đọc thêm lý thuyết về array rồi mới đọc tiếp bài Dictionary. Bạn tìm chủ để của mình viết mà đọc, hai bài đó khá chi tiết, có cả một số chỗ lưu ý quan trọng.Mình vẫn chưa hiểu rõ mong bạn sửa code luôn để mình học hỏi với
Bạn nói như vậy ngừoi mới vào đây sẽ hiểu lầm là Dictionary có liên quan đến mảng.. Bạn cần đọc thêm lý thuyết về array rồi mới đọc tiếp bài Dictionary. Bạn tìm chủ để của mình viết mà đọc, hai bài đó khá chi tiết, có cả một số chỗ lưu ý quan trọng.
Sub loc()
Dim lr As Long, rng(), arr(1 To 1000, 1 To 4), dic As Object, tmp As String, k As Long, i As Long
With Sheet1
lr = .Range("B" & Rows.Count).End(xlUp).Row
rng = .Range("B2:D" & lr)
End With
With Sheet2
lr2 = .Range("B" & Rows.Count).End(xlUp).Row
rng2 = .Range("B2:D" & lr)
Set dic = CreateObject("Scripting.dictionary")
For i = 1 To UBound(rng, 1)
tmp = rng(i, 1) & rng(i, 2)
If tmp <> "" And Not dic.Exists(tmp) Then
k = k + 1
dic.Add tmp, k
arr(k, 1) = k
arr(k, 2) = rng(i, 1)
arr(k, 3) = rng(i, 2)
End If
Next i
For i = 1 To UBound(rng2, 1)
tmp = rng2(i, 1) & rng2(i, 2)
If tmp <> "" And Not dic.Exists(tmp) Then
k = k + 1
dic.Add tmp, k
arr(k, 1) = k
arr(k, 2) = rng2(i, 1)
arr(k, 3) = rng2(i, 2)
End If
Next i
End With
With Sheet3
.Range("A3").Resize(k, 3) = arr
End With
End Sub
Chưa đúng, bạn còn nhầm chỗ này:Với bài này em viết như này thì đã ra đúng kết quả, nhưng mọi người cho em hỏi có cách viết nào ngắn gọn hơn không ạ, Em cám ơnMã:Sub loc() Dim lr As Long, rng(), arr(1 To 1000, 1 To 4), dic As Object, tmp As String, k As Long, i As Long With Sheet1 lr = .Range("B" & Rows.Count).End(xlUp).Row rng = .Range("B2:D" & lr) End With With Sheet2 lr2 = .Range("B" & Rows.Count).End(xlUp).Row rng2 = .Range("B2:D" & lr) Set dic = CreateObject("Scripting.dictionary") For i = 1 To UBound(rng, 1) tmp = rng(i, 1) & rng(i, 2) If tmp <> "" And Not dic.Exists(tmp) Then k = k + 1 dic.Add tmp, k arr(k, 1) = k arr(k, 2) = rng(i, 1) arr(k, 3) = rng(i, 2) End If Next i For i = 1 To UBound(rng2, 1) tmp = rng2(i, 1) & rng2(i, 2) If tmp <> "" And Not dic.Exists(tmp) Then k = k + 1 dic.Add tmp, k arr(k, 1) = k arr(k, 2) = rng2(i, 1) arr(k, 3) = rng2(i, 2) End If Next i End With With Sheet3 .Range("A3").Resize(k, 3) = arr End With End Sub
lr2 = .Range("B" & Rows.Count).End(xlUp).Row
rng2 = .Range("B2:D" & lr)
Vâng, số dòng 2 bảng linh động khác nhau anh ạ, anh chỉ em cách viết với 1 vòng lặp For với. em đang cần để học hỏiChưa đúng, bạn còn nhầm chỗ này:
phải là lr2Mã:lr2 = .Range("B" & Rows.Count).End(xlUp).Row rng2 = .Range("B2:D" & lr)
Dạng bài này phải viết thế, muốn ngắn nữa thì viết 1 vòng FOR thôi, nếu số dòng 2 bảng bằng nhau (khẳng định) thì nhẹ nhàng, nếu khác thì hơi....linh tinh, nói chung cũng chẳng ngắn bi nhiêu (chỉ có nhìn thấy 1 vòng FOR cho nó có vẻ "zồ" một tý tẹo. Híc)
Thân
Viết 1 vòng chơi vui thôi, chứ chẳng rút bao nhiêuVâng, số dòng 2 bảng linh động khác nhau anh ạ, anh chỉ em cách viết với 1 vòng lặp For với. em đang cần để học hỏi
Public Sub TeoTeo()
Dim Vung1, Vung2, Imax, I, K, Kq, Dic, Tam1, Tam2
Set Dic = CreateObject("Scripting.dictionary")
Vung1 = Sheets("sheet1").Range(Sheets("sheet1").[B2], Sheets("sheet1").[B5000].End(xlUp)).Resize(, 2)
Vung2 = Sheets("sheet2").Range(Sheets("sheet2").[B2], Sheets("sheet2").[B5000].End(xlUp)).Resize(, 2)
Imax = IIf(UBound(Vung1) >= UBound(Vung2), UBound(Vung1), UBound(Vung2))
ReDim Kq(1 To UBound(Vung1) + UBound(Vung2), 1 To 3)
For I = 1 To Imax
If I <= UBound(Vung1) Then
If Vung1(I, 1) <> "" Then
Tam1 = Vung1(I, 1) & "@" & Vung1(I, 2)
If Not Dic.Exists(Tam1) Then
K = K + 1
Dic.Add Tam1, K
Kq(K, 1) = K: Kq(K, 2) = Vung1(I, 1): Kq(K, 3) = Vung1(I, 2)
End If
End If
End If
If I <= UBound(Vung2) Then
If Vung2(I, 1) <> "" Then
Tam2 = Vung2(I, 1) & "@" & Vung2(I, 2)
If Not Dic.Exists(Tam2) Then
K = K + 1
Dic.Add Tam2, K
Kq(K, 1) = K: Kq(K, 2) = Vung2(I, 1): Kq(K, 3) = Vung2(I, 2)
End If
End If
End If
Next I
Sheets("sheet3").[E3].Resize(K, 3) = Kq
End Sub
Dạ, em cảm ơn anh nhiều. Em sẽ xem và học hỏi thêmViết 1 vòng chơi vui thôi, chứ chẳng rút bao nhiêu
Cẩn thận với việc ghép dữ liệu rồi so sánh, khi không nắm chắc dạng dữ liệu nên chèn 1 "thằng em" hơi "là lạ" vào giữa tụi nó cho chắc cú
Thân
Mã:Public Sub TeoTeo() Dim Vung1, Vung2, Imax, I, K, Kq, Dic, Tam1, Tam2 Set Dic = CreateObject("Scripting.dictionary") Vung1 = Sheets("sheet1").Range(Sheets("sheet1").[B2], Sheets("sheet1").[B5000].End(xlUp)).Resize(, 2) Vung2 = Sheets("sheet2").Range(Sheets("sheet2").[B2], Sheets("sheet2").[B5000].End(xlUp)).Resize(, 2) Imax = IIf(UBound(Vung1) >= UBound(Vung2), UBound(Vung1), UBound(Vung2)) ReDim Kq(1 To UBound(Vung1) + UBound(Vung2), 1 To 3) For I = 1 To Imax If I <= UBound(Vung1) Then If Vung1(I, 1) <> "" Then Tam1 = Vung1(I, 1) & "@" & Vung1(I, 2) If Not Dic.Exists(Tam1) Then K = K + 1 Dic.Add Tam1, K Kq(K, 1) = K: Kq(K, 2) = Vung1(I, 1): Kq(K, 3) = Vung1(I, 2) End If End If End If If I <= UBound(Vung2) Then If Vung2(I, 1) <> "" Then Tam2 = Vung2(I, 1) & "@" & Vung2(I, 2) If Not Dic.Exists(Tam2) Then K = K + 1 Dic.Add Tam2, K Kq(K, 1) = K: Kq(K, 2) = Vung2(I, 1): Kq(K, 3) = Vung2(I, 2) End If End If End If Next I Sheets("sheet3").[E3].Resize(K, 3) = Kq End Sub
Viết 1 vòng chơi vui thôi, chứ chẳng rút bao nhiêu
Cẩn thận với việc ghép dữ liệu rồi so sánh, khi không nắm chắc dạng dữ liệu nên chèn 1 "thằng em" hơi "là lạ" vào giữa tụi nó cho chắc cú
Thân
Mã:Public Sub TeoTeo() Dim Vung1, Vung2, Imax, I, K, Kq, Dic, Tam1, Tam2 Set Dic = CreateObject("Scripting.dictionary") Vung1 = Sheets("sheet1").Range(Sheets("sheet1").[B2], Sheets("sheet1").[B5000].End(xlUp)).Resize(, 2) Vung2 = Sheets("sheet2").Range(Sheets("sheet2").[B2], Sheets("sheet2").[B5000].End(xlUp)).Resize(, 2) Imax = IIf(UBound(Vung1) >= UBound(Vung2), UBound(Vung1), UBound(Vung2)) ReDim Kq(1 To UBound(Vung1) + UBound(Vung2), 1 To 3) For I = 1 To Imax If I <= UBound(Vung1) Then If Vung1(I, 1) <> "" Then Tam1 = Vung1(I, 1) & "@" & Vung1(I, 2) If Not Dic.Exists(Tam1) Then K = K + 1 Dic.Add Tam1, K Kq(K, 1) = K: Kq(K, 2) = Vung1(I, 1): Kq(K, 3) = Vung1(I, 2) End If End If End If If I <= UBound(Vung2) Then If Vung2(I, 1) <> "" Then Tam2 = Vung2(I, 1) & "@" & Vung2(I, 2) If Not Dic.Exists(Tam2) Then K = K + 1 Dic.Add Tam2, K Kq(K, 1) = K: Kq(K, 2) = Vung2(I, 1): Kq(K, 3) = Vung2(I, 2) End If End If End If Next I Sheets("sheet3").[E3].Resize(K, 3) = Kq End Sub
' trong vòng lặp
NhetVaoDich Dic, Vung1, Kq, I, K
NhetVaoDich Dic, Vung2, Kq, I, K
...
Sub NhetVaoDich(byVal Dic As Object, byVal Vung As Variant, byVal Kq As Variant, byVal I As Long, byRef K As Long)
Dim Tam As String
If I > UBound(Vung) Then Exit Sub
If Vung(I, 1) <> "" Then
Tam = Vung(I, 1) & "@" & Vung(I, 2)
If Not Dic.Exists(Tam) Then
K = K + 1
Dic.Add Tam, K
Kq(K, 1) = K: Kq(K, 2) = Vung(I, 1): Kq(K, 3) = Vung(I, 2)
End If
End If
End Sub