Xóa những dòng không được edit

Liên hệ QC

nguyenkendlk

Thành viên mới
Tham gia
14/4/10
Bài viết
3
Được thích
0
Em cần tạo 1 cái button, khi click vào đó thì nó sẽ xóa đi những row không được edit (trước đó) và lưu lại trạng thái là đã click. Để có click tiếp thì không xóa những dòng còn lại nữa. Xin các bác giúp em làm 1 file mẫu với. Em cảm ơn rất nhiều /-*+/
 
Em cần tạo 1 cái button, khi click vào đó thì nó sẽ xóa đi những row không được edit (trước đó) và lưu lại trạng thái là đã click. Để có click tiếp thì không xóa những dòng còn lại nữa. Xin các bác giúp em làm 1 file mẫu với. Em cảm ơn rất nhiều /-*+/
Hiểu bạn nói gì chết liền
những row không được edit (trước đó) là cái giống gì đây? (chỉ có bạn hiểu được thôi)
 
Upvote 0
Sorry, mình diễn đạt hơi khó hiểu. Ý mình là: mở file excel đó lên, dữ liệu có rất nhiều dòng. Người dùng sẽ sửa dữ liệu của 1 số dòng và click vào button. Lúc đó phải thực hiện xóa hết tất cả những dòng mà không được sửa. Mình cần gấp lắm, làm ơn giúp mình với.
 
Upvote 0
Về lý thuyết thì không thể.
Trình tự như sau:
Mở file lên, trong đó có 100 dòng
sửa 30 dòng bất kỳ, trong 1 dòng có thể sửa 1 ô hoặc nhiều ô. Vị trí ô cũng bất kỳ.
xoá 70 dòng còn lại.

VBA không có khả năng bắt sự kiện không xoá dòng (có sự kiện đâu mà bắt?), mà chỉ bắt sự kiện xoá (nếu có xoá)

Đồng thời, VBA không có khả năng nhớ và so sánh dữ liệu 100 dòng ban đầu và 100 dòng sau khi sửa. Hơn nữa, nếu so sánh được, thì 100 dòng ban đầu không thể so sánh với 30 dòng, hoặc 40, 50 dòng. Vì biết đâu người dùng cũng đã xoá 20 trong số 70 dòng đáng lẽ phải xoá. Và 40, 50 dòng còn lại đó không nằm đúng vị trí ban đầu là cái chắc.
 
Upvote 0
Nghĩ ra 1 hướng nhưng chưa thử: (với điều kiện dữ liệu đúng chuẩn database)

1. Khi mở file: Copy sheet sang 1 sheet tmp (với n dòng dữ liệu không kể tiêu đề)
2. Chỉnh sửa búa xua.
3. Khi nhấn nút:

- Tạo 1 biến mảng Arr1 n dòng 1 cột.
- Dùng vòng lặp với biến i duyệt qua tất cả các dòng của sheet tmp (không kể dòng tiêu đề)
- Dùng vòng lặp qua tất cả các cột của Database sheet tmp, và dùng toán tử nối chuỗi nối tất cả các cột trên cùng dòng i, gán kết quả vào phần tử (i, 1)
- Quay lại sheet chính, cũng dùng phép nối chuỗi, nối tất cả các cột trên cùng dòng thành 1 phần tử của biến mảng Arr2.
- Kết quả ta có 2 mảng 1 cột: Arr1 n dòng và Arr2 m dòng. (n >= m)
- Dò tìm từng phần tử của Arr2 trong Arr1, nếu tìm thấy, tức là chưa chỉnh sửa, và xoá. Nếu không tìm thấy, thì bỏ qua.
- Do có xoá dòng, nên phải dò tìm Arr2 ngược từ dưới lên.

Như vậy, nếu sửa dù chỉ 1 ký tự cũng được xem là có chỉnh sửa, và để lại.

Nguyên tắc là phải có cái ban đầu để so sánh với cái sau khi chỉnh sửa. Nếu không dùng sheet tmp mà bắt VBA nhớ triền miên cả 1 sheet dữ liệu ban đầu thì có nước treo máy.
 
Upvote 0
Nghĩ ra 1 hướng nhưng chưa thử: (với điều kiện dữ liệu đúng chuẩn database)

