我有2张床,每张都有一张桌子。一个包含原始数据(2000多行),另一个包含我想从原始数据中删除的数据(500行左右)。我有以下代码来执行此操作,但它相当慢,我相信它可以更快:
Dim r As Range
Dim wsOriginal As Worksheet, wsDelete As Worksheet
Dim str As String
Dim i as Long
Set wsOriginal = ThisWorkbook.Sheets("List")
Set wsDelete = ThisWorkbook.Sheets("PermaDelete")
For i = wsDelete.UsedRange.Rows.Count To 2 Step -1
str = wsDelete.Cells(i, 1).Value & wsDelete.Cells(i, 2).Value & wsDelete.Cells(i, 3).Value & wsDelete.Cells(i, 4).Value & wsDelete.Cells(i, 5).Value
Set r = wsOriginal.Columns(30).Find(str, , xlValues, xlWhole, xlByRows, xlNext) ' Column 30 on original has concatenation of the required 5 rows, to match form of str
If Not r Is Nothing Then
Do
wsOriginal.Rows(r.Row).EntireRow.Delete
Set r = wsOriginal.Columns(30).Find(str, , xlValues, xlWhole, xlByRows, xlNext)
Loop Until r Is Nothing
End If
Next i
因此,我遍历wsDelete
中的每一行,然后使用.Find
在较大的wsOriginal
中找到一行。如果找到它,则删除它并再次查找同一行(因为少数人会在多行中复制此信息)。对我来说,这听起来像是更快的方式(而不是循环通过wsOriginal
),但代码本身似乎需要相当长的时间(2-3分钟)。我使用.ScreenUpdating
和.EnableEvents
的常用技巧也设置为false。
我还能如何优化它以减少等待时间?
答案 0 :(得分:0)
我最近在这里回复了一篇类似的帖子:Need suggestions on how to speed up this bit of code [duplicate]
这要在循环之前进行:
Dim rng As Range
Set rng = Nothing
循环中的而不是行删除执行此操作:
If rng is Nothing Then
rng = wsOriginal.Cells(r.Row, 1)
Else
rng = Union(rng, wsOriginal.Cells(r.Row, 1))
End If
然后在循环结束后:
rng.EntireRow.Delete
修改强>
修正上面的错字,道歉,绕过.Find
位:
在您set r
之后添加一行:firstAddress = r.Address
并将Loop Until
更改为Loop While Not r Is Nothing And r.Address <> firstAddress
这里有很好的解释:Range.Find Method (Excel)
答案 1 :(得分:-1)
这有一个非常简单的解决方法。 Excel的REMOVE DUPLICATE逻辑用于删除电子表格中显示较低的副本。
如果要删除工作表1中显示的工作表2中的所有项目,只需将工作表2中的项目粘贴到工作表1的顶部,运行该列的REMOVE DUPLICATE函数,然后删除所有项目来自第2页。
这很容易。