循环通过工作表删除重复项
Posted
技术标签:
【中文标题】循环通过工作表删除重复项【英文标题】:Looping through sheets removing duplicates 【发布时间】:2021-03-10 23:09:10 【问题描述】:我的代码似乎工作正常。我想检查改进、潜在错误和意外后果。
我有包含重复信息的电子表格,有些电子表格每个文件中有 100 张。
我不想使用删除重复信息手动浏览每张工作表。
经过搜索,我认为我有一个解决方案。
Sub RemoveDuplicates()
' RemoveDuplicates Macro
' Selects all values then removes duplicates
'
' Declare Current as a worksheet object variable.
Dim Current As Worksheet
Dim starting_ws As Worksheet
Set starting_ws = ActiveSheet 'remember which worksheet is active in the beginning
' Loop through all of the worksheets in the active workbook.
For Each Current In Worksheets
Current.Activate
LastRow = Cells(Rows.Count, "A").End(xlUp).Row
ActiveSheet.Range("A1" & LastRow).RemoveDuplicates Columns:=Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11), Header:=xlYes
Next
starting_ws.Activate 'activate the worksheet that was originally active
End Sub
我只在每张工作表上寻找重复项,而不是比较工作表。列数也将保持不变。
【问题讨论】:
提供一张示例电子表格的图片有助于更好地理解您所指的重复值。 【参考方案1】:删除重复项(多列和工作表)
使用Option Explicit
。
这个ActiveSheet.Range("A1" & LastRow)
肯定是错的。考虑一下。
您必须符合Range
、Cells
、Rows
和Columns
的条件,例如Current.Cells
, Current.Rows.Count
...
您不必激活Current
。 Current
在您的情况下是 ActiveSheet
(因为您已激活它),因此无需使用 ActiveSheet
代替。
不要让Excel
定义范围:您自己定义。
带问题的代码
Option Explicit
Sub removeDupes()
' Here's a question:
' Why can't I use 'Cols' instead of the array written explicitly?
Dim Cols As Variant
Cols = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)
Const FirstAddress As String = "A1"
Dim wb As Workbook
Set wb = ActiveWorkbook
Dim ws As Worksheet
Dim LastCell As Range
For Each ws In wb.Worksheets
Set LastCell = ws.Cells(ws.Rows.Count, "A").End(xlUp).Offset(, 10)
ws.Range(FirstAddress, LastCell).RemoveDuplicates _
Columns:=Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11), Header:=xlYes
' This doesn't work.
'ws.Range(FirstAddress, LastCell).RemoveDuplicates _
Columns:=Cols, Header:=xlYes
' Try this with ByVal array.
'ws.Range(FirstAddress, LastCell).RemoveDuplicates _
Columns:=(Cols), Header:=xlYes
Next
End Sub
【讨论】:
非常感谢。刚刚查看了 Option Explicit 是什么,非常有用,它认为我确实在我所指的代码示例中看到了它。我明白你的意思是引用一个单元格然后引用一行。我一直在使用当前的活动表进行切割和更改,我理解我的错误。而且我确实觉得很奇怪,您必须对列使用显式数组。所以我从你的例子中假设使用 ws.Rows.Count 将只计算其中包含数据的行?再次感谢您的出色回复, 由于Excel 2007
,ws.Rows.Count
(工作表中的Rows.Count
)表示行1048576
,所以它实际上是A
列中的最后一个单元格:单元格A1048576
。只有 End(xlUp) '跳转'到最后一个非空单元格。相当于按CRTL
+UP
。最后Offset(, 10)
或Offset(0, 10)
表示向右十列以确定同一行但在列K
中的单元格,因此在下一行(ws.Range(FirstAddress, LastCell)...
)中我们可以定义完整范围:从@987654349 @.
非常感谢!这完全清楚地解释了这些人在做什么。感谢您帮助像我这样的 vba 初学者。 @VBasic2008
@VBasic2008 我相信在方法结束时将对象设置为空是一种很好的做法。例如,就在上面的 End Sub 之前,您可以输入以下代码: Set wb = Nothing: Set ws = nothing
感谢您的关注,但这是不可能的:Have a read。此外,我已批准您的编辑,但仍未测试是否需要像 Variatus 在his answer 中建议的那样从零开始的数组到 如何使用动态列数组从 Excel 工作表中删除重复行? .以上是关于循环通过工作表删除重复项的主要内容,如果未能解决你的问题,请参考以下文章