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