1. Khi mở file: Copy sheet sang 1 sheet tmp (với n dòng dữ liệu không kể tiêu đề)
2. Chỉnh sửa búa xua.
3. Khi nhấn nút: .......
Em lại nghĩ đến một phương án khác (cũng chưa thử):
1. Khi mở file: Tạo 1 sheet mới tmp
2. Khi có sự chỉnh sửa trên sheet nguồn: Nếu chỉ số hàng của ô được sửa mà chưa có trên sheet tmp thì thêm chỉ số hàng này vào cột A của sheet tmp. Có thể kiểm tra sự tồn tại này bằng phương thức Find hoặc hàm WorksheetFunction.Countif
3. Khi nhấn nút: Duyệt cột A của sheet tmp từ dưới lên trên, nếu hàng nào trên sheet nguồn mà không được liệt kê ở sheet tmp thì xóa hàng đó đi (tất nhiên cũng trừ hàng tiêu đề). Cuối cùng là xóa sheet tmp.
Trong code của nút này cần có bẫy lỗi: Nếu sheet tmp không tồn tại (đã xóa) hoặc chưa có dữ liệu (chưa chỉnh sửa bất kỳ ô nào trên sheet nguồn) thì Exit Sub.
 
Lần chỉnh sửa cuối:
Upvote 0
Cách này cũng hay, nhưng chưa dự phòng trường hợp người dùng edit nhầm dòng, và phục hồi lại (xem như không edit). Chỉ số dòng đã cập nhật vào sheet tmp mât rồi.

Chuyện đã edit hay chưa, có edit hay không, phải so sánh với dữ liệu gốc từng ký tự một mới chính xác.
 
Upvote 0
Cách này cũng hay, nhưng chưa dự phòng trường hợp người dùng edit nhầm dòng, và phục hồi lại (xem như không edit). Chỉ số dòng đã cập nhật vào sheet tmp mât rồi.

Chuyện đã edit hay chưa, có edit hay không, phải so sánh với dữ liệu gốc từng ký tự một mới chính xác.
Vậy thì thử kiểu này không biết liệu có ổn không:
1. Khi mở file: Copy các cột trong sheet nguồn và dán giá trị sang bên phải (chắc cũng không đến nỗi thiếu cột). Cuối vùng dữ liệu vừa dán có 1 cột ghi lại trạng thái.
2. Chỉnh sửa búa xua.
3. Khi nhấn nút:
- Cập nhật giá trị trên cột trạng thái bằng cách so sánh giá trị (nối các ô bên trái - dữ liệu sau khi sửa) với (nối các ô bên phải - dữ liệu gốc) và trả về giá trị 0-1 hoặc 2 giá trị phân biệt bất kỳ. Giá trị trên cột này có thể được tạo ra nhờ hàm IF.
- Lọc toàn bộ dữ liệu (cả mới và cũ) theo cột trạng thái này (lấy giá trị chưa sửa).
- Xóa tất cả kết quả lọc.
- Xóa các cột phụ đã dán khi mở file.

Nếu có dữ liệu mẫu của tác giả topic thì dễ mần ăn hơn đấy nhỉ.
 
Upvote 0
Cách này so với cách bài 7 là cùng thuật toán. Nhiều hơn 1 công đoạn là gán giá trị 0, 1 và 1 công đoạn là filter.
Ngoài ra, 1 cái hay là nếu người dùng sửa 30 dòng, đáng lẽ xoá 70 dòng, họ lại xoá trước 10, 20 dòng, thì chỉ phải dò tìm trên 1 số dòng ít hơn, mà vẫn đúng.

Trong khi đó làm theo bài 7, làm theo mảng (có lẽ nhanh hơn), nhưng bị cái vòng lặp dò tìm từng giá trị mảng Arr2 trong tất cả giá trị của Arr1.

Chưa biết so sánh tốc độ sẽ như thế nào? Phải có dữ liệu mẫu để test cả 2 cách.

Còn 1 vấn đề: Không biết giới hạn số ký tự trong 1 biến string của VBA, có đủ để nối 20, 30 cột với nhau hay không?
 
Upvote 0
Web KT

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

Back
Top Bottom