RemoveDuplicates不按预期方式工作

我有一个从网站导出的大型数据集。 我在我的主要“filter”工作簿中使用macros来查找该文件,并将导出的文件Sheet 1中的数据复制到筛选器工作簿Sheet 1中。

将数据复制到filter工作簿的Sheet1中后,使用VBA将filter工作簿的Sheet 1中的A / B / D / F / H / Z / AA /等列复制到filter工作簿的Sheet2中,同时,我在此使用此代码尝试删除任何重复的行:

工作表(“Sheet2”)。范围(“A:DZ”)。RemoveDuplicates Columns:= 15,Header:= xlYes

我发现尽pipeRemoveDuplicates没有按预期工作。

例如,筛选器工作簿(和导出工作簿)中的Sheet1有3344行。 当我手动过滤使用条件格式来突出重复,我可以find314行被列为重复(意味着157真正的行数据和157行是实际数据的重复。我还没有发现任何重复存在的例子超过每次一次)。 所以在Sheet2上,我期待看到3344 – 157 = 3157行的实际数据。 我没有看到,甚至3030行(3344-314)。 相反,我得到1897行粘贴到Sheet2,这是1447行(比预期less1290行)的差异。

最重要的是,我手动检查数据以查看在列中使用Control-F的内容,并发现在某些情况下,两个重复的项目都从Sheet2中丢失(与它只是删除一个重复项行)。

重复的数据不在连续的行上,分散在Sheet2的整个列中。 但是,在我尝试删除重复文件之前对其进行sorting时,似乎不会影响其准确性或正确性。 我也试着在代码的不同位置使用DeleteDuplicates /在不同的时间,但结果总是以相同的数量(1447个缺less的行而不是157个缺失的行)closures。

我发现这个网站上只有一些文章,这是最接近但不是安静的我的问题: 删除行重复数据VBA

和其他帮助网站/论坛提到有一些与Office 2007中的错误,防止这个工作(我使用2013年)。

有没有人知道我可以find解决办法,或者如果存在的话 – 或者如果这仍然是一个真正的错误或只是我上面的代码行的问题。

Adding bits of code I use in this example in case it is something within these that is causing the problem… Part of the copy code: wsFromSheet.Cells.Copy wsToFile.Range("A1").PasteSpecial xlPasteValuesAndNumberFormats Application.CutCopyMode = False wbFromFile.Close True Part of the 'paste column code': Sheets("Sheet2").Rows(1 & ":" & Sheets("Sheet2").Columns.Count).ClearContents 'Clear from row 1 down LastRowFromSiteTracker = xSht.Cells.SpecialCells(xlCellTypeLastCell).Row 'original report has 128 columns xSht.Range("B1:B" & LastRowFromSiteTracker).Copy ySht.Cells(Rows.Count, "A").End(xlUp) 'customer name 'repeat a bunch of times, then… Application.CutCopyMode = False 'do I need this line? Worksheets("Sheet2").Range("A:DZ").RemoveDuplicates Columns:=15, Header:=xlYes End Sub Example/sample of data: Row Source Data Expected Data Actual Data 1 1000474608 1000474608 1000474608 (Dup missing from sheet2) 2 1000474608 1000487672 1000487672 3 1000487672 1000487674 1000487674 4 1000487674 1000487676 1000487676 (missing from sheet2, wasn't a dup) 5 1000487676 1000487678 1000487678 6 1000487678 1000487680 1000487680 7 1000487680 1000487682 1000487682 (Dup missing from sheet2) 8 1000487682 1000520278 1000520278 9 1000487682 1000520280 1000520280 10 1000520278 1000520282 1000520282 (Is there) 11 1000520280 1000520286 1000520286 12 1000520282 1000520336 1000520336 (Is there) 13 1000520282 1000520338 1000520338 14 1000520286 1000520392 1000520392 15 1000520286 1000520394 1000520394 16 1000520336 1000530333 1000530333 17 1000520338 18 1000520392 19 1000520394 20 1000530333 

编辑:编辑:编辑:所以我试图做一些更多的手动testing,并尝试两个单独的东西,相同的数据集,得到两个不同的结果。 我使用了“条件格式” – 突出显示主“主”function区中的“重复”和“数据”function区中的“删除重复”。

Remove Duplicatesbutton查找并删除列P中的163个项目,并留下3181行。

但是,当我使用突出显示重复条件格式查找P列中重复项314项,保留3030非重复项。

