2016-06-12 2 views
1

У меня есть рабочий лист с этим типом структуры (есть несколько столбцов в реальном листе, но не много):Excel VBA Место значения в многомерном массиве

ColumnAValue1 ColumnBValue1 23 
ColumnAValue1 ColumnBValue1 45 
ColumnAValue1 ColumnBValue1 2.4 
ColumnAValue1 ColumnBValue2 1 
ColumnAValue1 ColumnBValue2 3 
ColumnAValue2 ColumnBValue1 5 
ColumnAValue2 ColumnBValue1 6 
ColumnAValue2 ColumnBValue1 7 
ColumnAValue2 ColumnBValue2 355 
ColumnAValue2 ColumnBValue2 221 

И я хочу, чтобы получить средние, номера позиций и отклонения для каждой комбинации (например, ColumnAValue1 ColumnBValue1 будет в среднем 23, 45 и 2,4). Поэтому я думал, что получение всех данных в массиве, или в коллекции или в словаре (я не знаю, существует ли что-то вроде «Многомерного словаря»). Я хотел закончить с многомерным массивом (или коллекцией) со структурой, подобной этим:

AllData(
     ColumnAValue1(
        ColumnBValue1(23,45,2.4) 
        ColumnBValue2(1,3) 
        ) 
     ColumnAValue2(
        ColumnBValue1(5,6,7) 
        ColumnBValue2(355,221) 
        ) 
     ) 

Я знаю, как получить уникальные значения из столбцов.

Мои два вопроса: 1) Как создать массив (или коллекции) с соответствующими ключами (ColumnAValue1 и ColumnAValue2 для первого Dimention и ColumnBValue1 и ColumnBValue2 для второго), и 2) затем проведите все мои данные и значения «место» в соответствующем подмассиве.

ответ

2
Sub Test() 
    Dim c As Collection 
    Set c = New Collection 

    Dim ws As Worksheet 
    Set ws = ThisWorkbook.Worksheets("Sheet1") 

    Dim i As Long 
    For i = 1 To 10 'Assume 10 rows 
    AddToLayeredCollection c, ws.Cells(i, 3).value, ws.Cells(i, 1).value, ws.Cells(i, 2).value 'Assume two columns for keys, A and B 
    Next 

    'Add 'c' to the watch window and examine it 
End Sub 

Public Sub AddToLayeredCollection(ByVal root_collection As Collection, ByVal value As Variant, ParamArray keys() As Variant) 
    Dim i As Long 
    Dim target_collection As Collection 

    Set target_collection = root_collection 
    For i = LBound(keys) To UBound(keys) 
    Set target_collection = ResolveToCollection(target_collection, keys(i)) 
    Next 

    target_collection.Add value 
End Sub 

Private Function ResolveToCollection(ByVal parent_collection As Collection, ByVal key As Variant) As Collection 
    On Error Resume Next 
    Set ResolveToCollection = parent_collection(key)(1) 
    On Error GoTo 0 

    If ResolveToCollection Is Nothing Then 
    Set ResolveToCollection = New Collection 
    parent_collection.Add Array(key, ResolveToCollection), key 
    End If 
End Function 

Единственная причина, я использую Array() вещь, чтобы быть в состоянии retrieve keys from the collection. Вы можете use Dictionary instead и удалить Array().

+0

Wow! Он делает то, что я просил! Все еще пытаюсь получить логику кода, но изучение c в окнах часов (как вы сказали) выглядит великолепно. Я поражен и очень благодарен. Я застрял четыре дня с этим, прежде чем сдаваться и спрашивать здесь ... – CMArg

+0

@GSerg Между словарем и массивом, который является более предпочтительным подходом в этом случае. Ищите свое мнение в качестве энтузиаста, чтобы учиться на своем ценном опыте и опыте. – skkakkar

+0

@skkakkar Это вопрос личных предпочтений. Я обычно использую 'Collection', потому что это внутренний класс, и я знаю, что он будет доступен. Использование словаря будет более чистым в коде, но это зависит от внешней библиотеки - тогда опять-таки библиотека, вероятно, будет присутствовать в любой системе, где вы запускаете Excel, - затем снова прочитайте [комментарии ниже этого ответа] (http : //stackoverflow.com/a/5702529/11683). – GSerg