Xóa dữ liệu trùng bằng VBA

Tham gia ngày
23 Tháng mười hai 2015
Bài viết
145
Được thích
102
Điểm
180
Tuổi
27
Nơi ở
Hồ Chí Minh
Chào cả nhà, mình có một file như đính kèm. Dữ liệu mới được thêm vào liên tục hàng ngày, tuy nhiên sẽ có nhiều trường hợp hóa đơn được thêm mới bị trùng số với hóa đơn từ ngày trước đó (Mình dùng conditional formatting để bôi đỏ những hóa đơn này). Giờ mình muốn dùng VBA để xóa các dòng hóa đơn trùng cũ, giữ lại các dòng mới. Tuy nhiên, các ghi chú (remark) thì được cập nhật từ hóa đơn cũ vào hóa đơn mới.
Yêu cầu là trong quá trình chạy VBA không tạo thêm dòng mới, và code gọn nhẹ vì dữ liệu của mình khá lớn (>10000 dòng), mình dùng 2 vòng lặp for...next... thì ra kết quả nhưng tốc độ chạy rất chậm. Mong mọi người giúp đỡ.
 

File đính kèm

excel_lv1.5

Thành viên tiêu biểu
Tham gia ngày
20 Tháng mười 2017
Bài viết
753
Được thích
1,303
Điểm
360
Chào cả nhà, mình có một file như đính kèm. Dữ liệu mới được thêm vào liên tục hàng ngày, tuy nhiên sẽ có nhiều trường hợp hóa đơn được thêm mới bị trùng số với hóa đơn từ ngày trước đó (Mình dùng conditional formatting để bôi đỏ những hóa đơn này). Giờ mình muốn dùng VBA để xóa các dòng hóa đơn trùng cũ, giữ lại các dòng mới. Tuy nhiên, các ghi chú (remark) thì được cập nhật từ hóa đơn cũ vào hóa đơn mới.
Yêu cầu là trong quá trình chạy VBA không tạo thêm dòng mới, và code gọn nhẹ vì dữ liệu của mình khá lớn (>10000 dòng), mình dùng 2 vòng lặp for...next... thì ra kết quả nhưng tốc độ chạy rất chậm. Mong mọi người giúp đỡ.
Mấy bài tổng hợp dữ liệu mà dùng VBA như cực hình, ngay cả ADO, DAO cũng vậy, thử dùng power pivot xem dữ liệu nhiều bao nhiêu cũng chẳng sợ, thay đổi dữ liệu bấm refresh là được
 

File đính kèm

Tham gia ngày
23 Tháng mười hai 2015
Bài viết
145
Được thích
102
Điểm
180
Tuổi
27
Nơi ở
Hồ Chí Minh
Sao mình không gửi cái này lên..


Hóa đơn mới có không? Nếu có thì có giữ lại không?
Có cả những hóa đơn không trùng nha bạn, những hóa đơn đó mình giữ nguyên. Code của mình tương tự như bên dưới.

Mã:
Sub test()
Dim i, j, r As Integer
r = Cells(4, 1).End(xlDown).row
For i = 4 To r
    For j = i + 1 To r
        If Cells(i, 1) = Cells(j, 1) Then
            Cells(j, 3) = Cells(i, 3)
            Cells(i, 1).EntireRow.Delete
            i = i - 1
            j = j - 1
            r = r - 1
        End If
    Next j
Next i
End Sub
 
Tham gia ngày
23 Tháng mười hai 2015
Bài viết
145
Được thích
102
Điểm
180
Tuổi
27
Nơi ở
Hồ Chí Minh

befaint

|||||||||||||
Tham gia ngày
6 Tháng một 2011
Bài viết
10,030
Được thích
11,798
Điểm
1,560
Làm được nhưng không bao giờ nên làm như vậy bạn.
Lý do: Nguyên tắc dữ liệu đầu vào như nào thì phải luôn luôn lưu trữ lại để còn biết lịch sử của nó, biết cái gì thay đổi, thêm mới.

