У нас есть вариативная переменная arr. Мы её использовали до этого в коде, и (так как больше её данные не нужны) использовали дальше в коде, просто заполнив заново? Безо всякого очищения и ReDim??? А что - так можно было?
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
vikttur написал: её можно менять при использовании
спасибо! То есть она сама меняется в процессе наполнения - правильно я понял?
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Нет, неправильно. Массив можно заполнить значениями диапазона. После использования заполнить из другого диапазона с другим размером... Можно задать размерность и заполнять массив (хоть весь, хоть часть его).
Цитата
TheBestOfTheBest: при выводе на лист будет выведен весь массив, это может сильно тормозить.
Не обязательно. Довольно часто бывает, что вычисления нужной (предполагаемой) размерности сложнее, чем задание размерности с запасом. После заполнения массива можно выгрузить только часть. Например:
Код
ReDim aTemp (1 To 500, 1 To 10)
' внесено k=400 записей, да и последние "столбцы" не заполнялись
.Cells(1,1).Resize(k,8).Value = aTemp
vikttur написал: После заполнения массива можно выгрузить только часть.
Вот это более правильное решение. Офф. К вопросу почему программист когда ложиться спать на прикроватную тумбочку ставит два стакана, один полный, другой пустой!?
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
не понимаю((( размерность с запасом лучше/корректнее/быстрее, чем Variant? А если просто Erase arr перед очередным использованием? Я, наверное, очень глупые, с точки зрения операций с массивами, вопросы задаю…
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
TheBestOfTheBest написал: Кроме этого Вы не можете определить размер arr и переопределить его размер.
Размер arr, это весь массив данных он по логике не может быть меньше количества повторений, а переменная k как раз и определяет границу выгрузки части массива на лист. Что касаемо определения размерности массива, то это как бы и не требуется.
Jack Famous написал: размерность с запасом лучше/корректнее/быстрее, чем Variant?
При чем здесь типы данных? Нужно загрузить массив из диапазона A1:C20
Код
aData = .Range("A1:C20").Value
Размерность массива - 20 на 3 Можно было задать размерность при объявлении
Код
Dim aData (1 To 20, 1 To 3)
но при этом пришлось бы заполнять массив в цикле
А если заранее неизвестно, сколько строк придется заполнять? С горизонтльной размерностью проще - ее можно менять в процессе, не стирая уже сохраненные данные
Код
ReDim Preserve aData (1 To 20, 1 To 5)
А как быть с вертикальной? Таблетки успокоительные глотать? Размерность задаем заранее такой, чтобы была не меньше предполагаемого максимума. и выгружаем из массива не все, включая пустые, а только нужное.
vikttur, стало понятнее - спасибо)) но всё равно не ясно, чем хуже заполнить aData, не задавая размерность вообще (как Variant)? Она же самоопределится в процессе? Да и в основном, тут на форуме, так и делают с массивами… А вот Дима «The_Prist» Щербаков в этом плане строг - у него я, как правило, вижу все объявления.
Причём, как я понял, .Value2 лучше, чем .Value, особенно с датами.
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Вы путаете размерность с типом. В этой теме о типе я вооще ни разу не писал. Размерность - количество элементов по вертикали, горизонали, диагонали... (до 64 размерностей, правда, не знаю, зачем столько). Тип зависит от типа данных, которые будут размещаться в массиве. Тип не нужно задавать, если предполагается работа с разнотипными даными.
vikttur, смотрите: 1. Можно задать arr или arr() - в первом случае это Variant/Variant(), а во втором только Variant(). Верно? Уже тут явное объявление массива будет быстрее. 2. Размерность для массива нужно определить, задать с запасом или же просто заполнить переменную (например с листа, через Array или как-то ещё) без циклов и определений. Верно? Вот со вторым мне и не очень понятно, в каком случае задание точных границ или границ с запасом будет лучше, чем просто наполнение.
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Jack Famous написал: Вот со вторым мне и не очень понятно, в каком случае задание точных границ или границ с запасом будет лучше, чем просто наполнение.
Под конкретную задачу. В которой размер диапазона или массива не изменяется, чаще используется динамический массив arr()
"Все гениальное просто, а все простое гениально!!!"
в каком случае задание точных границ или границ с запасом будет лучше, чем просто наполнение.
Уже, наверное, третий раз. Заполнять массив не получится, пока неизвестны его размерности. Т.е. нельзя объявить как arr() и записать в него значение. Нужно или задать размерность (ReDim), или загрузить в массив диапазон (при этом размерности примут значения размеров диапазона)
Цитата
А если заранее неизвестно, сколько строк придется заполнять?
vikttur, под наполнением я имею ввиду arr=rng.value2, а не вставку на лист (если вдруг вы про это ) Количество элементов массива после его наполнения можно же через UBound узнать. UBound(arr,1)*UBound(arr,2) = КОЛ-ВО строк* КОЛ-ВО столбцов
Или же всё плохо и меня спасёт только штудирование матчасти?
UPD: кажется я начал понимать, о чём вы))) спасибо!
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Jack Famous написал: UBound(arr,1)*UBound(arr,2) = КОЛ-ВО строк* КОЛ-ВО столбцов
Это не количество строк а наибольший индекс. Если массив начинается с нулевого индекса то UBound(arr) не будет равно количеству строк (столбцов) массива
"Все гениальное просто, а все простое гениально!!!"
Nordheim, ну да - нужно будет единицы добавить к каждому Ubound, в таком случае. А при наполнении массива диапазоном с листа каждая граница с 1 должна быть автоматом. Правильно сделали, что поправили
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Jack Famous написал: 1. Можно задать arr или arr() - в первом случае это Variant/Variant(), а во втором только Variant(). Верно?
Dim arr(20,3) As String - объявление массива с верхними границами 20 и 3, причем нижнее значение 0 или 1 в зависимости от Option Base 1 - arr (1 TO 20, 1 TO 3), если нет Option Base 1, то arr (0 TO 20, 0 TO 3), тип данных строковый
Dim arr - объявление переменной,, поскольку тип не указан, то VBA присваивает Variant Затем arr=.Range("A1:C20").Value - VBA из переменной делает массив размерностями согласно диапазону. но тип остается Variant, нижняя граница всегда =1 (от Option Base 1 не зависит)
Dim arr() - объявление динамического массива, поскольку тип не указан, то VBA присваивает Variant. Динамический потому, что можно менять его размер, но только в некоторых пределах (см. описание ReDim), т.е. из arr (1 TO 20, 1 TO 3) можно сделать arr (1 TO 20, 1 TO 5), но нельзя сделать arr (1 TO 20, 1 TO 2) или arr (1 TO 120, 1 TO 3). Также если указать тип (Dim arr() As Stribg), то диапазон в такой массив записать нельзя, т.е. arr=Range("A1:C20").Value даст ошибку.
Jack Famous написал: Количество элементов массива после его наполнения можно же через UBound узнать.
Неверно, через Ubound можно узнать верхнюю границу, причем: в зависимости от Option Base 1 - arr (1 TO 20, 1 TO 3), если нет Option Base 1, то arr (0 TO 19, 0 TO 2) -граница будет 20 или 19 / 3 или 2
Поэтому если массив предполагается выводить в ячейки или сопоставлять с диапазоном, то лучше использовать Option Base 1, при этом верхняя граница (20) покажет количество элементов в массиве/размер Range.
TheBestOfTheBest написал: нижнее значение 0 или 1 в зависимости от Option Base 1
а разве нижняя граница при заполнении массива диапазоном с листа не будет 1 - по умолчанию, без объявления Option Base???
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
TheBestOfTheBest, с 0 - как и должен быть. Я же именно про заполнение с листа говорил. По ссылке так и есть
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Господа, в этой теме снова столкнулся с "массивной" проблемой. Код не функционирует. Karataev пытался мне объяснить, но до меня не доходит
КОД
Код
Option Explicit
Sub Extract()
Dim arr(), x(), temp()
Dim cl As Range
Dim i&
Dim itxt$
ReDim temp(1 To Selection.Cells.Count, 1 To 1)
temp() = Selection.Value: itxt = Join(temp(), ", ")
ReDim temp(1 To Selection.Cells.Count, 1 To 1)
temp() = Split(itxt, ", "): arr() = GetUniqArrFromArr(temp)
Set cl = Application.InputBox("Óêàæèòå ÿ÷åéêó âñòàâêè:", "Âûáðàòü ÎÄÍÓ ÿ÷åéêó", , Type:=8)
cl.Resize(UBound(arr) + 1).Value2 = WorksheetFunction.Transpose(arr)
End Sub
'================================================================================================================
Public Function GetUniqArrFromArr(WF_arr As Variant) As Variant
Dim x, iTemp
With CreateObject("Scripting.Dictionary")
For Each x In WF_arr
If Len(x) > 0 Then iTemp = .Item(x)
Next x
GetUniqArrFromArr = .Keys
End With
End Function
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
можно менять его размер, но только в некоторых пределах (см. описание ReDim), т.е. из arr (1 TO 20, 1 TO 3) можно сделать arr (1 TO 20, 1 TO 5), но нельзя сделать arr (1 TO 20, 1 TO 2) или arr (1 TO 120, 1 TO 3).
Плюс в JOIN можно отдавать только одномерный массив