thắc mắc code xóa rows trống trong một cột dữ liệu (1 người xem)

Liên hệ QC

Người dùng đang xem chủ đề này

ninhmoon

Thành viên tiêu biểu
Tham gia
3/3/14
Bài viết
525
Được thích
48
Hello!
Em có 1 thắc mắc với đoạn code bên dưới.
Tuy rằng không khai báo biến i nhưng mà vẫn sử dụng và chạy được là như thế nào.


[GPECODE=vb]
Sub delempty()
'Dim i As Range
Rng = Selection.Rows.Count
ActiveCell.Offset(0, 0).Select
Application.ScreenUpdating = False
For i = 1 To Rng
If ActiveCell.Value = "" Then
Selection.EntireRow.Delete
Else
ActiveCell.Offset(1, 0).Select
End If
Next i
Application.ScreenUpdating = True

End Sub



[/GPECODE]
 
Hello!
Em có 1 thắc mắc với đoạn code bên dưới.
Tuy rằng không khai báo biến i nhưng mà vẫn sử dụng và chạy được là như thế nào.


[GPECODE=vb]
Sub delempty()
'Dim i As Range
Rng = Selection.Rows.Count
ActiveCell.Offset(0, 0).Select
Application.ScreenUpdating = False
For i = 1 To Rng
If ActiveCell.Value = "" Then
Selection.EntireRow.Delete
Else
ActiveCell.Offset(1, 0).Select
End If
Next i
Application.ScreenUpdating = True

End Sub



[/GPECODE]
trong VBA cho phép bạn không khai báo mà vẫn sử dụng được.
tuy nhiên tôi khuyên bạn là mình phải nên khai báo rõ ràng để tiện kiểm soát các câu lệnh
 
Upvote 0
Code này, nếu 2 ô trống liên tiếp trong cùng cột (thí dụ A10, A11) sẽ chỉ xóa 1 dòng.
 
Upvote 0
Code này, nếu 2 ô trống liên tiếp trong cùng cột (thí dụ A10, A11) sẽ chỉ xóa 1 dòng.
Khi xóa 1 dòng trống thì dòng dưới bị đẩy lên nên khi next thì dòng tiếp theo trống sẽ bị xóa.
Code này chỉ có lỗi khi Selection được chọn từ dưới lên thay vì từ trên xuống, khi đó số dòng xóa được nhiều nhất là 1 khi ô dưới cùng trống.
 
Upvote 0
Khi xóa 1 dòng trống thì dòng dưới bị đẩy lên nên khi next thì dòng tiếp theo trống sẽ bị xóa.
Code này chỉ có lỗi khi Selection được chọn từ dưới lên thay vì từ trên xuống, khi đó số dòng xóa được nhiều nhất là 1 khi ô dưới cùng trống.
Đúng rồi, tôi không xem kỹ. (do thuật toán rắc rối)
Nếu chọn từ dưới lên thì thuật toán sẽ đơn giản hơn. Thí dụ:

PHP:
For i = dongcuoi to dongdau step -1
     If Cells(i, 2) = "" then Cells(i, 2).EntireRow.Delete
Next
 
Upvote 0
Đúng rồi, tôi không xem kỹ. (do thuật toán rắc rối)
Nếu chọn từ dưới lên thì thuật toán sẽ đơn giản hơn. Thí dụ:

PHP:
For i = dongcuoi to dongdau step -1
     If Cells(i, 2) = "" then Cells(i, 2).EntireRow.Delete
Next

Ngắn hơn tí và có lẽ bớt động tác xác định canh toàn bộ hàng Sư phụ nhỉ?

PHP:
For i = dongcuoi to dongdau step -1
     If Cells(i, 2) = "" then Rows(i).Delete
Next
 
Upvote 0
Ta có thể gôm vô 1 biến Range nào đó (bằng fương thức Union()) & xóa 1 lần thôi. Lúc này thì từ dưới lên hay trên xuống cũng 1 tốc độ.

Ngoài ra còn có cách đưa vô mảng, nhanh hơn nhiều. Nhưng chuyện này xin nhường cho các thầy chuyên mảng.
 
Upvote 0
Ta có thể gôm vô 1 biến Range nào đó (bằng fương thức Union()) & xóa 1 lần thôi. Lúc này thì từ dưới lên hay trên xuống cũng 1 tốc độ.

