Excel 我的匹配功能花费的时间太长(3小时!!),需要其他推荐吗

Excel 我的匹配功能花费的时间太长(3小时!!),需要其他推荐吗,excel,vba,Excel,Vba,正如标题所说,匹配函数花费的时间太长。一个电子表格有100000行长,它有一堆证券,我需要确保它们在另一个有800000行的电子表格上。代码如下: 仅供参考,我在代码构建方面一般,所以我在阐述我的论点方面相当初级 Option Explicit 'a lot of dims StartTime = Timer Set ShVar = ThisWorkbook.Worksheets("in1") With wnewwqr Set OutShVar = wnewwqr.Work

正如标题所说,匹配函数花费的时间太长。一个电子表格有100000行长,它有一堆证券,我需要确保它们在另一个有800000行的电子表格上。代码如下:

仅供参考,我在代码构建方面一般,所以我在阐述我的论点方面相当初级

 Option Explicit
 'a lot of dims
 StartTime = Timer

 Set ShVar = ThisWorkbook.Worksheets("in1")


With wnewwqr
    Set OutShVar = wnewwqr.Worksheets("First Sheet")
    Set RngConcat = OutShVar.Range("B:B")
    Set RngConcatISIN = OutShVar.Range("A:A")
    Set OutShVar1 = wnewwqr.Worksheets("Second Sheet")
    Set RngConcat1 = OutShVar1.Range("B:B")
    Set RngConcatISIN1 = OutShVar1.Range("A:A")
End With

With ShVar
    lastrow = .Cells(.Rows.Count, "H").End(xlUp).Row
 End With

 For i = 2 To lastrow
     With ShVar

         If .Range("O" & i).Value = "" Then     
             .Range("P" & i & ":Q" & i).Value = "No Security"   'Checking for no securities
         Else
             If Not IsError(Application.Match(.Range("O" & i).Value, RngConcat, 0)) Then
                 .Range("P" & i).Value = "US"     ' writing US when it finds a US security in the confidential workbook
             Else
                 .Range("P" & i).Value = "Not a US Security"
             End If
         End If
         If .Range("P" & i).Value = "Not a US Security" Then
             If Not IsError(Application.Match(.Range("O" & i).Value, RngConcat1, 0)) Then        'Only searching for securities if the first vlookup resulted in nothing and then it would go into the second sheet
                 .Range("Q" & i).Value = "US"
             Else
                 .Range("Q" & i).Value = .Range("P" & i).Value
             End If
         End If
     End With
 Next i



SecondsElapsed = Round(Timer - StartTime, 2)
'Notify user in seconds
MsgBox "This code ran successfully in " & SecondsElapsed & " seconds", vbInformation
End Sub
更新:

我已经把一切都变成了variant,现在使用find函数,但仍然没有我希望的那么快。对2000行进行试运行大约需要14分钟。我必须在90000行上这样做

Option Explicit
Sub something
Dim lastrow As Long
Dim OutShVar As Worksheet
Dim ShVar As Worksheet
Dim WhatCell As Range
Dim i As Long
Dim TaskID As Variant
Dim confidentialfp As String
Dim confidential As String
Dim wconfidential As Workbook
Dim x As Variant

Set ShVar = ThisWorkbook.Worksheets("in1")

With ShVar
lastrow = .Cells(.Rows.Count, "H").End(xlUp).Row
End With

 confidential = "confidential_2018-03-01 (Consolidated).xlsx"


Set wconfidential = Workbooks(confidential)

With wconfidential
Set OutShVar = .Worksheets("First Sheet")
End With

 With ShVar
 For i = 1 To lastrow
 TaskID = ShVar.Range("O" & i).Value
Set x = .Range("A" & i)
 Set WhatCell = OutShVar.Range("B:B").Find(TaskID, lookat:=xlWhole)
On Error Resume Next
x.Offset(0, 7).Value = WhatCell.Offset(0, 1)
Next i
End With

End Sub

我不确定你是否完全理解ScottCraner的观点。他说的是,你应该将所有的参考值(即证券的大列表)读入几个数组,然后将输出值写入另一个数组。然后在一个命令中将整个输出数组写入工作表

