如何删除Excel中的SENSITIVE案例重复项(对于100k或更多记录)?

时间:2017-04-03 11:01:57

标签: excel excel-formula excel-2016

我已尝试使用此公式字段并复制到我拥有的所有> 100k记录。

  

= IF(SUMPRODUCT( - EXACT(A2,$ B $ 1:B1)), “”,A2)

其中:

  1. 列A =包含所有数据(包括重复项)的列
  2. 列B =显示数据的列(来自列A),如果唯一,则为空字符串
  3. 但是我遇到了这个问题:

    enter image description here

    是的,我的Excel 2016是32位,是的,我的笔记本电脑只有8GB RAM。但我已经读过64位和16GB RAM的人遇到了和我一样的错误。

    我知道Excel功能中有一个功能:数据>选择列>删除重复项。但是,此功能仅删除大小写INSENSITIVE数据。

    请告诉我如何克服这个问题。我愿意使用像Crystal Reports这样的东西或某种免费软件来解决这个问题。请指教。

3 个答案:

答案 0 :(得分:2)

您可以尝试这样的事情。 在尝试备份数据之前。 下面的代码将从A列中删除重复项,并且区分大小写。

Sub GetUniqueValues()
Dim x, dict
Dim lr As Long
lr = Cells(Rows.Count, 1).End(xlUp).Row
x = Range("A2:A" & lr).Value
Set dict = CreateObject("Scripting.Dictionary")
For i = 1 To UBound(x, 1)
    dict.Item(x(i, 1)) = ""
Next i
Range("A2:A" & lr).ClearContents
Range("A2").Resize(dict.Count).Value = Application.Transpose(dict.keys)
End Sub

已编辑的代码:

Sub GetUniqueValues()
Dim x, dict, y
Dim lr As Long
Application.ScreenUpdating = False

lr = Cells(Rows.Count, 1).End(xlUp).Row
x = Range("A2:A" & lr).Value
Set dict = CreateObject("Scripting.Dictionary")
For i = 1 To UBound(x, 1)
    dict.Item(x(i, 1)) = ""
Next i
ReDim y(1 To dict.Count, 1 To 1)

i = 0
For Each it In dict.keys
   i = i + 1
   y(i, 1) = it
Next it

Range("A2:A" & lr).ClearContents
Range("A2").Resize(dict.Count).Value = y

Application.ScreenUpdating = True
End Sub

答案 1 :(得分:0)

对于一般解决方案,已建议的VBA方法可能更喜欢。但是对于只能运行一次的东西,你可以按照预期的方式使它工作,只需稍加适应=IF(SUMPRODUCT(--EXACT(A2,$B$1:B1)),"",A2)的方式。我还尝试使用COUNTIF算法,它比SUMPRODUCT快得多,但这不区分大小写。

由于我还运行带有8GB内存的32位Excel,我很想知道是否可以复制内存问题。我在A列中生成了一个包含100,000个随机5个字母字符串的列表。只使用了10个字母(ABCDEFGHJK),因此在100,000个字符串中,有些字符会出现多次。然后,我在B列中应用OP建议的公式,仅过滤掉唯一值。它确实有效,但花了很长时间。但是我从来没有遇到OP所做的记忆问题。

提议的解决方案:
根据这些观察结果,一个可能解决您特定问题的方法可能是将A列复制到新的临时工作站,并在所有其他工作簿关闭时运行您的SUMPRODUCT公式。完成后,您只需将结果粘贴回原始文件中的原始列即可。实际上,删除重复项可以通过简单地过滤该列来完成,以便将所有dublicates(空单元格)组合在一起,然后删除这些行。我尝试复制的细节可以在下面找到。

SUMPRODUCT:大约1小时
首先,我尝试了与OP =IF(SUMPRODUCT(--EXACT(A2,$B$1:B1)),"",A2)中相同的公式,但一次只执行10,000行(通过在行10,000,20,000等处插入空行并一次复制一万行。)每组10,000行需要几分钟才能完成。当我将整个shebang作为所有100,000个单元格的一次巨大复制操作时,操作大约需要一个小时才能完成,而Excel在此期间没有响应。内存使用量为1.4 GB,CPU平均容量超过50%(使用Windows任务管理器监控)。当我已经以各种方式操作数据(因此消耗更多内存)时,我也尝试运行公式,这将CPU容量推高到100%并导致几次崩溃。我设法避免这种情况,只需关闭Excel以清除内存并从新重启中再次运行操作而不打开其他工作簿。

正如您在下面的屏幕截图中看到的那样,公式有效,唯一条目在列表中变得更加罕见(正如预期的那样,因为它们是随机的)。我将1分配给包含重复的单元格,这样我就可以轻松地计算它们。这种情况有36,843个。

第一行,没有重复: First rows

最后一行,主要是重复行(带有1的单元格): 100,000th row

COUNTIF:8.5分钟
与花费大约一个小时完成的SUMPRODUCT算法相比,以下COUNTIF公式仅在8,5分钟内完成了相同的工作,但它不区分大小写。此方法需要使用帮助列。 COUNTIF返回在当前单元格上方的范围内使用特定字符串的实例数,因此每次第一次遇到字符串时,它将返回1.单元格B2包含=COUNTIF($A$2:$A2,A2),并复制此所有10万行的时间大约需要8分半钟。然后,在一个单独的列中,我只使用一个简单的IF公式来过滤掉A列中的唯一值;单元格C2包含=IF(B2=1,A2,1),如果它是唯一的,则返回A列中的字符串;否则返回1(以便与SUMPRODUCT轻松比较)。将所有100,000行的IF公式复制下来几乎是瞬间完成的。在此操作之后,C列中的1的总和,令人放心,与SUMPRODUCT,36,843的情况相同。

索引:失败
我还使用INDEX和MATCH函数使用数组公式。此公式与COUNTIF执行相同的工作,但也过滤掉空行: =INDEX($A$2:$A$100001,MATCH(0,COUNTIF($E$1:E1,$A$2:$A$100001),0))。这应该作为数组公式(Ctrl + Shift + Enter)输入到单元格B2中,然后向下复制。一次复制一个单独的单元格可以正常运行几十行,但是除此之外的任何东西都会导致Excel崩溃。我甚至尝试过夜间运行,但操作从未完成。 (该公式可以扩展为区分大小写,但我没有费心去尝试。)

然而,有一点需要注意的是,失败的INDEX公式是当公式应用于单独的工作簿时,会发生上述行为。我还尝试在与DISO公式相同的工作簿中的D列中运行此公式。然后我确实遇到了OP中描述的内存问题,毫不奇怪,这表明内存问题取决于工作簿中的其余数据。

答案 2 :(得分:0)

使用排序功能获取唯一值。不需要图书馆。可以轻松转换以选择完整的行:

Sub GetUniqueValues()
    'Sort once so we can run through the list without nested loops
    Sheet1.Range("$A:$A").Sort Key1:=Sheet1.Range("$A:$A"), Header:=xlYes, MatchCase:=True
    count = Application.WorksheetFunction.CountA(Sheet1.Range("$A:$A"))
    LastCell = 1

    For i = 2 To count
        If Sheet1.Cells(i, 1).Value = Sheet1.Cells(LastCell, 1).Value Then
            'Remove second/third/fourth occurrences
            Sheet1.Cells(i, 1).Clear
        Else
            'If its first occurrence of this value, make a note of its position
            LastCell = i
        End If
    Next

    'Sort again to move the cells emptied out to the bottom
    Sheet1.Range("$A:$A").Sort Key1:=Sheet1.Range("$A:$A"), Header:=xlYes, MatchCase:=True
End Sub