Вопрос или проблема
ПРИМЕНИТЕ XLOOKUP БЫСТРЕЕ С ПОМОЩЬЮ КОДА VBA
ПРИМЕНИТЕ XLOOKUP БЫСТРЕЕ С ПОМОЩЬЮ КОДА VBA С ИСПОЛЬЗОВАНИЕМ ПЕРЕМЕННЫХ
ПРИМЕНИТЕ XLOOKUP БЫСТРЕЕ С ПОМОЩЬЮ КОДА VBA С ИСПОЛЬЗОВАНИЕМ СЛОВАРЯ
ПРИМЕНИТЕ XLOOKUP БЫСТРЕЕ С ПОМОЩЬЮ КОДА VBA С ИСПОЛЬЗОВАНИЕМ СЛОВАРЯ ubound
ПРИМЕНИТЕ XLOOKUP БЫСТРЕЕ С ПОМОЩЬЮ КОДА VBA С ИСПОЛЬЗОВАНИЕМ СЛОВАРЯ
Sub ApplyMultipleXLookupsWithDictionary()
Dim wsSrc As Worksheet, wsTgt As Worksheet
Dim lastRowSrc As Long, lastRowTgt As Long, i As Long
Dim lookupDict As Object, key As Variant, result As Variant
Dim sourceData As Variant, outputData As Variant
' Инициализация словаря и листов
Set lookupDict = CreateObject("Scripting.Dictionary")
Set wsSrc = ThisWorkbook.Sheets("Sheet1")
Set wsTgt = ThisWorkbook.Sheets("Sheet2")
' Загрузить исходные данные в словарь
sourceData = wsSrc.Range("A1:E" & wsSrc.Cells(wsSrc.Rows.Count, "A").End(xlUp).Row).Value
For i = 1 To UBound(sourceData, 1)
key = sourceData(i, 1)
If Not lookupDict.Exists(key) Then
lookupDict(key) = Array(sourceData(i, 2), sourceData(i, 3), sourceData(i, 4)) ' Только B, C, E
End If
Next i
' Отключить обновления для повышения производительности
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
' Загрузить целевые данные и подготовить выходные данные
lastRowTgt = wsTgt.Cells(wsTgt.Rows.Count, "A").End(xlUp).Row
ReDim outputData(1 To lastRowTgt - 1, 1 To 9) ' Столбцы B до J
For i = 2 To lastRowTgt
key = wsTgt.Cells(i, 1).Value
If lookupDict.Exists(key) Then
result = lookupDict(key)
outputData(i - 1, 1) = result(0) ' Столбец B
outputData(i - 1, 2) = result(0) ' Столбец C
outputData(i - 1, 3) = result(1) ' Столбец E
outputData(i - 1, 4) = result(1) ' Столбец F
outputData(i - 1, 5) = result(2) ' Столбец H
Else
FillNotFound outputData, i - 1
End If
Next i
' Записать выходные данные обратно в целевой лист
wsTgt.Range("B2:H" & lastRowTgt).Value = outputData
' Применить формулы XLOOKUP
For i = 2 To lastRowTgt
With wsTgt
.Cells(i, 2).Formula = "=XLOOKUP(A" & i & ", Sheet1!A:A, Sheet1!B:B, ""не найдено"", 0, 1)"
.Cells(i, 3).Formula = "=XLOOKUP(A" & i & ", Sheet1!A:A, Sheet1!B:B, ""не найдено"", 0, -1)"
.Cells(i, 5).Formula = "=XLOOKUP(A" & i & ", Sheet1!A:A, Sheet1!C:C, ""не найдено"", 0, 1)"
.Cells(i, 6).Formula = "=XLOOKUP(A" & i & ", Sheet1!A:A, Sheet1!C:C, ""не найдено"", 0, -1)"
.Cells(i, 8).Formula = "=XLOOKUP(A" & i & ", Sheet1!A:A, Sheet1!E:E, ""не найдено"", 0, -1)"
End With
Next i
' Включить обновления обратно
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
MsgBox "Операции XLOOKUP завершены.", vbInformation
End Sub
Sub FillNotFound(outputData As Variant, index As Long)
Dim j As Long
For j = 1 To 5 ‘ Заполнить столбцы B до F
outputData(index, j) = “не найдено”
Next j
End Sub
Ответ или решение
Использование функции XLOOKUP в VBA коде может привести к повышению производительности по сравнению с другими методами поиска, особенно при работе с большими наборами данных. Давайте рассмотрим, в чем заключаются преимущества XLOOKUP и как его применение в VBA может отразиться на производительности.
Преимущества XLOOKUP
-
Универсальность: Функция XLOOKUP может быть использована для поиска данных как по вертикали, так и по горизонтали, что делает ее более гибкой по сравнению с VLOOKUP или HLOOKUP.
-
Стратегия поиска: XLOOKUP позволяет выбрать метод поиска — строгий, с приблизительным соответствием или даже несколько других, что может быть полезно в различных сценариях.
-
Обработка ошибок: XLOOKUP имеет встроенные возможности для обработки ошибок, что уменьшает необходимость добавления дополнительных условий для обработки случаев, когда значение не найдено.
Влияние на производительность при использовании в VBA
-
Загрузка данных в словарь: В примере, где используется Scripting.Dictionary, мы сначала загружаем данные в словарь. Это позволяет значительно ускорить доступ к данным, так как поиск по словарю осуществляется за постоянное время O(1) в среднем. Если бы мы использовали стандартные функции Excel для поиска в больших диапазонах, это потребовало бы гораздо больше времени из-за линейного поиска.
-
Минимизация обновлений экрана: Отключение обновления экрана и автоматического пересчета во время выполнения VBA-процедуры также значительно увеличивает скорость выполнения. Это особенно заметно, когда выполняется множество операций на больших объемах данных.
-
Пакетная запись выходных данных: Вместо построчной записи результатов, что может быть медленным, мы загружаем все результаты в массив и пишем их обратно за одну операцию. Это также уменьшает взаимодействие с интерфейсом Excel, что замедляет выполнение.
Практические рекомендации
-
Избегайте слишком частого обращения к ячейкам Excel: Взаимодействие с ячейками — это дорогостоящая операция. Лучше загружать данные в массивы, выполнять операции в памяти, а затем загружать данные обратно.
-
Используйте словари для поиска: Автоматическая запись и доступ к данным через Scripting.Dictionary минимизирует время, необходимое для обработки больших наборов данных.
-
Следите за размером данных: Если ваши наборы данных слишком велики, даже XLOOKUP может замедлить работу из-за размера обрабатываемого диапазона. В таких случаях стоит рассмотреть возможность обработки данных в нескольких частях.
Заключение
XLOOKUP действительно быстрее, когда применяется в VBA коде, особенно в больших наборах данных, благодаря своей универсальности и эффективной обработке поиска. При правильном использовании и оптимизации VBA-кода можно существенно повысить производительность работы с данными в Excel.