Lequocvan
Thành viên thường trực
A | B | C | D | E |
1 | l1c2 | l1c3 | l1c4 | l1c5 |
2 | l2c2 | l2c3 | l2c4 | l2c5 |
1 | a | b | c | e |
5 | 01 | 412 | 8543 | 2198 |
8 | 102 | 731 | 4932 |
A | B | C | D | E |
1 | l1c2 | l1c3 | l1c4 | l1c5 |
2 | l2c2 | l2c3 | l2c4 | l2c5 |
1 | a | b | c | e |
5 | 01 | 412 | 8543 | 2198 |
8 | 102 | 731 | 4932 |
Dùng WorksheetFunction.Countif() = 1 là điều kiện để add range cần xóa chứ không phải tạo cột phụ bạn à.Mình có thói quen khi giải bài là mặc định làm việc với data lớn.
Nếu dùng COUNTIF thì phải dùng cột phụ?
Trường hợp này là chủ thớt muốn thực tập dùng dictionary thôi.
Anh cho ví dụ để các thành viên học hỏi thêm anh nhé.Không dùng hàm chỉ dùng thuật toán vẫn chạy được 1 vòng lặp với bài này.
Nếu cột A là giá trị.Không dùng hàm chỉ dùng thuật toán vẫn chạy được 1 vòng lặp với bài này.Nhưng có khả năng kết quả không theo thứ tự.
Option Explicit
Sub delete()
Dim rng As String
rng = Range("A1:A" & Cells(Rows.Count, "A").End(xlUp).Row).Address
With Range(rng)
.Value = Evaluate("=" & rng & "/(INDEX(COUNTIF(" & rng & "," & rng & "),)>1)")
.SpecialCells(xlCellTypeConstants, xlErrors).EntireRow.delete
End With
End Sub
Đó chỉ là lý luận của bạn thôi.Bài trên làm sai rồi.
Với hình bài #1 thì sau khi xóa sẽ còn hai dòng có giá trị 1.
View attachment 287374
Hic, cách bác dùng rất là ấn tượng về mặt hình ảnh trong bộ môn giải phẫu học, có thể hình dung được cái logic biến đổi thế nào sau chu trình này.lô gic từ đầu vào đi qua đầu ra
Bạn có học qua ngành Y?Hic, cách bác dùng rất là ấn tượng về mặt hình ảnh trong bộ môn giải phẫu học, có thể hình dung được cái logic biến đổi thế nào sau chu trình này.
Chân chất Dict 2 vòng lặp.Nếu cột A là giá trị.
Không dùng cột phụ, đồng thời không dùng vòng lặp, code này tốc độ có lẽ tương đương dùng dic:
Thứ tự không đổi. Chỉ có vấn đề là nếu cột A là công thức thì sẽ bị mất
Sub XoaDuyNhat()
Dim LastR As Long, Arr(), Dict1, Dict2
LastR = Sheet1.Cells(10000, 1).End(xlUp).Row
Set Dict1 = CreateObject("Scripting.Dictionary")
Set Dict2 = CreateObject("Scripting.Dictionary")
Arr = Sheet1.Range("A2:A" & LastR).Value
For i = 1 To UBound(Arr, 1)
If Dict1.exists(Arr(i, 1)) Then
Dict1.Remove Arr(i, 1)
Dict2.Add Arr(i, 1), i
Else
If Not Dict2.exists(Arr(i, 1)) Then Dict1.Add Arr(i, 1), i
End If
Next
For i = LastR To 2 Step -1
If Dict2.exists(Sheet1.Cells(i, 1).Value) Then
Sheet1.Cells(i, 1).EntireRow.Delete
End If
Next
End Sub
Dict này nhanh gấp từ 80 đến 90 lần code bebo. Test với 10 ngàn dòng và 10 cộtNếu cột A là giá trị.
code này tốc độ có lẽ tương đương dùng dic:
Sub XoaDuyNhat()
Dim LastR As Long, Arr(), Dict1, Dict2, ResArr(), k As Long
LastR = Sheet1.Cells(100000, 1).End(xlUp).Row
Set Dict1 = CreateObject("Scripting.Dictionary")
Set Dict2 = CreateObject("Scripting.Dictionary")
Arr = Sheet1.Range("A2:j" & LastR).Value
ReDim ResArr(1 To UBound(Arr, 1), 1 To 10)
t = Timer
For i = 1 To UBound(Arr, 1)
If Dict1.exists(Arr(i, 1)) Then
Dict1.Remove Arr(i, 1)
Dict2.Item(Arr(i, 1)) = i
Else
If Not Dict2.exists(Arr(i, 1)) Then Dict1.Add Arr(i, 1), i
End If
Next
For i = 1 To UBound(Arr, 1)
If Dict2.exists(Arr(i, 1)) Then
k = k + 1
For j = 1 To 10
ResArr(k, j) = Arr(i, j)
Next j
End If
Next
If k > 0 Then
Sheet1.Range("A2:j" & LastR).Clear
Sheet1.Range("A2").Resize(k, 10).Value = ResArr
End If
Set Dict1 = Nothing: Set Dict2 = Nothing
Sheet1.Cells(1, 12) = Timer - t
End Sub
Có điều chắc chắn là Clear còn đỡ hơn ClearContents.Dùng .Clear sẽ làm bảng tính phình dung lượng to đùng.
Vụ này em có đề cập một lần lâu rồi, và hầu như không ai biết.
.ClearContents với =“” thì sao anh?Ngược lại anh nhé.
Anh cứ thử nghiệm các kiểu đi sẽ thấy.
Dùng mảng gán kết quả đồng thời xóa dữ liệuDùng dictionary có thể làm được việc: Tìm ở cột A, khi thấy giá trị duy nhất thì xoá cả dòng hoặc xoá range tương ứng không ah?
A B C D E 1 l1c2 l1c3 l1c4 l1c5 2 l2c2 l2c3 l2c4 l2c5 1 a b c e 5 01 412 8543 2198 8 102 731 4932
Sub ABC()
Dim arr(), res(), Dic As Object, sRow&, sCol&, i&, k&, ik&, j&, key$
Set Dic = CreateObject("Scripting.Dictionary")
arr = Range("A2:E" & Range("A" & Rows.Count).End(xlUp).Row).Value
sRow = UBound(arr): sCol = UBound(arr, 2)
ReDim res(1 To sRow, 1 To sCol)
For i = 1 To sRow
If Not Dic.exists(arr(i, 1)) Then
Dic.Add arr(i, 1), i
Else
key = "|" & arr(i, 1)
If Not Dic.exists(key) Then
Dic.Add key, Empty
ik = Dic(arr(i, 1))
k = k + 1
For j = 1 To sCol
res(k, j) = arr(ik, j)
Next j
End If
k = k + 1
For j = 1 To sCol
res(k, j) = arr(i, j)
Next j
End If
Next
Range("A2").Resize(sRow, sCol) = res
End Sub
Mình thì hiểu đơn giản là Clear bao gồm xóa dữ liệu và xóa cả định dạng. ClearContents chỉ xóa dữ liệu, để lại định dạng. Chính định dạng không dữ liệu mới làm nặng file.Ngược lại anh nhé.
Mình thì hiểu đơn giản là Clear bao gồm xóa dữ liệu và xóa cả định dạng. ClearContents chỉ xóa dữ liệu, để lại định dạng. Chính định dạng không dữ liệu mới làm nặng file
Thật ra khi làm thật, kết quả là dữ liệu qua chỉnh sửa, mình sẽ dùng ClearContents để khỏi mất công định dạng lại, nhất là ngày tháng. Số thì kệ nó. Khung thì không có.Mà thôi kệ anh.