Функция поиска по списку VBA быстро - PullRequest
0 голосов
/ 13 декабря 2018

У меня есть несколько листов, содержащих ListObjects

Когда мне приходится искать соответствующие значения в списке объектов, я делаю следующее:

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 голосов
/ 13 декабря 2018

Если ваши данные находятся на листе , то 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)

0 голосов
/ 13 декабря 2018

Одним из основных замедлений в 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 раз быстрее!

...