Code xóa dữ liệu không chạy.

Liên hệ QC
Tôi tuân thủ nội quy khi đăng bài

LuuAnh980

Thành viên tiêu biểu
Tham gia
28/9/22
Bài viết
453
Được thích
104
Giới tính
Nữ
Em dùng đoạn code này để xóa dữ liệu cột D3 đến E, và cột J, và cột L của sheet Beginning.20231202_145401.jpg
Mà chạy code không thấy chạy ạ.
Mong các anh chỉ giúp em sai chổ nào ạ. Thông cảm em dùng điện thoại, nên chỉ chụp hình.
 
Upvote 0
Em không ngồi máy anh ơi, chiều em thử ạ.
 
Upvote 0
Chịu khó đọc cho kỹ, tôi sẽ chỉ ra từng chỗ sai cho bạn:

Mã:
...
    For Each Sh In Worksheets(Array("Beginning"))
'        Sheets(Sh).Select
        lr = Sheets("Beginning").Cells(Rows.Count, 4).End(xlUp).Row
        Sh.Range("D3:D" & lr + 1).Clear 'Contents
        Sh.Range("E3:E" & lr + 1).Clear 'Contents
        Sh.Range("J3:J" & lr + 1).Clear
        Sh.Range("L3:L" & lr + 1).Clear
    Next Sh
...
Bên trong cái vòng lặp For...Each thì Sh chính là Sheets(Beginning). Chỗ Sheets("Beginning") bạn chỉ cần dùng Sh

Mã:
...
        lr = Sheets("Beginning").Cells(Rows.Count, 4).End(xlUp).Row
        Sh.Range("D3:D" & lr + 1).Clear 'Contents
        Sh.Range("E3:E" & lr + 1).Clear 'Contents
        Sh.Range("J3:J" & lr + 1).Clear
        Sh.Range("L3:L" & lr + 1).Clear
Vậy phải chỉnh lại từng cột hả bạn @hhoang_56 .
lr = Sheets("Beginning").Cells(Rows.Count, 4).End(xlUp).Row
Cột 4 tức là cột D. Code trên lầ dòng cuối của cột D. Ví dụ dòng ấy là 1234.
Sh.Range("D3: D" & lr + 1) = Sh.Range("D3: D1235")
Sh.Range("E3:E" & lr + 1) = Sh.Range("D3: D1235")
Hai range trên nằm sát nhau và có cùng số dòng cho nên bạn có thể gom lại thành 1
Sh.Range("D3:E" & lr + 1) = Sh.Range("D3:E1235")
Tuy nhiên, trường hợp bài này thì nên để chúng riêng 2 cột dễ debug hơn.

Em có bắt chước theo Bác @VetMini chỉnh code:
Mã:
        Sh.Range("D3:E" & lr + 1).Clear 'Contents
        Sh.Range("J3" & lr + 1).Clear
        Sh.Range("L3" & lr + 1).Clear
    Next Sh
Sao code chỉ xóa cột D : E thôi, còn cột J và L không xóa ạ.
Trong code này, bạn hấp tấp nên gõ sót:
Nếu lr là 1234
Sh.Range("J3" & lr + 1) = Sh.Range("J31235") : một ô
Nếu gõ đúng
Sh.Range("J3:J" & lr + 1) = Sh.Range("J3:J1235") : một vùng gồm 1233 ô

tới anh @Hoàng Tuấn 868 ,...
Mã:
Sub XoaDuLieu()
Dim sh As Worksheet, lr As Long, i As Long, arr
Set sh = ThisWorkbook.Sheets("Beginning")
arr = Array(4, 5, 10, 12)
lr = sh.Cells(Rows.Count, 4).End(xlUp).Row
If Range("D4").Value <> "" Then 'them vào
    With sh
        For i = 0 To UBound(arr)
            .Range(.Cells(3, arr(i)), .Cells(lr, arr(i))).ClearContents
        Next i
    End With
    End If ' them vào
End Sub
Thấy chạy đúng ý của em rồi, mà không biết về sau có sự cố gì không ạ.
Code này viết theo trường phái thịnh hành ở GPE, code không sai nhưng trường phái của tôi quan niệm khác:
1. ở đây chỉ có 4 cột, lập cái array chuyển tên cột thành số làm cho code khó đọc. Lúc dựng array lại không chú thích nó dùng làm gì - nếu có chú thích, người đọc có thể tự tính ra 4 là cột D, 10 là cột J,...

