Кстати весьма интересна разница по работе ВПР с открытым и закрытым файлом. Даже разовый вызов конкретно озадачил функцию. SQL наклацанный конечно не мгновенно,
Код |
---|
SELECT `Sheet1$_1`.ID, iif(`Sheet1$`.ID Is Null,'Нет','Есть') AS 'result'
FROM {oj `C:\temp\20000.xlsx`.`Sheet1$` `Sheet1$_1` LEFT OUTER JOIN `C:\temp\900000.xlsx`.`Sheet1$` `Sheet1$` ON `Sheet1$_1`.ID = `Sheet1$`.ID} |
но выдал результат по 20 000 из 900 000 где файл с 900 000 был закрыт, за относительно нормальные 2 мин. ВПР тужился 4 мин и я остановил на 60% расчета. К несчастью SQL еще и отсортировал , на что тоже ушло время.
генерировал 900000 формулой
="A"&RANDBETWEEN(1:900000)
20000
=MID("ab";RANDBETWEEN(1;2);1)&RANDBETWEEN(1:900000)
Теперь макрос в лоб на словаре
Код |
---|
Sub get_from()
t = Timer
Sub get_from()
t = Timer
Set Dict = CreateObject("Scripting.Dictionary")
a = Workbooks("20000.xlsx").Sheets(1).Range("a2:a20000").Value2
ReDim c(1 To UBound(a, 1), 1 To 1)
B = Workbooks("900000.xlsx").Sheets(1).Range("a2:a900000").Value2
For j = 1 To UBound(B)
If Not Dict.Exists(B(j, 1)) Then Dict.Add B(j, 1), B(j, 1)
Next
Debug.Print Timer - t
For i = 1 To UBound(a)
If Dict.Exists(a(i, 1)) Then
c(i, 1) = "Есть"
Else
c(i, 1) = "нет"
End If
Next
Debug.Print Timer - t
Workbooks("20000.xlsx").Sheets(2).Range("f2:f20000") = c
Debug.Print Timer - t
End Sub |
заполнение словаря
31,85938
далее на 32,94531 заполнен массив результата
и на 33,01563 данные выгружены.
То есть 97% времени тратим на подготовку. а потом быстро все делаем. Но если это делать через UDF и каждый раз заполнять словарь, то очевиден плачевный результат.