Cách 1...củ chuối đây, hihihi...xem file đính kèm nhé.Em chào các anh, chị . Em có ví dụ bên duói mong diễn đàn giúp em giải qyết vấn đề về dũ liệu trùng nhau.
Cách 1...củ chuối đây, hihihi...xem file đính kèm nhé.
Cảm on bạn, nhung bạn gủi lại cho mình Film vói, film trên bạn gủi bị lỗi ko mỏ dduocj.
Sub demso()
Dim arr, Darr As Variant, d As Object, i, j As Long
[e2:e60000].Clear
arr = [a2].Resize([a60000].End(3).Row, 2).Value
Darr = [d2].Resize([d60000].End(3).Row - 1, 2)
Set d = CreateObject("Scripting.Dictionary")
For i = 1 To UBound(Darr)
For j = 1 To UBound(arr)
If arr(j, 1) = Darr(i, 1) Then
If Not d.exists(arr(j, 1) & arr(j, 2)) Then
d.Add arr(j, 1) & arr(j, 2), ""
Darr(i, 2) = Darr(i, 2) + 1
End If
End If
Next j
Next i
[d2].Resize([d60000].End(3).Row - 1, 2) = Darr
End Sub
Cảm ơn bạn, nhưng bạn có thể giúp mình thêm là dư liệu ở sheets1 còn danh sách tên có sẵn ở sheets2 và là cột A. Bạn giúp mình nhé.
Sub demso()
Dim arr, Darr As Variant, d As Object, i, j As Long
[b2:b60000].Clear
arr = Sheet1.[a2].Resize(Sheet1.[a60000].End(3).Row, 2).Value
Darr = [a2].Resize([a60000].End(3).Row - 1, 2)
Set d = CreateObject("Scripting.Dictionary")
For i = 1 To UBound(Darr)
For j = 1 To UBound(arr)
If arr(j, 1) = Darr(i, 1) Then
If Not d.exists(arr(j, 1) & arr(j, 2)) Then
d.Add arr(j, 1) & arr(j, 2), ""
Darr(i, 2) = Darr(i, 2) + 1
End If
End If
Next j
Next i
[a2].Resize([a60000].End(3).Row - 1, 2) = Darr
End Sub
Function Dem(Rng1 As Range, Rng2 As Range, dK As String)
Dim i As Long, k As Long, mArr As Variant
Dim sArr1(), sArr2()
Dim Dic As Object
Set Dic = CreateObject("Scripting.dictionary")
sArr1 = Rng1.Value
sArr2 = Rng2.Value
For i = 1 To UBound(sArr1)
mArr = sArr1(i, 1) & sArr2(i, 1)
If Not Dic.exists(mArr) Then
Dic.Add mArr, ""
If mArr Like "*" & dK & "*" Then
k = k + 1
End If
End If
Next
If dK <> "" Then Dem = k
Set Dic = Nothing
End Function
Cảm ơn bạn, nhưng bạn có thể giúp mình thêm là dư liệu ở sheets1 còn danh sách tên có sẵn ở sheets2 và là cột A. Bạn giúp mình nhé.
Sub demso()
Dim arr, Darr As Variant, d As Object, i, j As Long
[b2:b60000].Clear
arr = Sheet1.[a2].Resize(Sheet1.[a60000].End(3).Row, 2).Value
Darr = [a2].Resize([a60000].End(3).Row - 1, 2)
Set d = CreateObject("Scripting.Dictionary")
For i = 1 To UBound(arr)
If Not d.exists(arr(i, 1) & arr(i, 2)) Then
d.Add arr(i, 1) & arr(i, 2), arr(i, 1)
End If
Next
For j = 1 To UBound(Darr)
For Each Key In d
If d.Item(Key) = Darr(j, 1) Then Darr(j, 2) = Darr(j, 2) + 1
Next
Next j
[a2].Resize([a60000].End(3).Row - 1, 2) = Darr
End Sub
Cảm ơn bạn, nhưng bạn có thể giúp mình thêm là dư liệu ở sheets1 còn danh sách tên có sẵn ở sheets2 và là cột A. Bạn giúp mình nhé.
=COUNT(1/FREQUENCY(IF(Sheet1!$A$2:$A$100=$A2,IF(Sheet1!$B$2:$B$100<>"",MATCH(Sheet1!$B$2:$B$100,Sheet1!$B$2:$B$100,0))),IF(Sheet1!$A$2:$A$100=$A2,IF(Sheet1!$B$2:$B$100<>"",MATCH(Sheet1!$B$2:$B$100,Sheet1!$B$2:$B$100,0)))))
Anh ạ, dữ liệu của em gần 100.000 bản ghi, vậy khi dùng công thức như của anh có được ko ạ?Công thức tại cell B2 của sheet2:
Bấm Ctrl + Shift + Enter để kết thúc rồi kéo fill xuốngMã:=COUNT(1/FREQUENCY(IF(Sheet1!$A$2:$A$100=$A2,IF(Sheet1!$B$2:$B$100<>"",MATCH(Sheet1!$B$2:$B$100,Sheet1!$B$2:$B$100,0))),IF(Sheet1!$A$2:$A$100=$A2,IF(Sheet1!$B$2:$B$100<>"",MATCH(Sheet1!$B$2:$B$100,Sheet1!$B$2:$B$100,0)))))
(Bài toán đếm duy nhất theo điều kiện có cả "đống" trên diễn đàn rồi)
Anh ạ, dữ liệu của em gần 100.000 bản ghi, vậy khi dùng công thức như của anh có được ko ạ?
Quăn file lên đi xem thế nào?Em chưa biết dùng cái đó, anh hướng dẫn em với, nhưng dữ liệu của e ở sheets gốc không được thay đổi, và cũng không copy dữ liệu sang sheets khác, vì nếu làm vậy file sẽ nặng.
Sub GetData1()
Dim cnn As Connection, rst As Recordset, s$
On Error GoTo Loi
Set cnn = New Connection
s = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ThisWorkbook.FullName & _
";Extended Properties=""Excel 12.0;HDR=NO"";"
cnn.Open s
Set rst = New Recordset
s = "SELECT Q.SoLuot FROM KetQua K LEFT JOIN (SELECT HoTen,COUNT(*) AS SoLuot FROM (SELECT DISTINCT (F1 & F2),F1 AS Hoten FROM Data) GROUP BY HoTen) Q ON K.F1=Q.HoTen"
rst.Open s, cnn
Range("E2").CopyFromRecordset rst
Loi:
If rst.State = adStateOpen Then rst.Close
Set rst = Nothing
If cnn.State = adStateOpen Then cnn.Close
Set rst = Nothing
End Sub
Sub CreateName()
Dim r As Range, s$
Sheet1.Activate
Set r = Sheet1.Range("A2", Range("B1000000").End(xlUp))
s = "=" & r.Address
ThisWorkbook.Names.Add "Data", s
Set r = Range("D2", Range("D1000000").End(xlUp))
s = "=" & r.Address
ThisWorkbook.Names.Add "KetQua", s
End Sub
Sub DeleteName()
With ThisWorkbook
.Names("Data").Delete
.Names("KetQua").Delete
End With
End Sub
Sub Main()
CreateName
GetData1
DeleteName
End Sub
Chỉnh lại code #6, tôi nghĩ là nó sẻ nhanh hơn
Mã:Sub demso() Dim arr, Darr As Variant, d As Object, i, j As Long [b2:b60000].Clear arr = Sheet1.[a2].Resize(Sheet1.[a60000].End(3).Row, 2).Value Darr = [a2].Resize([a60000].End(3).Row - 1, 2) Set d = CreateObject("Scripting.Dictionary") For i = 1 To UBound(arr) If Not d.exists([COLOR=#ff0000]arr(i, 1) & arr(i, 2)[/COLOR]) Then d.Add [COLOR=#ff0000]arr(i, 1) & arr(i, 2)[/COLOR], arr(i, 1) End If Next For j = 1 To UBound(Darr) For Each Key In d If d.Item(Key) = Darr(j, 1) Then Darr(j, 2) = Darr(j, 2) + 1 Next Next j [a2].Resize([a60000].End(3).Row - 1, 2) = Darr End Sub
Chẳng thấy chạy gì ráo! Cho file lên để minh họa đi bạn à!Một cách củ chuối nữa (không biết có to bằng mấy củ chuối trên không?)...
Kết quả chính xác luôn anh ạ!Một cách củ chuối nữa (không biết có to bằng mấy củ chuối trên không?)...
---------------------------------------------------------------------------------
(chọn tools - reference - microsoft activex object 2.x)
Bài này sao tự nhiên dùng ADO chi vậy trời?
Bài này nếu dùng list có sẵn như chủ topic yêu cầu e rằng không thể làm được. Vì nếu trùng tên ở cột A mà khác ngày ở cột B thì bước kế tiếp là làm gì? Chịu...Cũng là một cách làm thôi! Có điều:
- ADO thích hợp đối với việc lấy dữ liệu trên file đóng
- Với file hiện hành mà dùng ADO thì e rằng tốc độ tính toán vẫn còn là vấn đề phải bàn lại
--------------------
Hải thử bài này (với dữ liệu bài 17) xem thế nào?
Hình như ADO chỉ chạy với 65k dòng thôi bác ạ, bây giờ em mới để ý. Nếu nhiều hơn 65k chắc phải chia ra thành từng khối rồi load nhiều lần. Không biết phiên bản mới hơn có khắc phục được không?Đã tải file ở bài 14, giả lập dữ liệu 100,000 dòng và chẳng thấy chạy gì ráo
Mời bạn thí nghiệm ADO với dữ liệu giả lập trong file đính kèm dưới đây xem ra kết quả trong bao lâu
Thì đã bảo là củ chuối mà anh, còn dùng 2 dic với array thì không khó, hết 1.8s.Bài này sao tự nhiên dùng ADO chi vậy trời? Có lạm dụng quá chăng?
Dùng Dic mình thấy cũng thuận tiện đơn giản mà lị. Kỳ quá quá.
Anh ơi, xem lai công thức giúp e với, e làm ki đc.Công thức tại cell B2 của sheet2:
Bấm Ctrl + Shift + Enter để kết thúc rồi kéo fill xuốngMã:=COUNT(1/FREQUENCY(IF(Sheet1!$A$2:$A$100=$A2,IF(Sheet1!$B$2:$B$100<>"",MATCH(Sheet1!$B$2:$B$100,Sheet1!$B$2:$B$100,0))),IF(Sheet1!$A$2:$A$100=$A2,IF(Sheet1!$B$2:$B$100<>"",MATCH(Sheet1!$B$2:$B$100,Sheet1!$B$2:$B$100,0)))))
(Bài toán đếm duy nhất theo điều kiện có cả "đống" trên diễn đàn rồi)
Chắc là đúng anh ah, đợt trước em thử 80.000 nghìn dòng, ko thấy chạy, cho số dòng nhỏ đi thì lại đượcHình như ADO chỉ chạy với 65k dòng thôi bác ạ, bây giờ em mới để ý. Nếu nhiều hơn 65k chắc phải chia ra thành từng khối rồi load nhiều lần. Không biết phiên bản mới hơn có khắc phục được không?
Bạn có cách nào nhanh hơn chỉ mình với, ko dùng công thức kia cũng đc nhưng ma no chạy lâu lắm, cứ ngồi đợi dài cổ ra.Chắc là đúng anh ah, đợt trước em thử 80.000 nghìn dòng, ko thấy chạy, cho số dòng nhỏ đi thì lại được
Bạn có cách nào nhanh hơn chỉ mình với, ko dùng công thức kia cũng đc nhưng ma no chạy lâu lắm, cứ ngồi đợi dài cổ ra.