Добрый день, планетяне! Имеется динамический двумерный массив Arr. Чтобы перебрать все его строки, обычно используют способ вроде for i=LBound(Arr) to UBound (Arr). Возник следующий вопрос: возможно ли то-же самое сделать при помощи for each? Чтобы перебирались не все элементы, а именно все строки.
двумерный массив с листа всегда будет с единицы + лично я, чтобы не звбывать, что это именно двумерный массив, указываю оба измерения: For i=1 to UBound (Arr, 1)
Цитата
Мартын: возможно ли то-же самое сделать при помощи for each?
For Each… это цикл по всем элементам, соответственно, чтобы через него сделать цикл по строкам, нужно передать массив строк, созданный ручками или в цикле (есть ещё вариант извлечь из адреса регулярками, но это совсем другая тема)
А зачем вам это? В скорости этот метод если и выигрывает, то очень ненамного, но иногда и вовсе проигрывает + нет "встроенного" счётчика, как в For i=1 To …, который очень часто бывает нужен
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
А для чего нужен такой беребор, даже если таковой найдется , все равно обращаться скорее всего будете к элементу массива по индексу.Можно заполнять коллекцию строчными массивами, а потом по коллекции делать цикл, как вариант.
Jack Famous написал: массив с листа всегда будет с единицы
Не совсем отдуплил, что сие значит. Для меня исторически сложилось, что массивы должны начинаться с единицы, поэтому все модули начинаю с обязательных (для меня строк) Option explicit и base 1
Цитата
Nordheim написал: Можно заполнять коллекцию строчными массивами
Так я этим и пытаюсь заняться, только со словарём. Хочу засунуть строку как элемент словаря, а оно сопротивляется.
Код
Sub test
Dim PlArr As Variant
Dim OnePl As Variant
Dim i As Long
PlArr = ThisWorkbook.Worksheets("PLAN").ListObjects(1).DataBodyRange
For i = LBound(PlArr) To UBound(PlArr)
OnePl = PlArr(i)
Next
endsub
Почему в строке OnePl = PlArr(i) вылетает Subscript out of range? Массив PlArr создаётся, показывает, что LBound=1, а UBound=1456, но PlArr(1) - out of range! Что не так? И как засунуть в OnePl всю строку сразу, а не поэлементно.
Всегда считал, что многомерный массив это массив массивов и для двумерного A(10,10) вызов A(1) должен возвращать одномерный массив, то есть первую строку. Разве в VBA это не так?
Всегда считал, что многомерный массив это массив массивов и для двумерного A(10,10) вызов A(1) должен возвращать одномерный массив, то есть первую строку. Разве в VBA это не так?
Цитата
Jack Famous написал: В скорости этот метод если и выигрывает, то очень ненамного
Это я как раз и проверяю. Недавно наткнулся, что для словаря For each на пару порядков быстрее чем For i.
Мартын написал: И как засунуть в OnePl всю строку сразу, а не поэлементно.
Сделать в цикле второй цикл, по строкам массива запоняя одномерный массив, и запихивая его в словарь что то типа
Код
Sub main()
Dim arr(), coll As Object
Dim i&, j&, ikey
arr = tabl
ReDim iarr(UBound(arr, 2))
Set coll = CreateObject("scripting.dictionary")
For i = 0 To UBound(arr)
arr(i, 1) = i
For j = 0 To UBound(arr, 2)
iarr(j) = arr(i, j)
Next j
coll.Item(CStr(i)) = iarr
Next i
For Each ikey In coll
Debug.Print Join(coll.Item(ikey), " | ")
Next ikey
End Sub
Function tabl()
Dim i&, j&, arr(9, 9)
For i = 1 To 10
For j = 1 To 10
arr(i - 1, j - 1) = i * j
Next j, i
tabl = arr
End Function
Но нужно ли это?
"Все гениальное просто, а все простое гениально!!!"
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Андрей, ну конечно, речь не про какие-то встроенные в коллекции циклы имеется ввиду то, что применение цикла For Each для коллекций и словарей более "родные", чем перебор от 1 до .count.
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
Sub test()
Dim dict As Object, i As Long
Set dict = CreateObject("Scripting.Dictionary")
dict("A") = 1
For i = 1 To dict.Count
Debug.Print dict(i)
Next i
Set dict = Nothing
End Sub
А для коллекции видел? Там оно прям встроенное От 1 до .Count в словаре сам не видал в явном исполнении, т.к. там индексация элементов отсутствует. Хотя в определенных случаях придумать можно и такой цикл(например, если заполняем ключи изначально числами). Или когда те же Items сначала были в массив помещены:
Код
Dict.Add "a", "One"
Dict.Add 1, "Two"
Arr = Dict.Items
For i=0 To Dict.Count-1
MsgBox Arr(i)
Next
придумать-то много чего можно. Даже текущая тема как бы не совсем нужна в контексте массивов
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
Sub test()
Dim dict As Object, i As Long
Set dict = CreateObject("Scripting.Dictionary")
dict("A") = 1
For i = 0 To dict.Count - 1
Debug.Print dict.Keys()(i)
Next i
Set dict = Nothing
End Sub
Однажды столкнулся с ситуацией, когда нужно было циклом перебрать элементы коллекции. А коллекция была очень большая. Уже не помню точно, но больше 10 000 элементов. Перебирал циклом For-Nexy. Заметил, что с каждой итерацией перебор идёт все медленнее и медленнее.А после 3000 это стало уже видно невооружённым глазом. Владимир (ZVI).сказал, что при цикле For-Next время на каждую итерацию растёт в геометрической прогрессии и рекомендовал при переборе коллекций использовать For-Each. Применил - результат подтвердил правильность рекомендации.
Общий смысл такой, что я заменяю жуткий SQL запрос, который работает медленно, на "извращения" с массивами и словарями. Работа ускоряется в десятки раз. В данном случае этот словарь нужен, чтобы связать данные из одной таблицы с другой, через exists. Суть не в "зачем", а в принципиальной возможности это сделать. Я уже понял, что в VBA невозможно напрямую получить всю строку из двумерного массива. Нашёл способ через WorksheetFunction.Index, потом попробую, приемлемо ли получится по скорости.
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