Всем привет. Вопрос спортивный. Есть код, который берёт с листа данные в массив (например, А1:J20), а дальше мы через функцию Application.Index выдёргиваем из этого массива строки с 10 по 20-ю без цикла. Вопрос - как вот в эту строку кода подставить свои переменные
т.е. вместо 10:20 и 1:10 подставить переменные a, b, c ?
Код
Sub Test()
Dim Arr As Variant, File_Array As Variant
'берём массив с листа 20 строк и 10 столбцов
Arr = Worksheets("Лист1").Range("A1:J20").Value
'выбираем строки из массива Arr начиная с 10-й по 20-ю и 10 столбцов
'аналог =ИНДЕКС(A1:J20;СТРОКА(10:20);СТОЛБЕЦ(1:10)) (формулу вводить в столбец А)
File_Array = Application.Index(Arr, [Row(10:20)], [Column(1:10)])
'обрезаем ненужные столбцы справа, т.к. их сейчас в массиве 16384
ReDim Preserve File_Array(1 To UBound(File_Array, 1), 1 To 10)
'выводим результат на Лист2
With Worksheets("Лист2")
.UsedRange.Clear
.Range("A1").Resize(UBound(File_Array), UBound(File_Array, 2)).Value = File_Array
End With
End Sub
Привет, Дим. К сожалению, не работает. Выдаёт ошибку 1004, Application-defined or object-defined error.
Код
Sub Test()
Dim Arr As Variant, a As Long, b As Long, c As Long, File_Array As Variant
'берём массив с листа 20 строк и 10 столбцов
Arr = Worksheets("Лист1").Range("A1:J20").Value
'выбираем строки из массива Arr начиная с 10-й по 20-ю и 10 столбцов
'аналог =ИНДЕКС(A1:J20;СТРОКА(10:20);СТОЛБЕЦ(1:10)) (формулу вводить в столбец А)
'VAR 1
'File_Array = Application.Index(Arr, [Row(10:20)], [Column(1:10)]) 'РАБОТАЕТ
'обрезаем ненужные столбцы справа, т.к. их сейчас в массиве 16384
'ReDim Preserve File_Array(1 To UBound(File_Array, 1), 1 To 10)
'VAR 2
a = 10
b = 20
c = 10
File_Array = Application.Index(Arr, Range(a & ":" & b), Columns(1).Resize(, c)) '<--- НЕ РАБОТАЕТ
'выводим результат на Лист2
With Worksheets("Лист2")
.UsedRange.Clear
.Range("A1").Resize(UBound(File_Array), UBound(File_Array, 2)).Value = File_Array
End With
End Sub
сомневаюсь я что это выгодно ,но если используется Evalaute в записи не позволяющей использовать переменные, то почему не использовать её же но в записи позволяющей.
Код
Application.Index(Arr, Evaluate("=ROW(" & a & ":" & b & ")"), Evaluate("=column(1:" & c & ")"))
я уже устал повторять им, что, если явного цикла нет, то это не значит, что его нет в вызываемой функции Думаю, что даже самописная процедура/функция на VBA будет быстрее Application.Index и проще в использовании…
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Сравните, кто может (я не понял предложенные варианты)
Код
Option Explicit
'====================================================================================================
Sub t()
Dim arr, t!
t = Timer
arr = SmartIndex(Worksheets("Лист1").Range("A1:J20").Value, 10, 20, 1, 10)
Debug.Print Format$(Timer - t, "0.00 sec")
End Sub
'====================================================================================================
Function SmartIndex(a2D, rBeg&, rEnd&, cBeg&, cEnd&) As Variant()
Dim aRes(), r&, rr&, c&, cc&
ReDim aRes(1 To rEnd - rBeg + 1, 1 To cEnd - cBeg + 1)
For c = cBeg To cEnd
cc = cc + 1: rr = 0
For r = rBeg To rEnd
rr=rr+1: aRes(rr, cc) = a2D(r, c)
Next r
Next c
SmartIndex = aRes
End Function
'====================================================================================================
'====================================================================================================
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Option Explicit
'====================================================================================================
Sub Test()
Dim rng As Range
Dim x, arr, t!, n&
Set rng = [_data]
arr = rng.Value
t = Timer
For n = 1 To 10000
x = IndexJF(arr, 10, 20, 1, 10) ' 0.17
' x = IndexJF(rng.Value, 10, 20, 1, 10) ' 1.21
' x = IndexPrist(rng, 10, 20, 1, 10) ' 0.27
Next n
Debug.Print Format$(Timer - t, "0.00 sec")
End Sub
'====================================================================================================
Function IndexJF(a2D, rBeg&, rEnd&, cBeg&, cEnd&) As Variant()
Dim aRes(), r&, rr&, c&, cc&
ReDim aRes(1 To rEnd - rBeg + 1, 1 To cEnd - cBeg + 1)
For c = cBeg To cEnd
cc = cc + 1: rr = 0
For r = rBeg To rEnd
rr = rr + 1: aRes(rr, cc) = a2D(r, c)
Next r
Next c
IndexJF = aRes
End Function
'====================================================================================================
Function IndexPrist(rng As Range, rBeg&, rEnd&, cBeg&, cEnd&) As Variant()
IndexPrist = rng.Offset(rBeg - 1, cBeg - 1).Resize(rEnd - rBeg + 1, cEnd - cBeg + 1).Value
End Function
'====================================================================================================
Димин вариант быстрее работает с диапазоном, а мой сделан для фильтрации массива
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