Ngoài ra còn có cách đưa vô mảng, nhanh hơn nhiều. Nhưng chuyện này xin nhường cho các thầy chuyên mảng.
hình như dạng này trên diễn đàn cũng đã có rồi đó thầy. lưu dữ liệu vào trong range sau đó xóa 1 lần
 
Upvote 0
trong VBA cho phép bạn không khai báo mà vẫn sử dụng được.
tuy nhiên tôi khuyên bạn là mình phải nên khai báo rõ ràng để tiện kiểm soát các câu lệnh
Đúng ah! trong VBA không bắt buộc phải khai báo biến, nhưng mà khai báo biến để làm cho code thêm rõ ràng, dễ hoạt động hơn.
Nhưng với trình độ gà mờ và lò mò VBA của Em. Để hiểu khi nào cần khai báo biến và gắn nó vào type của biến nào. và nó đi tới kết quả ra sao mà em chưa hiểu được. !$@!!
và Em phải làm như thế nào để hiểu được đối với đoạn code ở trên ah!
1. Em muốn khai báo biến i theo kiểu as range vì sự biến động ở đây là vị trí giữa các ô.
2. khi khai báo thì code sẽ thay đổi như thế nào?
hi vọng nhận được reply của các THầy.
 
Upvote 0
1. Em muốn khai báo biến i theo kiểu as range vì sự biến động ở đây là vị trí giữa các ô.
2. khi khai báo thì code sẽ thay đổi như thế nào?
Khai báo i kiểu range là biến đối tượng thì không thể dùng vòng lặp for như trên
Mã:
Sub ABC()
Dim i As Range, r As Range
For Each i In Selection
If Len(i.Value) = 0 Then
If r Is Nothing Then
Set r = i.EntireRow
Else
Set r = Union(r, i.EntireRow)
End If
End If
Next
r.Delete
End Sub
Để hiểu cách chương trình làm việc bạn bấm F8 để chạy từng lệnh rồi quan sát các thay đổi trong cửa sổ Local.
 
Lần chỉnh sửa cuối:
Upvote 0
Hello!
Em có 1 thắc mắc với đoạn code bên dưới.
Tuy rằng không khai báo biến i nhưng mà vẫn sử dụng và chạy được là như thế nào.

[GPECODE=vb]
Sub delempty()
'Dim i As Range
Rng = Selection.Rows.Count
ActiveCell.Offset(0, 0).Select
Application.ScreenUpdating = False
For i = 1 To Rng
If ActiveCell.Value = "" Then
Selection.EntireRow.Delete
Else
ActiveCell.Offset(1, 0).Select
End If
Next i
Application.ScreenUpdating = True

End Sub

[/GPECODE]

Trong code trên có tới 2 biến không khai báo, Rng và i.

Đúng ah! trong VBA không bắt buộc phải khai báo biến, nhưng mà khai báo biến để làm cho code thêm rõ ràng, dễ hoạt động hơn.
Nhưng với trình độ gà mờ và lò mò VBA của Em. Để hiểu khi nào cần khai báo biến và gắn nó vào type của biến nào. và nó đi tới kết quả ra sao mà em chưa hiểu được. !$@!!
và Em phải làm như thế nào để hiểu được đối với đoạn code ở trên ah!
1. Em muốn khai báo biến i theo kiểu as range vì sự biến động ở đây là vị trí giữa các ô.
2. khi khai báo thì code sẽ thay đổi như thế nào?
hi vọng nhận được reply của các THầy.

Range là range, vị trí là vị trí. Hai cái này khác nhau.
Range được biểu hiện là một object kiểu range.
Vị trí là một chỉ số, vì vậy nó được biểu hiện thoe kiểu số nguyên, integer hay long gì đó.

"khai báo biến để làm cho code thêm rõ ràng, dễ hoạt động hơn": câu này chưa chắc. Khai báo không thoe một tiêu chuẩn nhất định thì code cũng chả rõ ràng chút nào. Điển hình là bên trên, bạn không phân biệt nổi kiểu của biến, đăt i làm range thì càng khó hiểu.

chú thích: tôi cố tình không trả lời ngay vì đã nhắc nhở nhiều lần nhưng bạn vẫn không bỏ thói quen xưng hô theo ngôn ngữ nửa Tây nửa Ta.
 
Upvote 0

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

Back
Top Bottom