Excel / VBA检查是否存在行

时间:2009-05-14 16:12:53

标签: performance excel vba excel-vba

我有一张包含一些原始数据的表格,大约20,000行和50列。 (预计增加的行数,如果不是三倍,则可能增加一倍)

我需要一个公式来查看此数据,并确定两个指定列中的数据是否存在行。我目前的公式如下。

Function CheckExists(Table As Range, SearchCol1 As Integer, SearchVal1 As Variant, SearchCol2 As Integer, SearchVal2 As Variant)

    Dim i As Long
    Dim exists As Boolean

    exists = False

    For i = 1 To Table.Rows.Count
        If Table.Cells(i, SearchCol1) = SearchVal1 Then
            If Table.Cells(i, SearchCol2) = SearchVal2 Then
                exists = True
                Exit For
            End If
        End If
    Next i

    CheckExists = exists

End Function

我从另一张表中运行这个公式,大约有5000行。

我的问题是,这会杀死我的电脑,计算细胞需要很长时间。我希望有人可以提供一些关于如何更快或更好的建议,一个内置的公式,可以做我想要的。

6 个答案:

答案 0 :(得分:3)

您可以使用简单的if公式(例如

)在原始数据的末尾添加一列
if(AND(A1=4, B1=6), 1, 0)

其中A1 / B1是要检查的列,4和6将被实际值替换。检查是否存在行只是检查此列的总和:

if(sum(C:C) > 0, TRUE, FALSE)

其中C是具有公式的列。在大型Excel文档中,我通常会发现这样的复合方法最有效。如果您发布数据样本,我可以进一步细化。

答案 1 :(得分:2)

如果您使用Cells.Find,它将为您节省大量迭代从不包含您想要的值的单元格。

e.g。

Cells.Find(What:="-1", After:=ActiveCell, LookIn:=xlValues, LookAt:= _
      xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False _
      , SearchFormat:=False).Activate

将激活它找到值的单元格。然后,您可以检查您正在比较的其他单元格是否具有正确的值(如果找到了单元格)。

您可能还需要检查您所在的行/列是否是您要查找的值的正确行,尤其是当您搜索的数字为20时,它会找到数字20在错误的一行。

有一个游戏,我认为你会发现它比正常的迭代要快得多。

额外的,可能没有根据的建议:如果有这么多数据,数据库会不会有用吗?

<强>更新
我有一个快速的游戏 - 这个功能可以取代你上面使用的现有功能,让我知道它是否更快。

Function FindCheckExists(Table As Range, SearchCol1 As Integer, _
                         SearchVal1 As Variant, SearchCol2 As Integer, _
                         SearchVal2 As Variant)

    Dim i As Long
    Dim exists As Boolean
    Dim result As Range

    exists = False
    Do While (Not exists)

        Set result = Cells.Find(What:=SearchVal1, After:=Cells(1, SearchCol1), _
          LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, _
          SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False)

        If (result Is Nothing) Then Exit Function

        If result.Offset(0, (SearchCol2 - SearchCol1)).Value = SearchVal2 Then _
            exists = True

    Loop

    FindCheckExists = exists

End Function

上面的内容已经重新格式化为_以便在stackoverflow页面上更合适,如果没有它们,它可能看起来更整洁。

答案 2 :(得分:2)

我建议添加一列来连接两个感兴趣的列中的值,然后使用MATCH工作表函数搜索新列。

答案 3 :(得分:1)

没有必要使用VBA来实现这一点 - 你可以只使用常规的前端公式。下面的公式(第一个只执行1-5000行,但第二个将执行整个列)将确定相关组合是否存在:

=SUMPRODUCT(--(A1:A5000="SearchValue1"),--(B1:B5000="SearchValue2"))

=SUMPRODUCT(--(A:A="SearchValue1"),--(B:B="SearchValue2"))

要使用它,您只需将“SearchValue1”和“SearchValue2”修改为您要查找的值,如果您不使用A和B,则更改列字母。

答案 4 :(得分:1)

我说的很像rwmnau,除了我一般使用:

=SUMPRODUCT((A1:A5000="SearchValue1")*(B1:B5000="SearchValue2"))  

编辑如果使用Excel 2007,则可以使用COUNTIFS功能(注意最后的S)。

答案 5 :(得分:0)

我发现使用自动过滤最快。根据您的条件对其进行过滤,然后删除剩余的可见行。

e.g。 Ws.Rows(1).Insert 'Filter does not check first row Ws.AutoFilterMode = False Ws.Cells.AutoFilter searchCol1, "=*" & searchVal1 & "*", , , False Ws.Cells.AutoFilter searchCol2, "=*" & searchVal2 & "*", , , False Ws.AutoFilter.Range.SpecialCells(xlCellTypeVisible).EntireRow.Delete ActiveSheet.AutoFilterMode = False

希望有所帮助。