这两个数字不匹配是没有意义的。 我认为这与重复项本身有关 – 因为大部分重复的项目本身只有一个重复项(123123出现在两行中),但是只有很less的几行重复多次(234234显示在4或6中列)。

因此,不是使用手动方式,而是使用我在网上find的build议,这两种方法在运行时也提供了不同的结果:

 3344 Base records 1897 left after scrub of duplicates (1446 removed) Dim tmpAddress As String tmpAddress = "A2:BZ" & Worksheets("ColScrub").UsedRange.Rows.Count Worksheets("ColScrub").Range(tmpAddress).RemoveDuplicates Columns:=15, Header:=xlNo 3181 left after scrub of duplicates (162 removed) Cells.Select ActiveSheet.Range("$A$1:$EI$3345").RemoveDuplicates Columns:=31, Header:=xlYes 

1)你只是清理多less行,你有列,而不是行也可能不清除任何东西,所以使用UsedRange.Rows正确的行数

这条线…

 Sheets("Sheet2").Rows(1 & ":" & Sheets("Sheet2").Columns.Count).ClearContents 

应该读 …

 Sheets("Sheet2").Rows(1 & ":" & Sheets("Sheet2").UsedRange.Rows.Count).ClearContents 

如果没有正确清除旧的数据,可能会出现不可预知的结果。

2)Excel VBA看起来比较古怪,因为如果没有专门“select”有问题的对象并指定完整(不是列)范围,许多事情都不能正常工作

3)我也喜欢省略标题行(注意“A2”)并通过Header:= xlNo

4)除非你有625多列,否则BZ应该足够了

所以添加到您的代码…

 Dim tmpAddress as String tmpAddress = "A2:BZ" & Worksheets("Sheet2").UsedRange.Rows.Count Worksheets("Sheet2").Activate Worksheets("Sheet2").Range(tmpAddress).RemoveDuplicates Columns:=15, Header:=xlNo 

希望这可以帮助 :)

我不知道为什么(或如果/如何)这是什么不同,但这似乎是最接近我可以真正去除重复。 我想在这里添加它作为类似情况下的其他人的答案。

  Dim lastrow As Long With ThisWorkbook.Worksheets("ColScrub") If Application.WorksheetFunction.CountA(.Cells) <> 0 Then lastrow = .Cells.Find(What:="*", _ After:=.Range("A1"), _ Lookat:=xlPart, _ LookIn:=xlFormulas, _ SearchOrder:=xlByRows, _ SearchDirection:=xlPrevious, _ MatchCase:=False).Row 'Change P1 back to A1 if needed Else lastrow = 1 End If .Range("A1:AZ" & lastrow).RemoveDuplicates Columns:=Array(16), Header:=xlYes End With 

我必须通过视觉上的每一行来certificate我认为这是有效的,并且排除不删除不应该被删除的东西 – 但是这似乎消除了“双重复制”(4-6行项目而不是像其他重复2)。

现在我的进一步的经验表明,如果你有空白的行或列,UsedRange是完全不可靠的。 UsedRange只包含空白的行/列。 我find了一个更好的方法来获得最后的每一个。 这些函数使用2个基本假设,这对大多数电子表格都是适用的。

  1. 对于LastRow,有一个“关键”列,即一个必须是数据的列,例如一个ID列
  2. 对于LastCol应该有一个标题行(或行,你可以保证最后一列被填充)

考虑到这一点,我已经创build了以下2个函数来准确地检索最后的值,每次…几乎(我的完整函数处理合并单元格的页脚行的问题)

最后一行Public Function Excel_GetLastRow(xlSheet As Excel.Worksheet, _ ByVal KeyColumn As Long) As Long ' This could be adjusted for exact max rows Excel allows Const MAX_XL_ROWS As Long = 1048000 Excel_GetLastRow = xlSheet.Cells(MAX_XL_ROWS, KeyColumn).End(xlUp).row End Function

和最后一栏

 Public Function Excel_GetLastCol(xlSheet As Excel.Worksheet, _ ByVal HeaderRow As Long) As Long ' This could be adjusted for exact max columns Excel allows Const MAX_XL_COLS As Long = 16000 Excel_GetLastCol = xlSheet.Cells(MAX_XL_COLS, HeaderRow).End(xlToLeft).Column End Function 

使用这些值,您现在可以成功设置完整的数据范围。

左上angular=单元格(HeaderRow + 1,1)

右下angular= Cells(LastRow,LastCol)

我的完整function包括error handling和允许在页脚行和最后一个标题栏中的可能的合并单元格,但你明白了。

艺术