需要Excel VBA中最快的搜索方法吗

需要Excel VBA中最快的搜索方法吗,vba,excel,Vba,Excel,考虑一个场景,我有两列(a列和B列) 列A大约有130000行/字符串 列B大约有10000行/字符串 我想从列“A”中搜索列“B”的每个字符串 如您所见,数据量非常大。我已经尝试了Range.Find()方法。但这需要很多时间才能完成。我正在寻找一种方法/途径,使我能够在更短的周转时间内完成任务 *关于我的要求的更多说明* (1) 列A和B包含字符串值,而不是数字。绳子可以很大 (2) 对于“B”列中的每个单元格,“A”列中可能会出现很多次 (3) 我想获取列“A”中出现的所有列“B”的行号

考虑一个场景,我有两列(a列和B列)

列A大约有130000行/字符串 列B大约有10000行/字符串

我想从列“A”中搜索列“B”的每个字符串

如您所见,数据量非常大。我已经尝试了Range.Find()方法。但这需要很多时间才能完成。我正在寻找一种方法/途径,使我能够在更短的周转时间内完成任务

*关于我的要求的更多说明*

(1) 列A和B包含字符串值,而不是数字。绳子可以很大

(2) 对于“B”列中的每个单元格,“A”列中可能会出现很多次

(3) 我想获取列“A”中出现的所有列“B”的行号

(4) 对于“B”列中的字符串。它可以作为列“a”中任何单元格的子字符串找到


下载文件链接-wikisend.com/Download/431054/StackOverFlow_Sample.xlsx*

有什么建议吗

请放心,如果您需要任何额外的细节来解决上述问题

试试这个

对于A列中的
130000行和B列中的
10000行,这花费了
3
秒。输出在
列C
中生成

注意:我采用了
最坏的情况,即B列中的所有
10000
值都出现在A列中

这就是我的数据的外观

Sub Sample()
    Debug.Print Now

    Dim col As New Collection
    Dim ws As Worksheet
    Dim i As Long

    Set ws = ThisWorkbook.Sheets("Sheet1")

    Application.ScreenUpdating = False

    With ws
        .Range("C1:C10000").Value = "No"

        For i = 1 To 130000
            On Error Resume Next
            col.Add .Range("A" & i).Value, CStr(.Range("A" & i).Value)
            On Error GoTo 0
        Next i

        On Error Resume Next
        For i = 1 To 10000
            col.Add .Range("B" & i).Value, CStr(.Range("B" & i).Value)
            If Err.Number <> 0 Then .Range("C" & i).Value = "Yes"
            Err.Clear
        Next i
    End With

    Application.ScreenUpdating = True

    Debug.Print Now
End Sub

子样本()
调试,现在打印
Dim col作为新系列
将ws设置为工作表
我想我会坚持多久
设置ws=ThisWorkbook.Sheets(“Sheet1”)
Application.ScreenUpdating=False
与ws
.范围(“C1:C10000”).Value=“否”
对于i=1至130000
出错时继续下一步
列添加范围(“A”&i).Value,CStr(.Range(“A”&i).Value)
错误转到0
接下来我
出错时继续下一步
对于i=1到10000
列添加范围(“B”和i).Value,CStr(.Range(“B”和i).Value)
如果错误号为0,则为范围(“C”和i).Value=“是”
呃,明白了
接下来我
以
Application.ScreenUpdating=True
调试,现在打印
端接头
这就是结果

新的 A列130000 100个字符串,B列10000 30个字符串,27分钟

列C由列B字符串出现的行位置填充。 列D填充了列B字符串的出现次数

Public Sub searchcells()
    Dim arrA(1 To 130000) As String, arrB(1 To 10000) As String, t As Date, nLen As Integer
    t = Now
    Me.Range("c:d") = ""

    For i = 1 To 130000
        arrA(i) = Me.Cells(i, 1)
    Next
    For i = 1 To 10000
        arrB(i) = Me.Cells(i, 2)
    Next

    For i = 1 To 130000
        nLen = Len(arrA(i))
        For j = 1 To 10000
            If InStrRev(arrA(i), arrB(j), nLen - Len(arrB(j)) + 1) > 0 Then Me.Cells(j, 4) = Me.Cells(j, 4) + 1: Me.Cells(j, 3) = Me.Cells(j, 3) & i & "; "
        Next
        Me.Cells(1, 5) = i
    Next

    Debug.Print CDbl(Now - t) * 24 * 3600 & " seconds"
End Sub
单元格可以很容易地填充以下内容,更改每个部分中所需字符串数量和字符串长度的i和j限制

Public Sub fillcells()
    Dim temp As String
    Randomize

    For i = 1 To 13000
        temp = ""
        For j = 1 To 100
            temp = temp & Chr(70 + Int(10 * Rnd()))
        Next
        Me.Cells(i, 1) = temp
    Next
    For i = 1 To 10000
        temp = ""
        For j = 1 To 30
            temp = temp & Chr(70 + Int(10 * Rnd()))
        Next
        Me.Cells(i, 2) = temp
    Next
End Sub

我无法在工作时下载您的电子表格,因此,如果它没有达到要求,请忽略此项。

这取决于您的排序标准。。。也许你可以发布更多的信息和/或代码。嗯,怎么样?@Me我是如何尝试你的代码的,它已经运行了20多秒,我不得不结束它。也许我做错了什么。你想为我拼凑的数据尝试一下你的代码吗?这里不同方法的比较:虽然没有包括@SiddharthRout发布的收集方法,所以这是一个很好的补充…a列和B列中字符串的平均长度是多少?我在工作中无法访问您的电子表格,我正在测试一些解决方案。@SamWard:是的,
Countif/Vlookup/Find
在如此庞大的范围内造成了巨大的破坏,所以我开始收集这些数据。更不用说,在最坏的情况下是3秒钟;)+1设计良好的代码和良好的方法。通过
.Range(“A”&i).Value进行不必要的强制转换,CStr(.Range(“A”&i).Value)
作为
.Range(“A”&i)
默认属性为Value。值得注意的是。尝试不使用显式强制转换,而是在顶部添加选项CompareText:)看看是否可以获得额外的秒数hehe@mehow:是的。但是我完全限定了我的代码,即使它是默认属性。旧习难改;)就价值达成一致。@SiddharthRout-感谢您提供了快速而有趣的解决方案。但我不会在“A”或“B”列中有数字。它们可以有大的字符串。对于列“B”的每个值,列“A”中可能有许多匹配项,我想获取列“A”中列“B”的所有匹配项。我已经更新了我的问题。请查看更多详细信息。再次非常感谢:)@SiddharthRout-是的,我已经测试过了。它不起作用:(请你再看一遍我的问题。我在其中添加了更多的细节。谢谢你的回答。实际上每个字符串的长度都非常大。每个字符串的长度大约为100个字符。请尝试从下面的链接下载我的电子表格。*****wikisend.com/download/431054/StackOverFlow_Sample.xlsx****列B字符串也是~100个字符。)ters?我正在工作,无法从wikisend下载:(A列的所有单元格字符串长度=100&B列的所有单元格长度都在30左右哈哈,慢多了!~27个小时。好吧,通过不检查B列字符串的长度,将时间缩短到27分钟。