如果条目重复另一个表,从表中删除行

自从我和VBA一起工作了一段时间,所以我忍受了,因为我可能有点生疏。

我有2桌子。 一个是我所说的“已删除”列表,其中有几列,另一个是更详细的列表,包含所有细节。 我想要做的是在“已删除”列表中查找项目(见表1),如果一行中的所有项目都与主列表中的相关项目匹配(请参见表2),则删除该行。 我不能只做第一栏,因为数据结构不是很好。

表1(删除)

+-------------------+---------+-----------------+-----------------------+----------+ | Name | Source | Tel No | Address 1 | Postcode | +-------------------+---------+-----------------+-----------------------+----------+ | AN OTHER | MySrc | 01234 123456 | 18 FAKE STREET | XXX XXXX | | AN OTHER | MySrc2 | 01234 567890 | 29 FAKE STREET | XXX XXXX | +-------------------+---------+-----------------+-----------------------+----------+ 

表2(主)

 +---------------+-------+-----------+-----------+---------------+-------------+-------------------+----------------+----------------+----------------+----------+-------------+-------------+--------+--------+--------+--------+--------+--------+------------+--------+ | Name | Title | Full Name | Job Title | Tel No | Tel No 2 | Address Line 1 | Address Line 2 | Address Line 3 | Address Line 4 | Postcode | Data 1 | Data 2 | Data 3 | Data 4 | Data 5 | Data 6 | Data 7 | Data 8 | Date Added | Source | +---------------+-------+-----------+-----------+---------------+-------------+-------------------+----------------+----------------+----------------+----------+-------------+-------------+--------+--------+--------+--------+--------+--------+------------+--------+ | AN OTHER | | Person A | | 01234 123456 | | 18 FAKE STREET | | | | XXX XXXX | | | | | | | | | | MySrc | | AN OTHER | | Person B | | 01234 999999 | | 18 FAKE STREET | | | | XXX XXXX | | | | | | | | | | MySrc | |... about another 5000 rows... +---------------+-------+-----------+-----------+---------------+-------------+-------------------+----------------+----------------+----------------+----------+-------------+-------------+--------+--------+--------+--------+--------+--------+------------+--------+ 

正如你所看到的,它应该删除第1行,但离开第2行。

我有我写的下面的VBA代码,它目前find的重复仅基于一列存在的行。

 Sub createFinalList() Dim rng As Range, Dim r As Range Dim wsFinal As Worksheet, wsOriginal As Worksheet, wsDelete As Worksheet Set wsFinal = ThisWorkbook.Sheets("FinalList") Set wsOriginal = ThisWorkbook.Sheets("List") Set wsDelete = ThisWorkbook.Sheets("PermaDelete") For i = wsDelete.UsedRange.Rows.Count To 2 Step -1 Set r = wsOriginal.Columns(1).Find(wsDelete.Cells(i, 1).Value, , xlValues, xlWhole, xlByRows, xlNext) If Not r Is Nothing Then firstA = r.Address Set rng = Nothing Do If rng Is Nothing Then Set rng = wsOriginal.Rows(r.Row) Else Set rng = Union(r, rng) End If Set r = wsOriginal.Columns(1).Find(wsDelete.Cells(i, 1).Value, r, xlValues, xlWhole, xlByRows, xlNext) Debug.Print r.Address Loop Until firstA = r.Address End If Next i End Sub 

我之前想要做的是在删除最终结果之前使用。在rng查找每个后续列,但似乎应该有一个更简单的方法。 我错过了一个把戏吗? 有没有更简单的方法来做到这一点?

如果您的“已删除”数据与“主”数据完全一致,则可以使用AdvancedFilter 。 在这里阅读更多关于高级filter的信息: http : //www.excel-easy.com/examples/advanced-filter.html HTH

 Sub createFinalList() Dim mainSheet As Worksheet Dim criteriaSheet As Worksheet Set mainSheet = ThisWorkbook.Worksheets("Main") Set criteriaSheet = ThisWorkbook.Sheets("Deleted") Dim mainRange As Range Dim criteriaRng As Range Set mainRange = mainSheet.Range("A2:U3") Set criteriaRng = criteriaSheet.Range("A1:E3") mainRange.AdvancedFilter _ Action:=xlFilterInPlace, _ criteriaRange:=criteriaRng, _ Unique:=False ' Delete rows hidden by advanced filter Dim myRow As Range Dim toDelete As Range For Each myRow In mainRange.Rows If myRow.EntireRow.Hidden Then If toDelete Is Nothing Then Set toDelete = myRow Else Set toDelete = Union(toDelete, myRow) End If End If Next If Not toDelete Is Nothing Then _ toDelete.Delete End Sub 

你可以做一个非VBA的方法? 你总是看到同样的列?

  • 在“已删除”表格“= a1&b1&c1”中创build所有列的复合列…
  • 在主表上做一个类似的“查找”列
  • 在主表中添加一个标志列做一个vlookup“= vlookup(c1,deletedrowslookupcolumn,1,false)”
  • 过滤您的国旗列
  • 删除过滤的行

通过与@mlinth相同的结论,我得到了这个工作,并在.Find方法中使用了一个串联的string。 我在表2的末尾添加了一列,它是按照表1的顺序连接所需的列。同样,我可以在那里删除整行,然后修改我的.Find语句循环,所以它不再从r (刚刚被删除)开始

 Dim r As Range Dim wsOriginal As Worksheet, wsDelete As Worksheet Set wsOriginal = ThisWorkbook.Sheets("List") Set wsDelete = ThisWorkbook.Sheets("PermaDelete") Dim str As String 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) Do until r Is Nothing Then wsOriginal.Rows(r.Row).EntireRow.Delete Set r = wsOriginal.Columns(30).Find(str, , xlValues, xlWhole, xlByRows, xlNext) Loop Next i