По сути, есть 2 вопроса:
Для функции Excel .sort: Как добавить ключи, если я не знаю, сколько ключей (заголовков) будет у данного листа? (см. Ниже)
Я хочу передать ряд предопределенных массивов, содержащих информацию о том, как отсортировать данный выбор, в алгоритм сортировки Excel .sort ... Как мне сделать это правильно?
Описание проблемы:
У меня есть лист со списком заголовков в первом ряду. Заголовки имеют разные имена, и в первом ряду может быть различное количество заголовков. Заголовки описывают различные детали метрик, перечисленных в строках ниже на листе (одна метрика / строка).
Мне нужно написать код, чтобы я мог сортировать определенные связанные строки, а не весь лист. Например, мне может понадобиться отсортировать 28-й по 35-й ряд. Это будет передано этой программе переменной inRange . Однако я также хочу иметь возможность настроить приоритет сортировки и порядок сортировки каждого столбца при каждом запуске макроса. (обратите внимание, что строка может изменять только позицию в целом, отдельные ячейки в строке не могут изменить положение)
У меня есть следующие глобальные массивы, которые описывают заголовки:
headRow - содержит массив имен заголовков в виде строк, перечисленных в порядке столбца
prLst - содержит массив целых чисел (ввод в виде строк), которые определяют приоритет каждого из заголовков. Положение целых чисел в массиве - это номер столбца, который они описывают.
colIsString - содержит логическое определение, являются ли элементы, перечисленные в данном столбце, строками или целыми числами. True = строка, False = целое число. Опять же, позиция логического значения в массиве - это номер столбца, который они описывают.
sortOrder - содержит логические значения, определяющие ориентацию сортировки. «Правда» - по возрастанию. «Ложь» - по убыванию. Еще раз, позиция позиции логических значений в массиве - это номер столбца, который они описывают. ***
С уже созданными данными в массивах, У меня есть следующий код для передачи этих массивов в .sort:
Dim numHdrs, finalNumHdrs, count As Integer, newArray As Variant
For numHdrs = 1 To UBound(headRow)
If colIsString(numHdrs) = True Then
sortOrder(numHdrs) = xlAscending
ElseIf colIsString(numHdrs) = False Then
sortOrder(numHdrs) = xlDescending
End If
Next numHdrs
newArray = CombineArrays(headRow, prLst, sortOrder)
For finalNumHdrs = 1 To UBound(headRow)
If headRow(finalNumHdrs) And prLst(finalNumHdrs) And sortOrder(finalNumHdrs) <> "N/A" Then
'ActiveSheet.Sort.SortFields.Add Key(headRow(finalNumHdrs)):= finalNumHdrs
'ActiveSheet.Sort.SortFields.Add Order(finalNumHdrs):=sortOrder(finalNumHdrs)
End If
Next finalNumHdrs
With ActiveSheet.Sort
.SetRange inRange
.Apply
End With
У меня проблемы с добавлением полей сортировки, используя данные из массива:
'ActiveSheet.Sort.SortFields.Add Key(headRow(finalNumHdrs)):= finalNumHdrs
'ActiveSheet.Sort.SortFields.Add Order(finalNumHdrs):=sortOrder(finalNumHdrs)
Это явно не правильно. Поэтому я создал функцию, объединяющую headRow, prLst, и sortOrder , чтобы упростить подачу в .sort:
Function CombineArrays(arr1 As Variant, arr2 As Variant, arr3 As Variant)
Dim arr4 As Variant
ReDim arr4(1 To UBound(arr2), 1 To 2)
Dim i, j As Integer
For i = 0 To UBound(arr1)
arr4(arr2(i), 1) = arr1(i)
arr4(arr2(i), 2) = arr3(i)
Next i
CombineArrays = arr4
End Function
Поскольку arr2 задает приоритет сортировки для данного столбца, мне нужно передать его в .sort таким образом, чтобы arr2 указывал номер ключа. Например, если arr2 = 3, key3: = arr4 (3,1), order3: = arr4 (3,2). Я предполагаю, что порядок, в котором я элементы arr4, не будет иметь значения. (как если бы я добавил arr4 (4,1) перед arr4 (3,1), они все равно будут перечислены в соответствующем порядке)
Это сводится к двум вопросам:
Для функции Excel .sort: Как добавить ключи, если я не знаю, сколько ключей (заголовков) будет у данного листа?
Правильно ли я это делаю?
*** Примечание. Я бы использовал коллекционные объекты, если бы слышал о них ранее. Однако, поскольку я новичок в VBA, именно так я и создал программу. Это было бы слишком сложно, учитывая код, который я уже написал, чтобы вернуться и заменить все массивы на объекты коллекции.
ПРИМЕЧАНИЕ. Это часть более крупной программы, описание которой можно найти здесь: Сортировка групп строк Excel VBA Macro