Добрый день. Подскажите такой вопрос. Сидел массив ваял. Решил увеличить его размерность, но макрос выпадает в ошибку. Захожу на майкрософт там написано:
Код
Dim intArray(10, 10, 10) As Integer
ReDim Preserve intArray(10, 10, 20)
Пытаюсь выполнить этот код, но макрос выпадает в ошибку. Или я что-то не понимаю, или я не могу что ли изменить размерность объявленного массива? Спасибо.
Мастерство программиста не в том, чтобы писать программы, работающие без ошибок. А в том, чтобы писать программы, работающие при любом количестве ошибок.
SAS888 написал: массив должен быть объявлен динамическим:
С этим я тоже пробовал и всё хорошо работает. Просто никогда не загонялся над тем динамический или нет должен быть массив при расширении его. Но видимо в этом кроется хитрость, что нельзя расширить объявленный массив. Значит на сайте майкрософта нас дурят.
Мастерство программиста не в том, чтобы писать программы, работающие без ошибок. А в том, чтобы писать программы, работающие при любом количестве ошибок.
Alemox написал: Значит на сайте майкрософта нас дурят
По крайней мере здесь и в VBA-справке написано, что ReDim относится к динамическому массиву: Remarks: The ReDimstatement is used to size or resize a dynamic array А у Вас объявлен статический массив, который формируется в памяти по другим принципам, не подразумевающим изменение размерности.
Мастерство программиста не в том, чтобы писать программы, работающие без ошибок. А в том, чтобы писать программы, работающие при любом количестве ошибок.
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, большое спасибо, что проверили. Теперь будем знать.
Мастерство программиста не в том, чтобы писать программы, работающие без ошибок. А в том, чтобы писать программы, работающие при любом количестве ошибок.
Sanja написал: Redim Preserve изменяет только ПОСЛЕДНЮЮ размерность массива, а Вы пытаетесь изменить первую
честно говоря не понял про последнюю размерность как я должен поступить если я не знаю какой длины у меня массив будет? поэтому я задал ему начальные параметры равные 1 строке и 3 столбцам (ну вы поняли) а дальше пытаюсь увеличивать
ну если на пальцах, то в Вашем случае можно изменить 3-ку, а единицу нет. Посмотрите примеры выше, от bedvit, (#11), в массивах, из ТРЕХ размерностей, меняется последняя, две первых 10-ки остаются неизменны
Согласие есть продукт при полном непротивлении сторон
перевернуть подход или транспонировать массив. От куда у вас мнение, что это строка и столбец? А если массив трех мерный то там этаж или 4х, то там что, корпус?
Юрий М, а можно по-русски объяснить? Я не понимаю что значит ПОСЛЕДНЯЯ размерность массива! Как мне получить эту последнюю размерность? Без начального ReDim, ReDim Preserve не работает ведь! Может быть Вы можете сказать где ошибка в моем варианте кода?
Юрий М,ааааааааааааа, вот оно что мдя.... правила одномерного массива применили, видимо чтобы не сильно заморачиваться, ко всем остальным ну ладно, спасибо огромное что объяснили, а то я уже который раз это не могу сделать приходится создавать tmpArr а потом перебором новый массив заполнять
Если предполагается "редимпресервить" большой массив - то с каждым шагом будут возрастать потери времени на это действо. Я стараюсь вообще избегать такого алгоритма.
Полностью согласен . Посмотрите м.б. есть возможность определить размерность массива до заполнения данными, что бы не использовать ReDim Preserve. А "редимпресервить" только в крайнем случае.
Nordheim,ну в данном конкретном случае, да, есть возможность расчитать необходимые границы многомерного массива. НО, согласитель что 2 слова ReDim Preserve выглядят и читаются в коде куда лучше чем конструкции с FOR/DO.
Цитата
Hugo написал: Если предполагается "редимпресервить" большой массив - то с каждым шагом будут возрастать потери времени на это действо.
Ну а что в Вашем понимании большой? Для некотрых большой это и 30 ячеек памяти. Я "редимпресервил" максимальный одномерный массив размером в 5-6 тысяч значений. Ну честно говоря потерю времени я не заметил. Я не спорю что она есть, наверняка есть, и если такой массив наполняется не один раз за работу кода а несколько раз, то тогда может и будет заметно, но на обычных юзеров вроде нас, в негабаритных массивах эти потери времени вообще не отразятся, мы их попросту не заметим, если специально не будем замерять эти микроскунды))))
Просто честно говоря хотелось как то более изящно подойти к решению вопроса, но тут вот оно как... Только последняя размерность меняется.
Ну 5-6 тысяч это конечно ерунда, время доли секунды. А вот на 60000 уже нужно 2 секунды. Т.е. если сидите и ждёте когда код отработает (а 2 сек. уже заметно) - не будет лишним замерить сколько времени теряете именно на этой операции.
Оптимальная, простите, для кого? Удваивать, говрите? Ну давайте разберемся. Есть абстрактный 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 сек. Или у меня обман зрения?