Хорошо, все это вне листа, поэтому все массивы основаны на нуле. Чтобы проверить эту настройку, я создал рабочий лист с четырьмя столбцами в соответствии с вашими данными и используя случайные числа в четвертом столбце. Я сохранил это в текстовом файле (TestFile.txt), а затем прочитал его, чтобы получить массив с нулевым значением (диапазоны Excel основаны на 1, когда вы берете их в массив). Я сохранил 150000 строк в текстовом файле, чтобы правильно настроить рутину. Да, у меня SSD, и это повлияет на время запуска 2s, но я все равно ожидаю, что он будет работать в < 10s на вращающемся жестком диске, я думаю.
Во всяком случае, вот код (требуется ссылка VBA для Microsoft выполнения сценариев чисто для чтения файла):
Public Function ReturnFilteredArray(arrSource As Variant, _
strValueToFilterOut As String) As Variant
Dim arrDestination As Variant
Dim lngSrcCounter As Long
Dim lngDestCounter As Long
ReDim arrDestination(UBound(arrSource, 1) + 1, UBound(arrSource, 2) + 1)
lngDestCounter = 1
For lngSrcCounter = LBound(arrSource, 1) To UBound(arrSource, 1)
' Assuming the array dimensions are (100000, 3)
If CStr(arrSource(lngSrcCounter, 3)) <> strValueToFilterOut Then
' Hit an element we want to include
arrDestination(lngDestCounter, 1) = arrSource(lngSrcCounter, 0)
arrDestination(lngDestCounter, 2) = arrSource(lngSrcCounter, 1)
arrDestination(lngDestCounter, 3) = arrSource(lngSrcCounter, 2)
arrDestination(lngDestCounter, 4) = arrSource(lngSrcCounter, 3)
lngDestCounter = lngDestCounter + 1
End If
Next
ReturnFilteredArray = arrDestination
End Function
Sub TestRun()
Dim fso As FileSystemObject
Dim txs As TextStream
Dim arr As Variant
Dim arr2 As Variant
Dim lngCounter As Long
Debug.Print Now()
Set fso = New FileSystemObject
Set txs = fso.OpenTextFile("E:\Users\Thingy\Desktop\TestFile.txt", ForReading)
arr = Split(txs.ReadAll, vbNewLine)
ReDim arr2(UBound(arr), 3)
For lngCounter = 0 To UBound(arr) - 1
arr2(lngCounter, 0) = Split(arr(lngCounter), vbTab)(0)
arr2(lngCounter, 1) = Split(arr(lngCounter), vbTab)(1)
arr2(lngCounter, 2) = Split(arr(lngCounter), vbTab)(2)
arr2(lngCounter, 3) = Split(arr(lngCounter), vbTab)(3)
Next
arr2 = ReturnFilteredArray(arr2, "0")
Range("L2").Resize(UBound(arr2, 1), 5) = arr2
Debug.Print Now()
End Sub
Есть ряд предположений там, не в последнюю очередь размеры.Обратите внимание на разницу во втором счетчике измерений между arrDestination и arrSource. Это связано с тем, что Excel является 1-базируемым и нормальным массивом, основанным на 0.
Кроме того, когда я пишу массив, мне нужно было поднять второе измерение до 5, чтобы получить весь массив на листе. Я не смог обрезать пустые элементы, так как ReDim Preserve работает только в самом верхнем измерении (столбцах), и это первое измерение (строки), которое здесь меняется.
Anywho, это должно служить напоминанием о том, что, несмотря на его недостатки, Excel довольно изумительный.
Вы проверили фактическую производительность цикла по массиву? Должно быть довольно быстро. –
Фильтровать четвертую колонку, чтобы выбрать '0' и удалить выбранное? – pnuts
Цитирование через этот массив не должно занимать больше нескольких минут ... – emihir0