使用VBA删除另一张出现在另一张上的数据

我有两张桌子上的每一张。 一个带有原始数据(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 。 如果发现它,然后删除它并再次查找相同的行(因为一些重复此信息跨越1行)。 对我来说,这听起来像更快的方法(而不是循环wsOriginal ),但代码本身似乎需要相当长的时间(2-3分钟)。 我正在使用.ScreenUpdating.EnableEvents常规技巧设置为false。

我还可以如何优化这个以减less等待时间?

我最近在这里回复了一个类似的post: 需要关于如何加快这段代码的build议[复制]

这在循环之前:

 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方法(Excel)

这是一个非常简单的解决方法。 Excel的REMOVE DUPLICATE逻辑是删除电子表格中较低的副本。

如果您要删除表单1中显示的表单2中的所有项目,只需将表单2顶部的项目粘贴到表单1的顶部,为该列运行REMOVE DUPLICATEfunction,然后删除表单2中的所有项目。

那样容易。