Я пытаюсь проанализировать непрерывный диапазон данных (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) для всех заинтересованных.