Bạn chỉ cần ghi vào Sheet mới là được rồi.
 
Tham gia ngày
23 Tháng mười hai 2015
Bài viết
145
Được thích
102
Điểm
180
Tuổi
27
Nơi ở
Hồ Chí Minh
Làm được nhưng không bao giờ nên làm như vậy bạn.
Lý do: Nguyên tắc dữ liệu đầu vào như nào thì phải luôn luôn lưu trữ lại để còn biết lịch sử của nó, biết cái gì thay đổi, thêm mới.

Bạn chỉ cần ghi vào Sheet mới là được rồi.
À, tại những hóa đơn trùng kia bản chất là hóa đơn cũ đã được cập nhật số liệu trên hệ thống, nên tại thời điểm được cập nhật thì các hóa đơn cũ với số liệu cũ đã không còn trên system nữa rồi. Những cái remark kia là mình ghi bằng tay cho từng hóa đơn để tiện follow, nên muốn lấy lại, còn hóa đơn cũ thì xóa đi tại không còn giá trị sử dụng á.
 

befaint

|||||||||||||
Tham gia ngày
6 Tháng một 2011
Bài viết
10,030
Được thích
11,798
Điểm
1,560
không còn giá trị sử dụng
Bạn xóa dòng này
ws.Range(scll_target).Resize(max_row, num_cols).ClearContents

Dòng này:
If ii > 0 Then ws.Range(scll_target).Resize(ii, num_cols).Value = result
đổi thành:
ws.Range(scol_ref & start_row).Resize(last_row, num_cols).Value = result
 
Tham gia ngày
23 Tháng mười hai 2015
Bài viết
145
Được thích
102
Điểm
180
Tuổi
27
Nơi ở
Hồ Chí Minh
Bạn xóa dòng này
ws.Range(scll_target).Resize(max_row, num_cols).ClearContents

Dòng này:
If ii > 0 Then ws.Range(scll_target).Resize(ii, num_cols).Value = result
đổi thành:
ws.Range(scol_ref & start_row).Resize(last_row, num_cols).Value = result
Đa tạ đa tạ. Code của bạn hay quá, dễ tùy biến nữa.
 

syquyen1987

Thành viên chính thức
Tham gia ngày
8 Tháng bảy 2018
Bài viết
81
Được thích
32
Điểm
170
Tuổi
32

[QUOTE="befaint, post: 991781, member: 429354"]
[COLOR=rgb(255, 255, 255)]nha nha 1 2 3 5[/COLOR]
[/QUOTE]
Anh cho em xin hỏi, bài này cũng giải đc object dictionary như cấu trúc code của anh phải không ạ, em thấy anh khai báo object collection ha... gì đó thấy lạ lạ quá ạ

Bạn xóa dòng này
ws.Range(scll_target).Resize(max_row, num_cols).ClearContents

Dòng này:
If ii > 0 Then ws.Range(scll_target).Resize(ii, num_cols).Value = result
đổi thành:
ws.Range(scol_ref & start_row).Resize(last_row, num_cols).Value = result
Anh cho em xin hỏi, bài này cũng giải đc object dictionary như cấu trúc code của anh phải không ạ, em thấy anh khai báo object collection ha... gì đó thấy lạ lạ quá ạ
 

befaint

|||||||||||||
Tham gia ngày
6 Tháng một 2011
Bài viết
10,030
Được thích
11,798
Điểm
1,560
Anh cho em xin hỏi, bài này cũng giải đc object dictionary như cấu trúc code của anh phải không ạ, em thấy anh khai báo object collection ha... gì đó thấy lạ lạ quá ạ
Được nhé. Dùng cái gì mà tận dụng được chức năng kiểm tra sự tồn tại key trong object đó là được.
Từ bài 11 tới bài 18 (trừ bài 12) đều áp dụng được hết. Ở đây 99% là dùng, biết dùng, thích dùng Dictionary, còn mình thì không thích. Đại khái thế.

1600357088148.png
 
Top Bottom