Передача массивов и диапазона в .sort-алгоритм Excel - PullRequest
0 голосов
/ 26 июля 2011

По сути, есть 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

1 Ответ

2 голосов
/ 11 августа 2011

Я думаю, вы ожидаете, что метод сортировки примет массив ключей сортировки и порядков, которые он не может сделать. Сортировка ограничена максимум 3 столбцами сортировки (как в пользовательском интерфейсе)

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

' Assuming you have some array which lists the order in which to sort from most important to least important named priorityArr 
For i = UBound(priortyArr) To LBound(prioryArr)
  ActiveSheet.Sort.SortFields.Add Key:= headRow(i) Order:=sortOrder(i)
  ' do the rest you need to do and apply the sort
Next
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...