快速VBA listobject查找功能

时间:2018-12-13 16:47:18

标签: excel vba performance lookup-tables listobject

我有几张包含ListObjects的表

当我必须在listbject中寻找相应的值时,我要做的是:

dim mytable as Listobject
set mytable = thisworkbook.sheets(x).listobject(1)
ValuetoSearch="whatever"
valueResult=""
' looking for the corresponding value of column A in column B
for i=1 to mytable.listrows.count
    if mytable.listcolumns("A").databodyrange.item(i).value=ValuetoSearch then
       valueResult=mytable.listcolumns("B").databodyrange.item(i).value
       exit for
    end if
next i

那行得通。精细。 但是:

这是最快的搜索方式吗? 当用户在工作表中选择某些单元格(使用工作簿更改选择)时,我正在使用其中的几种查找操作(当选择“工作簿更改”时),这几乎意味着第二个延迟开始令用户烦恼。

欢呼 谢谢

2 个答案:

答案 0 :(得分:4)

VBA的主要减慢之一是读取/写入单元格值。您希望最大程度地减少读取/写入工作表的次数。事实证明,在大多数情况下,将值范围读入数组然后在该数组上执行计算要比对值范围本身进行相同计算快得多。

在您的情况下,您可以将表的范围读入数组(仅一个读操作),而不用对每一行进行读操作。

Dim mytable As ListObject
Dim myArr() As Variant

Set mytable = ThisWorkbook.Sheets(x).ListObject(1)
valuetosearch = "whatever"
valueResult = ""

myArr = mytable.Range.Value 'Read entire range of values into array

' looking for the corresponding value of column A in column B
For i = 1 To mytable.ListRows.Count
    If myArr(i, 1) = valuetosearch Then 'Check the value of the ith row, 1st column
       valueResult = myArr(i,2) 'Get the value of the ith row, 2nd column
       Exit For
    End If
Next i

我在具有1,000,000行的表上运行了快速基准测试,并且搜索到的值仅出现在最后一行(最坏的情况)。您的原始代码需要4.201秒,而这一代码需要0.484秒。快了将近9倍!

答案 1 :(得分:2)

如果您的数据在工作表上,那么Application.Match()会非常快:

Sub Tester()

    Dim m, rng, t

    Set rng = ThisWorkbook.Sheets(1).ListObjects(1).ListColumns(1).DataBodyRange

    t = Timer()
    m = Application.Match("Val_1", rng, 0) 'on the first row...
    Debug.Print m, Timer - t 'approx 0 sec

    t = Timer()
    m = Application.Match("Val_1000000", rng, 0) 'on the last row...
    Debug.Print m, Timer - t 'approx 0.03 to 0.05 sec

End Sub

m要么是匹配行的索引,要么是不匹配的错误-您可以使用IsError(m)

进行测试