Nhờ mọi người giúp dùm mình có 2 file Exel khi mở ra để làm và trong quá trình làm thì nó rất chậm. Cám ơn nhiều.
Nhờ mọi người giúp dùm mình có 2 file Exel khi mở ra để làm và trong quá trình làm thì nó rất chậm. Cám ơn nhiều.
a tài thật đó, e cố gắng ngồi run cả buổi trưa mà chẳng thấm vào đâuFile của bạn chứa trên 50000 "cục đá" nên nó "nặng" là phải rồi
Đã dọn dẹp giúp bạn
a tài thật đó, e cố gắng ngồi run cả buổi trưa mà chẳng thấm vào đâu(chắc do máy của e cùi hơn)
Code mà tôi dùng chỉ có vầy:có phải a dùng code để xóa như PTH đã nói ko? cho e xin đoạn code đó với. Thanks a!
Sub DelObjects()
Dim i As Long, wks As Worksheet
On Error Resume Next
Set wks = ActiveSheet
For i = 1 To 10000
wks.Shapes(1).Delete
Next
MsgBox "Còn " & wks.Shapes.Count & " objects"
End Sub
Số 10000 trong code có thể thay bởi wks.Shapes.Count thì khỏi phải chạy nhiều lần anh nhỉ.Code mà tôi dùng chỉ có vầy:
Cứ chạy code đến khi nào nhận được thông báo "Còn 0 objects" thì ngưngMã:Sub DelObjects() Dim i As Long, wks As Worksheet On Error Resume Next Set wks = ActiveSheet For i = 1 To 10000 wks.Shapes(1).Delete Next MsgBox "Còn " & wks.Shapes.Count & " objects" End Sub
Cũng tùy theo máy mạnh thì mình cách này máy yếu nên gắt từng đoạn mà xử giống như bó đũa lấy từng chiếc ra mà bẻ sẽ dễ hơn để nguyên bó anh Phúc? Em thì dùng cách ngắt từng đoạn để đỡ bị treo máySố 10000 trong code có thể thay bởi wks.Shapes.Count thì khỏi phải chạy nhiều lần anh nhỉ.
Số 10000 trong code có thể thay bởi wks.Shapes.Count thì khỏi phải chạy nhiều lần anh nhỉ.
Sub ShapesDelete()
Dim Obj As Shape
For Each Obj In ActiveSheet.Shapes
If Obj.Visible = msoFalse Then
Obj.Delete 'Xóa đối tượng Shape bị ẩn, do virus tạo ra
End If
Next
Set Obj = Nothing
End Sub
Do bác ndu lười thôi, dùng For each là chuẩn nhất:
Mã:Sub ShapesDelete() Dim Obj As Shape For Each Obj In ActiveSheet.Shapes If Obj.Visible = msoFalse Then Obj.Delete 'Xóa đối tượng Shape bị ẩn, do virus tạo ra End If Next Set Obj = Nothing End Sub
Số 10000 trong code có thể thay bởi wks.Shapes.Count thì khỏi phải chạy nhiều lần anh nhỉ.
Ẹc... Ẹc... Đó là vì các bạn ít khi đụng đến mấy "cục đá" này nên nghĩ vậy. Nếu mà sửa như Phúc và thầy Hướng, bảo đảm máy đơ luôn
Tóm lại: Phài xóa từ từ và con số 10000 là giới hạn mà tôi thí nghiệm ra (trên mấy tôi)
Ẹc... Ẹc... Đó là vì các bạn ít khi đụng đến mấy "cục đá" này nên nghĩ vậy. Nếu mà sửa như Phúc và thầy Hướng, bảo đảm máy đơ luôn
Tóm lại: Phài xóa từ từ và con số 10000 là giới hạn mà tôi thí nghiệm ra (trên mấy tôi)
Hic, em chưa hiểu lý do máy đơ? Hay với kiểu vòng lặp For each cho tập hợp nhiều Shape thì máy hoạt động kém. Có bạn nào test thử chưa?
Do while wks.Shapes.Count > 0
wks.Shapes(wks.Shapes.Count).Delete
Loop
k = wks.Shapes.Count
Do while k > 0
wks.Shapes(k).Delete
k = k - 1
Loop
Máy tôi yếu nên đã đơ từ khi mở tập tin rồi. Vậy không test được, chỉ "võ mồm" thôi.
Dứt khoát là đã Delete tất cả thì làm trong vòng lặp và luôn delete "phần tử cuối". Delete phần tử cuối là đúng bài bản.
Để khỏi phân tích cụ thể thì cứ nghĩ nôm na là nếu ta có 1 hàng học sinh và nếu cứ bỏ từng em đứng cuối thì rồi sẽ hết học sinh. Cũng có thể bỏ từng em thứ 1 nhưng như thế thì sau mỗi lần bỏ thì toàn bộ "hàng hiện hành" phải dịch lên đầu 1 "chỗ".
Tôi tin chắc rằng nếu ai có máy mạnh thì có thể test 2 kiểu delete và theo tôi kiểu luôn delete cuối là nhanh hơn.
Kiểu như
Mã:Do while wks.Shapes.Count > 0 wks.Shapes(wks.Shapes.Count).Delete Loop
Hoặc tốt hơn
Mã:k = wks.Shapes.Count Do while k > 0 wks.Shapes(k).Delete k = k - 1 Loop
Tôi không rõ với For Each thì các đối tượng được duyệt theo thứ tự nào. Chắc theo thứ tự tăng dần của chỉ số.
Sub Siwtom_Xoa()
k = ActiveSheet.Shapes.Count
Application.ScreenUpdating = False
Do While k > 0
ActiveSheet.Shapes(k).Delete
k = k - 1
'Tong: 58.559
If k = 45000 Then MsgBox ("con ") & k
If k = 40000 Then MsgBox ("con ") & k
If k = 30000 Then MsgBox ("con ") & k
If k = 20000 Then MsgBox ("con ") & k
If k = 10000 Then MsgBox ("con ") & k
If k = 1000 Then MsgBox ("con ") & k
Loop
Application.ScreenUpdating = True
End Sub
Tạm thời mình phát hiện file của bạn có nhiều name rác vì đang dùng máy cài office 2003.Em cũng bị hiện tượng một số file excel bị tăng dung lượng mặc dù dữ liệu rất ít. Nhờ mọi người giúp đỡ. Em gửi kèm theo một trong số các file đó.
Nếu dùng excel 2007 trở lên thì việc xóa name rác rất đơn giản.Có cách nào nhanh hơn không ạ? Xóa bằng tay từng cái thì rất lâu, mà mình bị nhiều file như thế này.
Hoặc có thể dùng Filter để lọc ra những name lỗi (with error) để xóa đi.name của bạn cũng ko nhiều lắm
View attachment 116898
bạn muốn xoá nhanh thì có thể dùng cách sau:
- Sort cột Value (hoặc Refers To)
- chọn từ vị trí 1 + Shift + vị trí 2, rồi Delete là xong.
Mình xem qua rồi chắc tại bạn thêm quá nhiều đối tượng form trong Object đó thôi Google
Nếu bạn vẫn muốn delete một loạt thì nên làm ngược từ số lớn trở về số nhỏ - với hy vọng tránh được tình trạng index hoặc bộ nhớ bị sắp xếp lại thường xuyên
Sub DelObjects()
Dim i As Long, wks As Worksheet
On Error Resume Next
Set wks = ActiveSheet
For i = 1 To 10000
wks.Shapes([COLOR=#ff0000][/COLOR][SIZE=4][COLOR=#ff0000][B]1[/B][/COLOR][/SIZE]).Delete
Next
MsgBox "Còn " & wks.Shapes.Count & " objects"
End Sub
Mình nghĩ cũng không cần, Code của mình:
Cái màu đỏ là số 1 chứ hổng phải chữ i nha. Bạn nghĩ nó hợp lý chứMã:Sub DelObjects() Dim i As Long, wks As Worksheet On Error Resume Next Set wks = ActiveSheet For i = 1 To 10000 wks.Shapes([SIZE=4][COLOR=#ff0000][B]1[/B][/COLOR][/SIZE]).Delete Next MsgBox "Còn " & wks.Shapes.Count & " objects" End Sub
Không phải tôi nói nó đúng hay không đúng.
Theo tôi suy diễn (không chắc là đúng, bởi vậy trước đó tôi có dùng từ "hy vọng") thì:
- Mỗi lần nó xoá đi phần tử số 1 thì các phần tử 2, 3, ... được đôn lên.
- Mỗi lần đôn như thế có thể tốn năng lượng.
Sự tốn năng lượng kể trên chỉ là ước phỏng. Nếu bên trong máy, các phần tử được xếp theo dạng nối đuôi vòng (circular queue) thì xoá đầu hay xoá đuôi không khác nhau bao nhiêu bởi vì việc xoá được thực hiện bằng cách dời con trỏ (tương tự như offset)
procedure TStringList.Delete(Index: Integer);
begin
if (Index < 0) or (Index >= FCount) then Error(@SListIndexError, Index);
Changing;
Finalize(FList^[Index]);
Dec(FCount);
if [B][COLOR=#0000ff]Index < FCount[/COLOR][/B] then
[B][COLOR=#ff0000]System.Move(FList^[Index + 1], FList^[Index],
(FCount - Index) * SizeOf(TStringItem));[/COLOR][/B]
Changed;
end;
- Mỗi lần đôn như thế có thể tốn năng lượng.
Trong VBA thì cái này phải thí nghiệm mới tin à nghen. Để xem sao cái
Ẹc... Ẹc...
Bác Siwtom cũng dùng từ "bài bản". Theo tôi hiểu thì bác ấy muốn nói "nên làm, chứ không bắt buộc phải làm".
Cũng có thể bỏ từng em thứ 1 nhưng như thế thì sau mỗi lần bỏ thì toàn bộ "hàng hiện hành" phải dịch lên đầu 1 "chỗ".
Tôi tin chắc rằng nếu ai có máy mạnh thì có thể test 2 kiểu delete và theo tôi kiểu luôn delete cuối là nhanh hơn.
Sub test()
Dim k As Long, TG As Double, i As Long
TG = Timer
k = ActiveSheet.Shapes.Count
For i = 1 To k
ActiveSheet.Shapes(1).Delete
Next
[L1] = Timer - TG
End Sub
Sub test()
Dim TG As Double, k As Long, wks As Worksheet
TG = Timer
Set wks = ActiveSheet
k = wks.Shapes.Count
Do While k > 0
wks.Shapes(k).Delete
k = k - 1
Loop
[K1].Value = Timer - TG
End Sub
Đồng ý 100%.
Chính vì vậy mà tôi vẫn nhét thêm trạng từ "hy vọng" (hopefully) và "có thể" (perhaps).
Bác Siwtom cũng dùng từ "bài bản". Theo tôi hiểu thì bác ấy muốn nói "nên làm, chứ không bắt buộc phải làm".
Sở dĩ tôi nghi ngờ là vì chợt nghĩ ra một tình huống thế này:
- Trên sheet có 20000 shape
- Điều hiển nhiên là Excel sẽ gán cho 1 shape nào đó là giá trị Index =1 và 1 cái nào đó là giá trị Index = 20000
- Bây giờ nếu tôi xóa bằng tay Shape mang index =1 thì hóa ra nó sẽ "chậm" hơn so với khi tôi xóa thằng shape mang index = 20000 (theo suy luận của bạn)
Tôi thì lại cảm thấy nó vô lý vô cùng ấy chứ ???!!!
Xin lỗi, vì tôi chỉ học mò nên cũng nói theo kiểu mò và dùng thực nghiệm để kiểm chứng thôi
\
Chú thích cho những bạn ít có tiếp xúc với cơ cấu dữ liệu:
Đối với array, các phần tử được xếp liên tục nhau trong bộ nhớ. Hàm (), tức là hàm dùng chỉ số để tìm phần tử, sử dụng con toán nhân trực tiếp (nhân chỉ số với số bytes của loại dữ liệu) để biết offset giữa phần tử này và phần tử đầu mảng.
Đối với danh sách liên kết hay liinked list, các phần từ không được xếp liên tục nhau trong bộ nhớ. Chúng liên hệ với nhau bằng cách mỗi phần tử (gọi là nút) chứa một con trỏ cho biết địa chỉ của phần tử kế nó. DSLK chỉ cần biết địa chỉ phần tử đầu tiên. Vì vậy DSLK không có con toán trực tiếp liên hệ giữa chỉ số và địa chỉ phần tử. Hàm () phải phăng từ phần tử đầu tiên cho đến phần tử cần kiếm.
Đối với bảng tra (indexed table), các phần tử cũng không liên tục nhau trong bộ nhớ. Hệ thống dùng một bảng tra (thường là bảng b-tree) để chứa địa chỉ từng phần tử. Đối với loại này, năng lượng xoá phần tử liên hệ trực tiếp đến sự cân bằng của bảng tra chứ không quan hệ mấy với vị trí phần tử.