还值得您将证券列表转换为
集合
,因为它具有非常快速的“查找”功能。有很多方法可以加快速度,比如对证券进行排序,但是你需要学习一些数学知识

在下面的示例中,此框架代码显示了如何执行此操作。你应该知道,我没有费心把两个证券列表分成两个集合,所以如果你需要的话,你应该自己做。我还将所有测试表放在同一工作簿上,因此根据需要调整工作表限定符:

Option Explicit

Sub RunMe()
    Dim securities As Collection
    Dim testSheet As Worksheet
    Dim testItems As Variant
    Dim i As Long
    Dim exists As Boolean
    Dim output() As Variant

    'Read the first list of securities into the collection.
    PopulateColumnCollection _
        ThisWorkbook.Worksheets("First Sheet"), _
        "B", _
        securities

    'Read the second list of securities into the collection.
    'I've used the same collection in this example, you'll need
    'to create two if you want separate columns in your output.
    PopulateColumnCollection _
        ThisWorkbook.Worksheets("Second Sheet"), _
        "B", _
        securities

    'Read the test items into an array.
    Set testSheet = ThisWorkbook.Worksheets("in1")
    With testSheet
        testItems = RangeTo2DArray(.Range( _
            .Cells(2, "O"), _
            .Cells(.Rows.Count, "O").End(xlUp)))
    End With

    'Prepare your output array.
    'I've just used one column for output. If you want two then
    'you'll need to resize the second dimension.
    ReDim output(1 To UBound(testItems, 1), 1 To 1)

    'Populate the output array based on the presence of
    'a matching security.
    For i = 1 To UBound(testItems, 1)
        If IsEmpty(testItems(i, 1)) Then
            output(i, 1) = "No Security"
        Else
            exists = False: On Error Resume Next
            exists = securities(CStr(testItems(i, 1))): On Error GoTo 0
            output(i, 1) = IIf(exists, "US", "Not a US Security")
        End If
    Next

    'Write the output array to your sheet.
    testSheet.Cells(2, "P").Resize(UBound(output, 1), UBound(output, 2)).Value = output
End Sub

Private Function RangeTo2DArray(rng As Range) As Variant
'Helper function to read range values into an array.

    Dim v As Variant
    Dim arr(1 To 1, 1 To 1) As Variant

    v = rng.Value2
    If Not IsArray(v) Then
        arr(1, 1) = v
        RangeTo2DArray = arr
    Else
        RangeTo2DArray = v
    End If
End Function
Private Sub PopulateColumnCollection(ws As Worksheet, columnIndex As String, col As Collection)
'Helper sub to read a column of values into a collection.
    Dim rng As Range
    Dim v As Variant
    Dim i As Long

    With ws
        Set rng = .Range( _
            .Cells(1, columnIndex), _
            .Cells(.Rows.Count, columnIndex).End(xlUp))
    End With
    v = RangeTo2DArray(rng)

    If col Is Nothing Then Set col = New Collection

    On Error Resume Next 'this avoids duplicates.
    For i = 1 To UBound(v, 1)
        col.Add True, CStr(v(i, 1))
    Next

End Sub

将所有内容更改为变量数组,并循环那些不是范围的数组。用输出加载另一个数组,并一次性发布结果。为什么要在同一行中循环两次?例如,在运行宏之前,
P
列的值是否为“非美国证券”?当我编写该列时,我假设它在进入下一部分之前已经编写了“非美国证券”。Scott-我正在寻找阵列它可能有助于为每一组3列列出业务规则-从包含的代码中看它不是非常清楚。@ScottCraner我已将所有内容更改为variant,请参阅更新,但仍然没有我希望的那么快。任何建议以前从未使用过此方法。让我试试这个,然后再打给你。非常感谢你在这里的帮助,我的上帝,工作得很有魅力。我需要达到这个水平,这很好。让我们知道你对这需要多长时间的感觉。正如我所说的,如果你想走得更快——快得多——那么你可以对所有证券的列表进行排序,并恢复到数组。10秒后,我按照自己的方式修改了它。速度完全符合我们的要求。你好,Ambie,很抱歉再次提出这个问题,你知道我是否可以在此声明中添加一个vlookup: