2015-10-15 3 views
0

У меня есть один одномерный массив:ReDim Preserve от 1-мерных в 2-мерном

Dim array1() As Variant 
array1 = Array("A", "B", "C", "D") 

концептуально, глядя, как это:

A 
B 
C 
D 

Я хотел бы добавить второе измерение к этому массив, сохраняя исходные данные. Я хочу добавить в этот массив два столбца для хранения данных.

Dim lngArrayLength as Long 
lngArrayLength = UBound(array1, 1) 

' Zero-indexed, so now should have 3 columns 
ReDim Preserve array1(lngArrayLength, 2) 

В результате в этом:

A NULL NULL 
B NULL NULL 
C NULL NULL 
D NULL NULL 

Проблема заключается в том, что мой ReDim Preserve команды бросает ошибку времени выполнения: '9': Подстрочный из ошибок диапазона. Я не могу понять, почему.

+5

Вы не можете изменить количество измерений с 'Redim Preserve' ни вы можете изменить количество элементов ничего, кроме последнего измерения.Вам нужно создать новый массив требуемого размера и скопировать данные из старого массива самостоятельно. См. [Функции для массивов VBA] (http://www.cpearson.com/excel/VBAArrays.htm) для множества идей. –

+0

@TonyDallimore - Ну, это ответ ... Я не думаю, что могу пометить комментарий как ответ, но вот и все ... Спасибо! – gotmike

+0

@TonyDallimore Действительно? Это очень разочаровывает. Тот факт, что 'ReDim Preserve' не может это сделать, является общеизвестным и неинтересным. Я подозреваю, поэтому он не был предложен в качестве ответа. Единственное известное решение - это то, что предложил Деметри. Я попытался предложить что-то новое и интересное для достижения вашей цели ... redimming массив 1D до 2D и хранения данных. –

ответ

2

Это свой род сырного решения:

Dim Array1() As Variant, TempArray() As Variant 

Array1 = Array("A", "B", "C", "D", "E") 
ReDim TempArray(0 To UBound(Array1), 0 To 2) 

For i = 0 To UBound(Array1) 
    TempArray(i, 0) = Array1(i) 
Next i 
Array1 = TempArray 
+0

Это то, что я в конечном счете использовал. Благодаря! – gotmike

2

ReDim не способен повторно проклейка массива в больший ранг (число измерений).

Общий способ приблизиться к этому - создать новый массив ранга, который вы хотите, и пропустить все элементы исходного массива, назначив их по одному для нового массива.

Вот интересная альтернатива, которая не является широко известно, что может сделать то же самое, без VBA зацикливание элементов:

array1D = Array("A", "B", "C", "D") 

array2D = Evaluate("{""" & Join(array1D, """;""") & """}&{"""","""",""""}") 

Результат: 1D массив будет преобразован в 2-х измерениях (3 колонки шириной, источник в 1-й колонке).

Результат: два новых столбца будут содержать точно такие же данные, как и первый столбец, но, конечно, теперь вы можете назначать любые новые значения для новых столбцов.

Оговорка: каждое измерение нижней границы будет 1.

Оговорка: это для массивов текста. Аналогичный метод можно использовать для числовых массивов.

Предостережение: элементы исходного массива не могут содержать точки с запятой.

Самое большое предостережение в этом методе заключается в том, что максимальная длина строки, которую может обрабатывать функция VBA Evaluate(), составляет всего 255 символов. Чтобы обойти это ограничение, мы используем вызов функции в процессе оценки, например, так:

Private array1D 

Public Sub Array1dTo2d() 

    array1D = Array("A", "B", "C", "D") 

    array2D = [transpose(Arr())&{"","",""}] 

End Sub 

Private Function Arr() 
    Arr = array1D 
End Function 

UPDATE

Вот динамичный способ реализации этого метода, так что легко указать количество столбцов в результирующем двумерном массиве.

Просто запустите TestArrayConversions рутины(), чтобы увидеть три примера:

Private array_ 

Public Sub TestArrayConversions() 

    array1 = Array("A", "B", "C", "D") 
    array1 = Array1dTo2d(array1, 3) 
    MsgBox "2D array has:" & vbLf & UBound(array1, 1) & " rows" & vbLf & UBound(array1, 2) & " columns" 

    array1 = Array("A", "B", "C", "D", "E", "F", "G", "H") 
    array1 = Array1dTo2d(array1, 25) 
    MsgBox "2D array has:" & vbLf & UBound(array1, 1) & " rows" & vbLf & UBound(array1, 2) & " columns" 

    array1 = Array("we", "can", "do", "it") 
    array1 = Array1dTo2d(array1, 6) 
    MsgBox "2D array has:" & vbLf & UBound(array1, 1) & " rows" & vbLf & UBound(array1, 2) & " columns" 

End Sub 

Public Function Array1dTo2d(arr1D, columns) 
    array_ = arr1D 
    Array1dTo2d = Evaluate("transpose(Arr())&{" & Application.Rept(""""",", columns - 1) & """""}") 
End Function 

Private Function Arr() 
    Arr = array_ 
End Function 
+1

интересный способ сделать это ... много предостережений ... – gotmike

+0

это также нормально работает для небольших файлов примеров, подобных этому, но как бы вы справились с этим для массива с переменным размером? – gotmike

+0

Что это значит? –

Смежные вопросы