2015-08-05 3 views
2

Я пытаюсь получить 2D-массив размером [x][3] заполненный. X - это только размер листа (количество строк), и меня интересуют 3 столбца. Столбцы не находятся рядом друг с другом, например, arr[i][0] следует заполнить из столбца AA, arr[i][1], из столбца K и arr[i][2] должен быть из столбцов L.Ввод отдельных диапазонов в 2D-массив

Я попытался присвоить его следующим образом, но получил ошибку в присвоении значения массива.

Любая помощь в этом была бы принята с благодарностью!

Код:

Sub SOC_work() 
'Trying to sort each of the disciplines further, by Stage of Construction 

Dim ar_SOC() As Variant 
Dim int_NumRows As Long 
Dim i_counter As Long 
Dim j_Counter As Long 
Dim lite As Range 

Application.Calculation = xlCalculationManual 
Application.ScreenUpdating = False 

Sheets("AVEVA_PBOM_PARTS").Select 


'Redimension the array size to the amount of parts in the PBOM 
int_NumRows = ActiveSheet.UsedRange.Rows.count - 1 
ReDim ar_SOC(int_NumRows, 3) 

'now assignt he range into the array space 
lite = Range("AA2", Range("AA2").End(xlDown)) 


ar_SOC[][1]=lite 



End Sub 

Есть ли способ сделать это без зацикливания через всю колонну?

+1

Заполните 3 отдельных 2D-массива, а затем выполните цикл, чтобы объединить их в один. Зацикливание через массивы происходит намного быстрее, чем через ячейки в диапазоне. –

ответ

3

Как описано в комментариях, вы можете заполнить три двухмерных массива. Затем вы можете заполнить четвертый массив из трех массивов, как показано ниже.

Sub populateArray() 
    Dim arrColOne() As Variant, arrColTwo() As Variant, arrColThree() As Variant 
    Dim arrAllData() As Variant 
    Dim i As Long 

    arrColOne = Range("A2:A" & lrow(1)) 'amend column number 
    arrColTwo = Range("D2:D" & lrow(4)) 
    arrColThree = Range("G2:G" & lrow(7)) 

    ReDim arrAllData(1 To UBound(arrColOne, 1), 2) As Variant 
    For i = 1 To UBound(arrColOne, 1) 
     arrAllData(i, 0) = arrColOne(i, 1) 
     arrAllData(i, 1) = arrColTwo(i, 1) 
     arrAllData(i, 2) = arrColThree(i, 1) 
    Next i 
End Sub 

Public Function lrow(colNum As Integer) As Long 
    lrow = Cells(Rows.Count, colNum).End(xlUp).Row 
End Function 

Вышеупомянутое потребует, чтобы все 3 столбца были одинаковой длины (иначе заполнение последнего массива не будет работать); это связано с тем, что четвертый массив перераспределяется, чтобы содержать количество элементов, содержащихся в первом массиве.

Тестирование с 250 000 строк данных, четвертый массив, заполненный в 0,43 секунды.

+0

Это сработает.Благодаря! – Dunn

+0

Это великолепно и точно то, что я искал, чтобы выгрузить 4 неконкурентных диапазона (столбцы), запустить countif для всех строк, а затем выделить нужные (дублированные) строки. Спасибо! – CaffeinatedCoder

1

Как вы мягко относитесь к массиву, который вы получаете взамен? Я могу получить вам массив Array(col)(row), не зацикливая его, если это сработает. Обратите внимание, что это не Array(col, row), кстати. Это одномерный массив столбцов, каждый из которых содержит одномерный массив значений строк. Если все в порядке с этим, вы можете сделать это:

Dim a(1 To 3) 
a(1) = WorksheetFunction.Index(WorksheetFunction.Transpose(Range("AA2:AA10")), 1, 0) 
a(2) = WorksheetFunction.Index(WorksheetFunction.Transpose(Range("K2:K10" )), 1, 0) 
a(3) = WorksheetFunction.Index(WorksheetFunction.Transpose(Range("L2:L10" )), 1, 0) 

Тогда вы могли бы получить доступ к элементам массива следующим образом:

Debug.Print UBound(a)  ' Number of columns (3) 
Debug.Print UBound(a(1)) ' Number of rows in column 1 
Debug.Print a(1)(3)  ' Value of column 1 (AA), row 3 

Index() функция может возвращать 1D массив, но только в ряды направление. Итак, вам нужно объединить его с Transpose(), чтобы вернуть массив 1D столбцов. Это все, что делает код выше.

+0

Я не думаю, что могу использовать его в этом случае, но это полезная идея, поэтому я сохраняю ваш код для использования в будущем. Благодаря! – Dunn

1

Что относительно массива массивов?

Sub NoLoop() 
Dim R1 As Range, R2 As Range, R3 As Range 
Dim Arr1() As Variant, Arr2() As Variant, Arr3() As Variant 

Dim LR As Long 
LR1 = Cells(Rows.Count, "AA").End(xlUp).Row 
LR2 = Cells(Rows.Count, "K").End(xlUp).Row 
LR3 = Cells(Rows.Count, "L").End(xlUp).Row 

Set R1 = Range(Cells(1, "AA"), Cells(LR1, "AA")) 
Set R2 = Range(Cells(1, "K"), Cells(LR2, "K")) 
Set R3 = Range(Cells(1, "L"), Cells(LR3, "L")) 

Arr1 = R1.Value 
Arr2 = R2.Value 
Arr3 = R3.Value 

ArrArr = Array(Arr1, Arr2, Arr3) 

End Sub 

При этом вы можете назвать ваши ценности с помощью:

MyVal = ArrArr(0)(1,1) 
MyVal = ArrArr(0)(2,1) 
MyVal = ArrArr(1)(1,1) 

Если первое число для массива (начинается с 0 и заканчивается 2) и второй номер для строки/ячейки диапазон, используемый для заполнения массива. Третье число всегда 1 (поскольку добавление диапазона к массиву возвращает двумерный массив)

С помощью этого кода вы также можете иметь разные размеры для каждого столбца, чтобы сохранить память.

+0

Вот что я делаю и в своем ответе. Однако вы можете избавиться от этого 2D-массива (и необходимость всегда указывать для него индекс столбца «1») с комбинацией «Index()» и «Transpose()». – Bond

+0

@Bond Извините, я писал, пока вы отвечали. Я не профессионал, и моя цель - только ответить на полученную помощь. – genespos

+1

Абсолютно. Не пытался предположить, что вы не должны были размещать это. Просто хотел, чтобы пять-пятерки для обоих придумали похожие решения! – Bond

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