Maika8008
Thành viên gạo cội
Cảm ơn bạn! Rất vui vì có bạn @Hoàng Tuấn 868 đồng hành.Chúc mừng anh nha. .
Cảm ơn bạn! Rất vui vì có bạn @Hoàng Tuấn 868 đồng hành.Chúc mừng anh nha. .
Hồi nào giờ thớt chạy code trên chỉ chậm thôi chứ không bị cờ-rát (crash).Dạ, bác. Nhưng nếu thớt bố trí các table đúng trật tự thì khỏi cần băn khoăn. Chờ thớt xác nhận thôi.
...
Theo tôi chỉ cần xóa từ dưới lên trên bất kể vị trí hàng ngang (nghĩa là không cần từ phải qua trái hay từ trái qua phải). Vì:Bạn có thể sort các Tables theo Address của chúng. Xoá từ dưới lên trên, từ phải qua trái.
Dữ liệu để sort: dòng cuối & cột cuối & tên Table (hoặc chỉ số của nó trong collection)
Bạn ơi vậy cần phải sửa lại code đó như nào để có thể chạy được nhanh hơn?Theo tôi chỉ cần xóa từ dưới lên trên bất kể vị trí hàng ngang (nghĩa là không cần từ phải qua trái hay từ trái qua phải). Vì:
- Ta đang xóa dòng và Shift Xlup chứ không phải Shift xltoRight, hay là xóa cột Shift xlToLeft
- Code bài 1 chạy tán loạn vị trí, chỉ chậm chứ không lỗi (theo chỉ số i mà ai biết thứ tự tạo 350 cái đã thực hiện thế nào).
Các table ở cùng sheet cách nhau bởi 3 cột, hàng tiêu đề và hàng 2 hàng 3 là cùng hàng 1,2,3 của excel bạn ạ.Tôi thực là đã có code cho thớt rồi nhưng nếu không nói rõ thì code sẽ tầm bậy. Lý do: thớt có đến 350 table trên 1 sheet lận, một con số không tưởng đối với tôi.
Cho hỏi chút là bạn dùng chữ "Table" là đúng nghĩa thiết kế bảng dữ liệu theo định dạng Table của Excel phải không? Tôi thấy đối với đối tượng "Table" thì nó có các phương thức xóa dòng của nó đó. Bạn tìm hiểu xem.Các table ở cùng sheet cách nhau bởi 3 cột, hàng tiêu đề và hàng 2 hàng 3 là cùng hàng 1,2,3 của excel bạn ạ.
bạn ơi vậy mình phải viết lại như nào mới đúng? mình viết như này nhưng không được mong bạn sửa giúp:Xoá dòng của table không ảnh hưởng đến dòng của bảng tính.
Chỉ là thớt xoá từng dòng cho nên bị chậm. Mỗi dòng xoá là Excel lại phải chỉnh các thông số của Table. Nếu xoá cả cụm một lúc thì nhanh hơn.
Đại khái như vầy:
[Table1].Rows("3:" & [Table1].Rows.Count).Delete Shift:=xlUp
Dùng code này thớt nhé, chạy xong cho biết kết quả nhanh chậm thế nào.Bạn ơi vậy cần phải sửa lại code đó như nào để có thể chạy được nhanh hơn?
Các table ở cùng sheet cách nhau bởi 3 cột, hàng tiêu đề và hàng 2 hàng 3 là cùng hàng 1,2,3 của excel bạn ạ.
Option Explicit
'Hàm lay so thu tu cot dua vao tên cot
Function ColumnName2Number(ByVal strAdr As String)
Dim lgCol&, i&, j&, k&, arr
arr = Array("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", _
"N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z")
For i = Len(strAdr) To 1 Step -1
If Not IsNumeric(Mid(strAdr, i, 1)) Then
For j = LBound(arr) To UBound(arr)
If arr(j) = UCase(Mid(strAdr, i, 1)) Then
lgCol = lgCol + 26 ^ k * (j + 1)
k = k + 1: Exit For
End If
Next
End If
Next
ColumnName2Number = lgCol
End Function
'Xoa cac dong cua table, chi chua lai 2 dong data dau tien.
Sub ShrinkTable_All()
Dim i As Integer, rw&, oTbl As Object, tblAdrs$, frw&, fcol&, lcol&, lVT&
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
With Sheets("Data")
If .ListObjects.Count > 0 Then
For i = .ListObjects.Count To 1 Step -1
Set oTbl = .ListObjects(i)
rw = oTbl.ListRows.Count
If rw > 2 Then
tblAdrs = .ListObjects(i).HeaderRowRange.Address(0, 0)
lVT = InStr(1, tblAdrs, ":")
fcol = ColumnName2Number(Left(tblAdrs, lVT - 1))
lcol = ColumnName2Number(Right(tblAdrs, Len(tblAdrs) - lVT))
tblAdrs = .ListObjects(i).HeaderRowRange.Address(1, 0)
frw = Right(tblAdrs, Len(tblAdrs) - InStrRev(tblAdrs, "$"))
.Range(.Cells(frw + 3, fcol), .Cells(rw + frw, lcol)).Delete xlUp
End If
Next i
End If
End With
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
End Sub
Bạn cần tìm hiểu về ý nghĩa của dấu ngoặc vuông [ ]bạn ơi vậy mình phải viết lại như nào mới đúng? mình viết như này nhưng không được mong bạn sửa giúp:
... [Table & i].Rows("3:" & [Table & i].Rows.Count).Delete Shift:=xlUp
oh nó đã chạy rất nhanh bạn ạ! Cảm ơn bạn rất nhiều!Dùng code này thớt nhé, chạy xong cho biết kết quả nhanh chậm thế nào.
Rich (BB code):Option Explicit 'Hàm lay so thu tu cot dua vao tên cot Function ColumnName2Number(ByVal strAdr As String) Dim lgCol&, i&, j&, k&, arr arr = Array("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", _ "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z") For i = Len(strAdr) To 1 Step -1 If Not IsNumeric(Mid(strAdr, i, 1)) Then For j = LBound(arr) To UBound(arr) If arr(j) = UCase(Mid(strAdr, i, 1)) Then lgCol = lgCol + 26 ^ k * (j + 1) k = k + 1: Exit For End If Next End If Next ColumnName2Number = lgCol End Function 'Xoa cac dong cua table, chi chua lai 2 dong data dau tien. Sub ShrinkTable_All() Dim i As Integer, rw&, oTbl As Object, tblAdrs$, frw&, fcol&, lcol&, lVT& Application.ScreenUpdating = False Application.Calculation = xlCalculationManual With Sheets("Data") If .ListObjects.Count > 0 Then For i = .ListObjects.Count To 1 Step -1 Set oTbl = .ListObjects(i) rw = oTbl.ListRows.Count If rw > 2 Then tblAdrs = .ListObjects(i).HeaderRowRange.Address(0, 0) lVT = InStr(1, tblAdrs, ":") fcol = ColumnName2Number(Left(tblAdrs, lVT - 1)) lcol = ColumnName2Number(Right(tblAdrs, Len(tblAdrs) - lVT)) tblAdrs = .ListObjects(i).HeaderRowRange.Address(1, 0) frw = Right(tblAdrs, Len(tblAdrs) - InStrRev(tblAdrs, "$")) .Range(.Cells(frw + 3, fcol), .Cells(rw + frw, lcol)).Delete xlUp End If Next i End If End With Application.ScreenUpdating = True Application.Calculation = xlCalculationAutomatic End Sub
Code bạn nhiều chỗ thừa lắm.Dùng code này thớt nhé, chạy xong cho biết kết quả nhanh chậm thế nào.
Rich (BB code):Option Explicit 'Hàm lay so thu tu cot dua vao tên cot Function ColumnName2Number(ByVal strAdr As String) ... End Function 'Xoa cac dong cua table, chi chua lai 2 dong data dau tien. Sub ShrinkTable_All() ... End Sub
Chúc mừng Bác, Cảm giác như được thăng chức Bác hả?tôi được nâng 1 cấp thành viên
Hễ tôi mạnh dạn chỉnh code, chỉnh công thức thì tôi coi là bạn....
Qua đây tôi gửi lời cảm ơn chân thành đến bác VetMini đã không ngại nhận tôi là bạn dù cách xa tuổi tác và kiến thức, sở học. Cảm ơn bác ptm0412 "lão chết tiệt" luôn làm tôi nể phục về sự công bằng của 1 Super Moderator (tất nhiên không cần nhắc đến học thuật vì ai cũng biết rồi).
Tình cờ là 2 bác đều có mặt trong thớt này.
Cảm ơn bác. Chỗ ColumnName2Number thì đúng là tôi nghĩ quẩn nên mất công lấy địa chỉ rồi cắt chuỗi. Còn chỗ sheet1.listobjects(1).DataBodyRange.Offset(2, 0).Resize(sheet1.listobjects(1).DataBodyRange.Rows.Count-2).Delete tôi sẽ ghi nhớ bởi khi làm không biết thuộc tính của table.Code bạn nhiều chỗ thừa lắm.
' dịch tên cột sang số
ColumnName2Number = Range(strAddr).Column
' nếu chỉ có "A", "AB" thì
ColumnName2Number = Cells(1, strAddr).Column
' xoá dòng trong tables
i = 0
For Each lo In Sheets("Data").ListObjects
i = i+1
If i > 350 Then Exit For
lo.AutoFilter.ShowAllData
sheet1.listobjects(1).DataBodyRange.Offset(2, 0).Resize(sheet1.listobjects(1).DataBodyRange.Rows.Count-2).Delete ' giữ lại 2 dòng data, nếu không cần giữ thì không cần offset+resize gì cả
Next lo
... Còn chỗ sheet1.listobjects(1).DataBodyRange.Offset(2, 0).Resize(sheet1.listobjects(1).DataBodyRange.Rows.Count-2).Delete tôi sẽ ghi nhớ bởi khi làm không biết thuộc tính của table.
Bác ơi code của bác tôi chạy bị báo lỗi này, Bác xem giúp tôi với:Code bạn nhiều chỗ thừa lắm.
' dịch tên cột sang số
ColumnName2Number = Range(strAddr).Column
' nếu chỉ có "A", "AB" thì
ColumnName2Number = Cells(1, strAddr).Column
' xoá dòng trong tables
i = 0
For Each lo In Sheets("Data").ListObjects
i = i+1
If i > 350 Then Exit For
lo.AutoFilter.ShowAllData
sheet1.listobjects(1).DataBodyRange.Offset(2, 0).Resize(sheet1.listobjects(1).DataBodyRange.Rows.Count-2).Delete ' giữ lại 2 dòng data, nếu không cần giữ thì không cần offset+resize gì cả
Next lo
Mình thử như này vẫn lỗi, Bác xem sửa lại code giúp mình:
Bạn phải thay ListObject(1) bằng LítObject(i) và phải có điều kiện số dòng > 2 chứ. Nhưng nhìn code thì nhiều thứ không ổn lắm. Tôi viết lại thế này nè:Bác ơi code của bác tôi chạy bị báo lỗi này, Bác xem giúp tôi với:
( hay là do lỗi Sheets("Data") với Sheet1.ListObjects(1)?, Thấy hai dòng lệnh này có tên sheet khác nhau hả bác?)
View attachment 275004
Bài đã được tự động gộp:
Mình thử như này vẫn lỗi, Bác xem sửa lại code giúp mình:
Sub xoa_chi_giu_lai_hai_hang_dau()
i = 0
For Each lo In Sheets("Data").ListObjects
i = i + 1
If i > 350 Then Exit For
lo.AutoFilter.ShowAllData
Sheets("Data").ListObjects(1).DataBodyRange.Offset(2, 0).Resize(Sheets("Data").ListObjects(1).DataBodyRange.Rows.Count - 2).Delete ' gi? l?i 2 dòng data, n?u không c?n gi? thì không c?n offset+resize gì c?
Next lo
End Sub
View attachment 275005
Sub DeleteTableRows_2()
Dim LstObj As Object
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
For Each LstObj In Sheets("Data").ListObjects
If rw > 2 Then LstObj.DataBodyRange.Offset(2, 0).Resize(LstObj.DataBodyRange.Rows.Count - 2).Delete xlUp
Next
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
End Sub
Chuyện nâng cấp cũng tức cười lắm.... Nhưng mà bỏ qua các chuyện bên trên đi. Sau bài này, tôi được nâng 1 cấp thành viên. Đấy là vinh hạnh và cũng là động lực với tôi trong hành trình cùng GPE.
...
bạn ơi code này sao mình nhấn f5 thấy không chạy bạn ạ?Bạn phải thay ListObject(1) bằng LítObject(i) và phải có điều kiện số dòng > 2 chứ. Nhưng nhìn code thì nhiều thứ không ổn lắm. Tôi viết lại thế này nè:
Rich (BB code):Sub DeleteTableRows_2() Dim LstObj As Object Application.ScreenUpdating = False Application.Calculation = xlCalculationManual For Each LstObj In Sheets("Data").ListObjects If rw > 2 Then LstObj.DataBodyRange.Offset(2, 0).Resize(LstObj.DataBodyRange.Rows.Count - 2).Delete xlUp Next Application.ScreenUpdating = True Application.Calculation = xlCalculationAutomatic End Sub