Страница 1 из 2
Переопределение границ массива с сохранением его элементов
Добавлено: 21 сен 2009, 02:45
AlexZZZ
Доброго времени суток всем!
Подскажите, пожалуйста, что-то я застопорился: на простом, вроде, коде выдаёт ошибку:
Код: Выделить всё
Dim nArray As Variant
'.....
ReDim Preserve nArray(1 To 2, 1 To 2) 'Переопределение массива с сохранением элементов
P/S: Так тоже выдаёт ошибку
Так, что я делаю не так?
Re: Переопределение границ массива с сохранением его элементов
Добавлено: 21 сен 2009, 03:00
EducatedFool
Попробуйте так:
Код: Выделить всё
[color=darkblue]Sub[/color] test1()
[color=darkblue]Dim[/color] nArray[B][color="Red"]()[/color][/B] [color=darkblue]As[/color] [color=darkblue]Variant[/color]
[color=green]'.....[/color]
[color=darkblue]ReDim[/color] [color=darkblue]Preserve[/color] nArray(1 [color=darkblue]To[/color] 2, 1 To 2) 'Переопределение массива с сохранением элементов
[color=darkblue]End[/color] [color=darkblue]Sub[/color]
Re: Переопределение границ массива с сохранением его элементов
Добавлено: 21 сен 2009, 06:03
SAS888
Необходимо заметить, что во-первых, при определении (переопределении) массива, безусловно, переменную нужно объявлять как массив (см, замечания от
Educated Fool). Во-вторых, переопределение границ массива
с сохранением данных, возможно
только для последней размерности многомерного массива. Например:
Код: Выделить всё
Sub qq()
Dim nArray() As Variant
ReDim nArray(1 To 2, 1 To 2)
'.....
ReDim Preserve nArray(1 To 2, 1 To 3) 'Этот код сработает нормально
ReDim Preserve nArray(1 To 3, 1 To 2) 'Этот код выдаст ошибку
End Sub
Re: Переопределение границ массива с сохранением его элементов
Добавлено: 21 сен 2009, 16:25
AlexZZZ
Спасибо за советы!
переопределение границ массива с сохранением данных, возможно только для последней размерности многомерного массива
Но как же тогда быть? Ведь, добавлять приходится именно первую размерность (это строки, число которых в начале цикла неизвестно, чтобы потом вставить это в листбокс). Тогда подскажите, как "транспонировать" массив?
Re: Переопределение границ массива с сохранением его элементов
Добавлено: 21 сен 2009, 19:31
EducatedFool
Но как же тогда быть? Ведь, добавлять приходится именно первую размерность (это строки, число которых в начале цикла неизвестно, чтобы потом вставить это в листбокс)
А почему не объявить массив с большим запасом строк?
Например,
nArray(1 To 100000, 1 To 2)
Не так уж много памяти отъест этот массив, а код намного упростится.
Или, может, имеет смысл использовать
коллекции?
Я в абсолютном большинстве случаев использую коллекции вместо массивов (за редким исключением, разве что когда массивы огромны, и очень важна скорость работы; либо если этот массив потом приходится переносить на лист)
Re: Переопределение границ массива с сохранением его элементов
Добавлено: 21 сен 2009, 22:44
AlexZZZ
Попробовал, в общем, проще всего в моём случае оказалось сделать 2 цикла: один определяет число строк в массиве, затем переопределяется массив и второй цикл по тем же условиям заполняет массив значениями. Всё работает, но решение какое-то не изящное, и вероятно, не самое производительное.
По совету EducatedFool попробую ещё разобраться, как организовывать двумерные коллекции, если такие существуют.
Re: Переопределение границ массива с сохранением его элементов
Добавлено: 22 сен 2009, 04:58
SAS888
AlexZZZ,
1. А какая конкретно у Вас задача? Почему нужно организовывать цикл для определения числа строк? Без него никак?
2. Если Вы работаете с массивом, перебирая его элементы в цикле, то я бы не советовал использовать ReDim Preserve. Ибо каждый раз, выполняя эту функцию, происходит перезапись всех элементов последней размерности массива, что есть долго и не рационально. Может быть лучше объявить другой (пустой) массив требуемой размерности, а в цикле просто присваивать значения его элементам? Уверяю Вас, что будет существенно быстрее.
Re: Переопределение границ массива с сохранением его элементов
Добавлено: 22 сен 2009, 11:32
AlexZZZ
Задача следующая. Есть строка данных вида:
Аспирин - 100 уп.
Анальгин - 280 уп.
Димедрол - 80 уп.
Её нужно пропарсить и вставить в двухколоночный листбокс. Для этого циклом определяю количество строк (считаю символы переноса строки) и по выходу из цикла указываю размерность массива (теперь уже только один раз и без сохранения элементов), а затем следующим циклом последовательно разбиваю эту строку на исходные составляющие и заполняю массив.
Повторюсь, что сейчас всё работает нормально, просто до этого пытался сделать всё в одном цикле, переопределяя в нём каждый раз границы массива.
Re: Переопределение границ массива с сохранением его элементов
Добавлено: 22 сен 2009, 12:14
Aent
Зачем же циклом считать количество vbCR ?
Код: Выделить всё
n = len(s) - len(replace(s,vbCr,vbNullString))
'или
n = UBound(split(s,vbCr))+1
Да и с массивом полученным по Split можно сразу работать.
Re: Переопределение границ массива с сохранением его элементов
Добавлено: 22 сен 2009, 23:10
AlexZZZ
Aent, как всегда приятно удивляете!
Вот это и есть изящное решение, которое я имел в виду! Правда, константы vba, почему-то в моём случае не работают, а работает так (n - число строк в массиве):
Код: Выделить всё
n = Len(s) - Len(Replace(s, Chr(10), "")) + 1
А Split я вообще раньше не использовал, а зря! Правда , как из него сделать двумерный массив я не разобрался, зато с одномерными работает отлично: