Страницы: 1 2 След.
RSS
Не увеличивается размерность массива ReDim Preserve
 
Добрый день. Подскажите такой вопрос.
Сидел массив ваял. Решил увеличить его размерность, но макрос выпадает в ошибку.
Захожу на майкрософт там написано:
Код
Dim intArray(10, 10, 10) As Integer
ReDim Preserve intArray(10, 10, 20)
Пытаюсь выполнить этот код, но макрос выпадает в ошибку.
Или я что-то не понимаю, или я не могу что ли изменить размерность объявленного массива?
Спасибо.
Изменено: Alemox - 13.09.2017 11:34:58
Мастерство программиста не в том, чтобы писать программы, работающие без ошибок.
А в том, чтобы писать программы, работающие при любом количестве ошибок.
 
Для использования ReDim Preserve (как и просто для ReDim), массив должен быть объявлен динамическим:
Код
Sub qq()
    Dim intArray() As Integer
    ReDim intArray(10, 10, 10)
    ReDim Preserve intArray(10, 10, 20)
End Sub
Чем шире угол зрения, тем он тупее.
 
Цитата
SAS888 написал:
массив должен быть объявлен динамическим:
С этим я тоже пробовал и всё хорошо работает. Просто никогда не загонялся над тем динамический или нет должен быть массив при расширении его. Но видимо в этом кроется хитрость, что нельзя расширить объявленный массив.
Значит на сайте майкрософта нас дурят.   :sceptic:  
Изменено: Alemox - 13.09.2017 11:48:08
Мастерство программиста не в том, чтобы писать программы, работающие без ошибок.
А в том, чтобы писать программы, работающие при любом количестве ошибок.
 
Цитата
но макрос выпадает в ошибку.
Ошибка в том, что массив уже определен, о чем и говорит сообщение
 
Цитата отсюда:
Цитата
ReDim не могут быть использованы на массивах фиксированного размера - то есть с массивами с постоянными границами, созданными с Dim.
Чем шире угол зрения, тем он тупее.
 
Цитата
Alemox написал: Значит на сайте майкрософта нас дурят
По крайней мере здесь и в VBA-справке написано, что ReDim относится к динамическому массиву: Remarks: The ReDimstatement is used to size or resize a dynamic array
А у Вас объявлен статический массив, который формируется в памяти по другим принципам, не подразумевающим изменение размерности.
 
Всем спасибо. Вопрос разъяснил для себя.
Мастерство программиста не в том, чтобы писать программы, работающие без ошибок.
А в том, чтобы писать программы, работающие при любом количестве ошибок.
 
Но ведь действительно там так и написано :)
Код
VB

Dim intArray(10, 10, 10) As Integer
ReDim Preserve intArray(10, 10, 20)
ReDim Preserve intArray(10, 10, 15)
ReDim intArray(10, 10, 10)

однако дурят...
Или для VB другие правила? Ибо там ниже ссылка идёт и на другой аналогичный пример.
Изменено: Hugo - 13.09.2017 13:48:05
 
Цитата
Hugo написал:
Или для VB другие правила?
VB2010 удалил, а так бы тоже интересно проверить. Но я думаю, что это они заработались.  :)  
Мастерство программиста не в том, чтобы писать программы, работающие без ошибок.
А в том, чтобы писать программы, работающие при любом количестве ошибок.
 
в Студии 2017(Microsoft Visual Studio Community 2017)- проект VB, такой код отрабатывает:
Код
Module Module1
    Sub Main()
        Dim intArray(10, 10, 10) As Integer
        ReDim Preserve intArray(10, 10, 20)
        ReDim Preserve intArray(10, 10, 15)
        ReDim intArray(10, 10, 10)
    End Sub
End Module

Размерности меняются.
«Бритва Оккама» или «Принцип Калашникова»?
 
Microsoft Visual Studio Community 2017
Версия 15.0.26228.9 D15RTWSVC
Microsoft .NET Framework
Версия 4.6.01590
Установленная версия: Community
Visual Basic 2017   00369-60000-00001-AA112
Microsoft Visual Basic 2017
«Бритва Оккама» или «Принцип Калашникова»?
 
bedvit, большое спасибо, что проверили. Теперь будем знать.
Мастерство программиста не в том, чтобы писать программы, работающие без ошибок.
А в том, чтобы писать программы, работающие при любом количестве ошибок.
 
а вот у меня почему то на отрез отказывается увеличиваться
Код
dim Arr()as variant
dim l as long
redim arr(1,3)
l = ubound(arr)
redim preserve arr(l+1,3)

выдает ошибку
Изменено: andrey062006 - 29.03.2018 20:22:07
 
Redim Preserve изменяет только ПОСЛЕДНЮЮ размерность массива, а Вы пытаетесь изменить первую
Согласие есть продукт при полном непротивлении сторон
 
Цитата
Sanja написал:
Redim Preserve изменяет только ПОСЛЕДНЮЮ размерность массива, а Вы пытаетесь изменить первую
честно говоря не понял про последнюю размерность
как я должен поступить если я не знаю какой длины у меня массив будет?
поэтому я задал ему начальные параметры равные 1 строке и 3 столбцам (ну вы поняли)
а дальше пытаюсь увеличивать
 
andrey062006, а причём тут, знаете Вы или нет количество строк? Вам объяснили, ПОЧЕМУ у Вас не получается.
 
Цитата
andrey062006 написал: честно говоря не понял
ну если на пальцах, то в Вашем случае можно изменить 3-ку, а единицу нет. Посмотрите примеры выше, от bedvit, (#11), в массивах, из ТРЕХ размерностей, меняется последняя, две первых 10-ки остаются неизменны
Согласие есть продукт при полном непротивлении сторон
 
Цитата
andrey062006 написал:
как я должен поступить
перевернуть подход или транспонировать массив. От куда у вас мнение, что это строка и столбец? А если массив трех мерный то там этаж или 4х, то там что, корпус?
Изменено: БМВ - 29.03.2018 20:31:19
По вопросам из тем форума, личку не читаю.
 
Юрий М, а можно по-русски объяснить?
Я не понимаю что значит ПОСЛЕДНЯЯ размерность массива!
Как мне получить эту последнюю размерность?
Без начального ReDim, ReDim Preserve не работает ведь!
Может быть Вы можете сказать где ошибка в моем варианте кода?
 
По-русски: у массива в общем случае две размерности: количество строк (первая) и количество столбцов (вторая). Менять можете только вторую.
 
Цитата
andrey062006 написал:
Вы можете сказать где ошибка в моем варианте кода?
См. ответ в #17.
 
Юрий М,ааааааааааааа, вот оно что
мдя.... правила одномерного массива применили, видимо чтобы не сильно заморачиваться, ко всем остальным
ну ладно, спасибо огромное что объяснили, а то я уже который раз это не могу сделать
приходится создавать tmpArr а потом перебором новый массив заполнять
 
Цитата
andrey062006 написал:
приходится создавать tmpArr а потом перебором новый массив заполнять
Я тоже так частенько поступаю )
 
Если предполагается "редимпресервить" большой массив - то с каждым шагом будут возрастать потери времени на это действо. Я стараюсь вообще избегать такого алгоритма.
 
Полностью согласен  :D . Посмотрите м.б. есть возможность определить размерность массива до заполнения данными, что бы не использовать ReDim Preserve.
А "редимпресервить" только в крайнем случае.
Изменено: Nordheim - 30.03.2018 15:23:42
"Все гениальное просто, а все простое гениально!!!"
 
Оптимальная стратегия - удваивать последнюю размерность
Владимир
 
Nordheim,ну в данном конкретном случае, да, есть возможность расчитать необходимые границы многомерного массива.
НО, согласитель что 2 слова ReDim Preserve выглядят и читаются в коде куда лучше чем конструкции с FOR/DO.
Цитата
Hugo написал:
Если предполагается "редимпресервить" большой массив - то с каждым шагом будут возрастать потери времени на это действо.
Ну а что в Вашем понимании большой?
Для некотрых большой это и 30 ячеек памяти.
Я "редимпресервил" максимальный одномерный массив размером в 5-6 тысяч значений. Ну честно говоря потерю времени я не заметил. Я не спорю что она есть, наверняка есть, и если такой массив наполняется не один раз за работу кода а несколько раз, то тогда может и будет заметно, но на обычных юзеров вроде нас, в негабаритных массивах эти потери времени вообще не отразятся, мы их попросту не заметим, если специально не будем замерять эти микроскунды))))

Просто честно говоря хотелось как то более изящно подойти к решению вопроса, но тут вот оно как... Только последняя размерность меняется.
 
Ну 5-6 тысяч это конечно ерунда, время доли секунды. А вот на 60000 уже нужно 2 секунды.
Т.е. если сидите и ждёте когда код отработает (а 2 сек. уже заметно) - не будет лишним замерить сколько времени теряете именно на этой операции.
 
Цитата
sokol92 написал:
Оптимальная стратегия - удваивать последнюю размерность
Оптимальная, простите, для кого?
Удваивать, говрите? Ну давайте разберемся.
Есть абстрактный Arr(1,10)
Следуя Вашей логике удваивание значит берем 10*2 = 20
Redim preserve Arr(1,20)->Redim preserve Arr(1,40)->Redim preserve Arr(1,80)->Redim preserve Arr(1,160)->Redim preserve Arr(1,320)->Redim preserve Arr(1,640)->Redim preserve Arr(1,1280)..........................................(1,163840)
Доудваивались))))))))
Это не оптимальная стратегия ни разу вообще.
А потом циклом все это перебирать? А если еще и анализ надо произвести этих данных в массиве? Или будет тратить ресурсы и ВРЕМЯ (вот уж где точно оно тратится) на транспорирование массива в WorkSheet?
 
Здравствуйте, Hugo! Давненько ничего не измеряли. Массив из миллиона записей, заполненный случайным текстом:
Код
Sub test()
  Dim arr(), v
  Dim t As Double
  Dim i As Long
  ReDim arr(1 To 1000000)
  For i = LBound(arr) To UBound(arr)
    arr(i) = Rnd() & " " & Rnd()
  Next i
  
  t = Timer
  ReDim Preserve arr(1 To 2000000)
  Debug.Print Timer - t
End Sub
На древнем компьютере (Win XP Excel 2007) - 0.2 сек. Или у меня обман зрения?
Изменено: sokol92 - 30.03.2018 15:18:19
Владимир
Страницы: 1 2 След.
Наверх