2. With chỉ định đối tượng tiền tố cho dấu chấm "." trong block
Người ta chỉ dùng With khi cái tên nó dài, gõ cực và dễ bị nhầm ký tự. Ở đây cái tên Sh chỉ có 2 ký tự, không nên dùng With.
Cái bất lợi của With là nếu thiếu dấu "." thì VBA sẽ hiểu là dùng đối tượng mặc định. Với Sheet thì VBA sẽ mặc định là ActiveSheet.
Vì vậy, nên tránh dùng With với WorkSheet. Trừ phi chỉ muốn nhắc đến sheet 1 lần
With WorkSheets("abcdef")
...
End With
Dùng như thế này tránh được phải khai báo biến và set cho sheet.

Cám ơn anh @HUONGHCKT nhiều, "union" dùng để làm gì đó anh?
Union theo Toán Đại Số là phép hội, gộp nhiều nhóm lại với nhau.
Lý thuyết:
Có 2 nhóm A và B. A hội B là một nhóm gồm tất cả các phần tử của A và tất cả các phần tử của B; nếu A và B chia sẻ nhau một số phần tử thì nhóm hội này chỉ chứa các phần tử chung ấy 1 lần (không phải 2 lần)

Union trong VBA và Excel là phép hội nhiều ranges lại thành một nhóm range.
Bình thường người ta dùng Union khi cần sử lý một nhóm ranges bằng một lệnh chung.
Ví dụ tôi muốn gán 1 vào ô A1, B2:C3, và E5:E10
union(range("a1"), range("b2:c3"), range("e5:e10")) = 1 ' lười gõ 3 dòng
 
Lần chỉnh sửa cuối:
Upvote 0
Sao code anh @HUONGHCKT em chạy lỗi này
loi124.png
nhấn Debug hiện màu vàng chổ này ạ:
loi125.png
mong các anh xem giúp.
 
Upvote 0
Code câu lệnh đó sai. Khi có vòng lặp i:
for i = 0 to UBound(arr)

Khi i = 0, Cells(Rows.Count, i) = Cells(Rows.Count, 0) sinh ra lỗi không có cột số 0
Bạn này viết code mà không test trước khi gởi bài.

Câu lệnh đúng là

lr = sh.Cells(Rows.Count, arr(i)).End(xlUp).Row
 
Upvote 0
Em chỉnh lại như Thầy Mỹ, thì lỗi "91" ạ:
loi126.png
nhấn Debug thì màu vàng :
loi127.png
Mong Thầy Mỹ xem giúp.
 
Upvote 0
Em chỉnh lại như Thầy Mỹ, thì lỗi "91" ạ:
Kiểm tra xem lúc đang lỗi thì lr bằng bao nhiêu, hoặc tốt nhất là mỗi lần tính lại lr thì lr có giá trị bao nhiêu. Đối chiếu với điều kiện If lr = 4
Do lr luôn lớn hơn 4 nên Rng = nothing và không thể sử dụng method Clear

Đến là mệt với code viết không test
 
Upvote 0
Em kiểm tra thì thấy lr = 86 Thầy Mỹ, vậy chỉnh code sao Thầy. À em chỉnh lại là lr>= 4 thì được rồi ạ.
loi128.png
 
Upvote 0
Em sửa thành If lr>=4 thì code chạy rồi Thầy.
 
Upvote 0
Em sửa thành If lr>=4 thì code chạy rồi Thầy.
Lý thuyết bổ sung:
Khai báo biến, gán giá trị cho biến, còn phải kiểm soát biến:
- Kiểm soát kiểu biến. Biến kiểu Long mà gắn Text là tiêu. Biến kiểu String, hoặc biến kiểu Sheet, biến kiểu Range, phải gắn giá trị phù hợp.
- Kiểm soát giá trị biến. Tại từng thời điểm biến có giá trị bao nhiêu. Giá trị đó được sử dụng ở đâu, có tương thích hay không.

Như code của @Hoàng Tuấn 868 mà bạn than phiền là chạy lần 2, lần 3 nó xóa dần lên tiêu đề và lên cả dòng 1. Nếu kiểm soát giá trị biến thì biết rằng sau lần xóa thứ nhất, lr = 2, sau lần xóa thứ 2, lr = 1. Lẽ ra phải có điều kiện như vừa rồi.
 
Upvote 0
À như code của anh @HUONGHCKT khi em chỉnh lr>=4, thì code chạy, nhưng khi xóa xong mà lỡ chạy tiếp lần 2 thì báo lỗi, vậy mình có thể bẫy lỗi được không Thầy Mỹ, như em tính thêm:
If lr <4 then Exit Sub
nhưng không biết để chổ nào cho phù hợp.
 
Upvote 0
À như code của anh @HUONGHCKT khi em chỉnh lr>=4, thì code chạy, nhưng khi xóa xong mà lỡ chạy tiếp lần 2 thì báo lỗi, vậy mình có thể bẫy lỗi được không Thầy Mỹ, như em tính thêm:
If lr <4 then Exit Sub
nhưng không biết để chổ nào cho phù hợp.
Trường hợp này Rng là Union 4 range con, nên chỉ khi cả 4 lần lr < 4 thì mới sinh ra lỗi.
Do đó bắt lỗi ngay tại chỗ lỗi:
Mã:
If Not Rng Is Nothing Then Rng.ClearContents

Không cần Else ... Exit Sub
 
Upvote 0
Kiểm tra xem lúc đang lỗi thì lr bằng bao nhiêu, hoặc tốt nhất là mỗi lần tính lại lr thì lr có giá trị bao nhiêu. Đối chiếu với điều kiện If lr = 4
Do lr luôn lớn hơn 4 nên Rng = nothing và không thể sử dụng method Clear

Đến là mệt với code viết không test
Cảm ơn Anh đã nhắc nhở. Đúng là tôi có sửa lại code của bạn ấy và do không có file nên cũng không test lại
Do không test lại nên nhâm chỗ Lr= 4 mà đúng ra phải là Lr>= 4 thì mới đúng.
 
Upvote 0
Chủ bài đăng mới học cấp 1 về VBA, mà hai bác viết cho những Code có chứa những dòng lệnh của cấp 2 hay cấp III thì tẩu hỏa nhập ma là cái chắc!
Để chọn 4 cột không theo 1 trật tự thì ta xài hàm CHOOSE() (Lý do là trong excel chủ bài đăng cũng đã tiếp cận với nó)

PHP:
Dim J as Integer, Col as Integer, Rws as long
For J = 1 to 4
  Col = Choose( J , 4 , 5, 10, 12, 19)
  Rws = Cells(9999,Col).End(xlup).row +9 'Dòng cuối có dữ liệu của cột đang xét'
 'Thêm dòng lệnh kiểm tra Rws >=4  '
   Dòng lệnh xóa dữ liệu của cột đang xét 
Next J
 
Upvote 0
Mong Thầy Mỹ chỉ cho em chổ thêm luôn ạ.
Bài đã được tự động gộp:

Trong code của Bác @SA_DQ các số 19, 9 là gì, mong Bác @SA_DQ giải thích dùm ạ.
 
Upvote 0
tới anh @Hoàng Tuấn 868 , sao code của anh em chạy lần đầu thấy đúng rồi (đã xóa đúng các cột)
Nhưng em lỡ tay chạy lần 2, thì code lại xóa luôn dòng tiêu đề của em luôn. (D3: E3), J3, L3.
Em có thử chạy tiếp thì lại xóa tiếp D2:E2,J2,L2. Chạy tiếp thì xóa tới D1:E1, J1, L1. Hết mới thôi.
Có cách nào hạn chế việc này không ạ.
Như là D4:E4 có dữ liệu thì mới xóa.
Bạn chạy thử code này
Mã:
Sub XoaDuLieu()
Dim sh As Worksheet, lr As Long, i As Long, arr
Set sh = ThisWorkbook.Sheets("Beginning")
arr = Array(4, 5, 10, 12)
lr = sh.Cells(Rows.Count, 4).End(xlUp).Row
if lr < 3 then lr = 3
    With sh
        For i = 0 To UBound(arr)
            .Range(.Cells(3, arr(i)), .Cells(lr, arr(i))).ClearContents
        Next i
    End With
End Sub
 
Upvote 0
Web KT

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

Back
Top Bottom