Как хранить диапазоны в массиве, коллекции или словаре на основе критериев? - PullRequest
0 голосов
/ 10 июля 2019

Я пытаюсь проанализировать непрерывный диапазон данных (orng) и создать поддиапазоны из orng, содержащие одинаковое строковое значение в 6-м столбце orng. Каждый поддиапазон имеет 1-15 строк и 38 столбцов. Насколько я знаю, я не могу создать новый объект диапазона для каждого поддиапазона, так как количество поддиапазонов неизвестно. Я создал массив, который содержит данные для поддиапазонов (aData). Я получил его для работы с кодом ниже, но я чувствую, что есть гораздо более чистый способ сделать это, что я не могу понять. Я также попытался использовать словарь безуспешно. В конечном счете мне придется обращаться ко всем данным для расчетов, и использование нескольких вложенных циклов for для доступа к каждому элементу кажется сложным.

Я использую Excel Professional Plus 2016 (не уверен, что это имеет значение).

Использование массива - единственный способ получить конечный результат, который я ищу, и это нормально. Я бы предпочел, чтобы массив был динамическим, но всякий раз, когда я пытался использовать метод ReDim Preserve, значения не сохранялись в массиве. Размер массива был бы идеальным, но каждый элемент был «пустым». Согласно Microsoft «каждому элементу массива должно быть присвоено его значение индивидуально», поэтому я полагаю, что не могу присвоить значения диапазона массиву в виде кусков. После того, как я обнаружил эту веб-страницу, я реализовал массив с предопределенной структурой и вложенными циклами for.

В идеале, я мог бы разделить orng на разные Области, но так как он смежный, я не в состоянии это сделать. Что я хотел бы знать: 1) есть ли лучший способ сделать то, что я пытаюсь сделать? (Легче читать, быстрее, меньше кода и т. Д. И 2), если нет лучшего способа, могу ли я получить совет о том, как сделать этот код чище (динамический диапазон, меньше циклов, лучшая структура)?

Private Sub rangetest()

Dim twb As Workbook: Set twb = ThisWorkbook
Dim cws As Worksheet: Set cws = twb.Sheets("Cleaned_2019+")
Dim orng As Range
Dim datelot As String, datelotcomp As String
Dim c As Long, i As Long, j As Long, k As Long, numrows As Long, lastrow 
    As Long, numlots As Long, _
    curRow As Long, lotRows As Long, startRow As Long, layerRows As Long, 
    aRow As Long
Dim aLot() As Variant, aData(9, 49, 37) As Variant
Dim Z As Boolean

Set orng = cws.Range("A973:AL1014")   'Set initial range to work with.
numrows = orng.Rows.Count             'Number of rows in orng.
curRow = 1                            'Current row in orng.
startRow = 1                          'Starting row in orng for next 
layer (changes when lot changes).
i = 0                                 'Layer of array (for aLot and aData arrays).
j = 0                                 'Row in orng where values for previous layer ended.
Z = False
Do Until Z = True
    datelot = Left(orng.Cells(curRow, 6).Value, 10)                            'Lot that we want the data for. Corresponds to a layer in the aData array.
    datelotcomp = Left(orng.Cells(curRow + 1, 6).Value, 10)                    'Lot of the next row in data sheet.
    If datelot <> datelotcomp Then                                             'If datelotcomp <> to datelot then we want a new layer for array.
        layerRows = curRow - j                                                 'Number of rows for a particular layer
        ReDim Preserve aLot(i)                                                 'Array of lot names
        aLot(i) = datelot                                                      'Assign lot name to aLot array
        For aRow = 1 To layerRows                                              'Row index in array
            For lotRows = startRow To curRow                                   'Loops through orng rows and sets those values in array
                For c = 1 To 38                                                'Loops through columns. There are always 38 columns
                    aData(i, aRow - 1, c - 1) = orng.Cells(lotRows, c).Value   'Add values to each index in array
                Next c
            Next lotRows
        Next aRow
        j = curRow
        i = i + 1
        startRow = curRow + 1
    End If
    If curRow = numrows Then                                                   'End loop at end of orng
        Z = True
    End If
    curRow = curRow + 1
Loop
numlots = i

End Sub

В результате я получаю массив со структурой aData (9, 49, 37), который содержит данные в первых 4 слоях aData (1-3,,). Это соответствует количеству лотов, которые находятся в организации, поэтому код работает правильно. Я просто хотел бы посоветовать, если я делаю что-то неэффективно.

Я буду проверять ответ на вопросы или добавлять пояснения.

Редактировать 1:

В итоге на вопрос был дан ответ здесь (Code Review) для всех заинтересованных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...