使用搜索时提高excel vba的性能

我在两张纸上有40万条记录,每页有5列,其中A列中的数据是唯一标识符。两张纸上的列顺序相同。我正在尝试搜索Sheet1中存在的记录并在Sheet2中找到它。如果找到,则需要将该记录的数据与sheet2中的数据进行比较。数据不匹配应突出显示sheet1中的单元格,并复制工作表3中的整行。

我的宏可以成功处理少量数据,但会被大数据挂起,而excel会自动关闭。

我尝试评论单元格的突出显示,并且仅复制该行并仅分隔25000条记录,但是可能会遇到与前面所述相同的性能问题。

Sub CompareSheets()

    Dim wS As Worksheet,wT As Worksheet,RS As Worksheet
    Dim intSheet1Column As Integer,i As Long,j As Long,k As Long,FoundRow As Long

    Set wS = ThisWorkbook.Worksheets("Sheet1")
    Set wT = ThisWorkbook.Worksheets("Sheet2")
    Set RS = ThisWorkbook.Worksheets("Sheet3")

    RS.Cells.ClearContents
    RS.Cells.Interior.Color = RGB(255,255,255)
    wS.Rows(1).EntireRow.Copy RS.Range("A1")

    On Error Resume Next
    For i = 2 To wS.UsedRange.Rows.Count
       For j = 2 To wT.UsedRange.Rows.Count
       If InStr(1,wT.Range("A" & j).Value,wS.Range("A" & i).Value) > 0 Then
                Match = "FOUND"
                FoundRow = j
       Exit For
       End If
       Next


       If Match = "FOUND" Then
           Copyflag = False
            For intSheet1Column = 2 To wS.UsedRange.Columns.Count
               If wS.Cells(i,intSheet1Column).Value <> wT.Cells(FoundRow,intSheet1Column).Value Then
                  wS.Cells(i,intSheet1Column).Interior.Color = RGB(255,0)
                  Copyflag = True
                  k = RS.UsedRange.Rows.Count
               End If
            Next
                  If Copyflag = True Then
                        wS.Rows(i).EntireRow.Copy RS.Range("A" & k + 1)
                  End If
       End If
    Next

    MsgBox "Validation Complete"
End Sub

Excel被吊死并自动关闭。

lucifer0777777777777 回答:使用搜索时提高excel vba的性能

使用.mat-icon { .no-theme { fill: inherit; } } 尝试此代码:

FIND
,

我注意到您的代码有几件事: 在这里:

            For intSheet1Column = 2 To wS.UsedRange.Columns.Count
               If wS.Cells(i,intSheet1Column).Value <> wT.Cells(FoundRow,intSheet1Column).Value Then
                  wS.Cells(i,intSheet1Column).Interior.Color = RGB(255,255,0)
                  CopyFlag = True
                  k = RS.UsedRange.Rows.Count
                  Exit For '<------ added
               End If
            Next

第一次输入if语句后,您还可以为其添加一个出口,因为CopyFlag不会得到任何更真实的结果。

接下来可能更重要的一点是,您不必在第二个if语句中重置Match,这意味着,在找到第一个匹配项之后,它将为每个后续后续语句进入If语句If Match="Found" Then i。那是故意的吗?如果没有,您可以添加以下内容:

       If Match = "FOUND" Then
           CopyFlag = False
            For intSheet1Column = 2 To wS.UsedRange.Columns.Count
               If wS.Cells(i,0)
                  CopyFlag = True
                  k = RS.UsedRange.Rows.Count
               End If
            Next
                  If CopyFlag = True Then
                        wS.Rows(i).EntireRow.Copy RS.Range("A" & k + 1)
                  End If
            Match="" '<------ added
       End If
,

我使用数组和用于搜索第二张工作表中ID的函数。如果对ID列进行了排序,我们可以做得更好。

Sub CompareSheets()

Dim sh1         As Worksheet
Dim sh2         As Worksheet
Dim sh3         As Worksheet
Dim arr1        As Variant
Dim arr2        As Variant
Dim Row1        As Long
Dim Row2        As Long
Dim Row3        As Integer
Dim o           As Long
Dim nOfColumns  As Integer
Dim myId        As String

Set sh1 = ThisWorkbook.Worksheets("Sheet1")
Set sh2 = ThisWorkbook.Worksheets("Sheet2")
Set sh3 = ThisWorkbook.Worksheets("Sheet3")

nOfColumns = 5
Row3 = 2

Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual

'Here I start from second row assuming there's columns header
With sh1
    arr1 = .Range(.Cells(2,1),.Cells(.Cells(.Rows.count,"A").End(xlUp).row,nOfColumns)).Value
End With

With sh2
    arr2 = .Range(.Cells(2,nOfColumns)).Value
End With

For Row1 = LBound(arr1,1) To UBound(arr1,1)

    myId = arr1(Row1,1) ' I assume that ID is in column 1
    Row2 = FindRow(arr2,myId)

    If Row2 < 0 Then
        ' Format the sh1 row not founded
        With sh1
            .Range(.Cells(Row1 + 1,.Cells(Row1 + 1,UBound(arr1,2))).Interior.Color = vbGreen
        End With
        ' Put the row not founded in sh3
        With sh3
            For o = LBound(arr1,2) To UBound(arr1,2)
                .Cells(Row3,o).Value = arr1(Row1,o)
            Next o
            Row3 = Row3 + 1
        End With
    End If

Next Row1

Application.ScreenUpdating = True
Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic

Erase arr1
Erase arr2
Set sh1 = Nothing
Set sh2 = Nothing
Set sh3 = Nothing

End Sub

Function FindRow(ByRef myArray As Variant,_
            ValueToSearch As Variant,_
            Optional IndexToSearchIn As Long = 1) As Long

FindRow = -1
If Not IsArray(myArray) Then Exit Function

Dim lB          As Long
Dim uB          As Long
Dim Counter     As Long

lB = LBound(myArray,1)
uB = UBound(myArray,1)

For Counter = lB To uB
    If myArray(Counter,IndexToSearchIn) = ValueToSearch Then
        FindRow = Counter
        Exit Function
    End If
Next Counter

End Function
本文链接:https://www.f2er.com/3167910.html

大家都在问