开发者

Passing Arrays and a Range to Excel's .sort Algorithm

There are essentially 2 questions:

For excel's .sort function: How do I add keys when I do not know how many keys (headers) a given sheet is going to have? (See Below)

I want to pass a number of predefined arrays, containing information on how to sort a given selection, to excel's .sort algorithm... How do I do this correctly?

Problem Description:

I have a sheet that lists headers in the first row. The headers are different names and there can be a variable number of headers present in the first row. The headers describe different details of metrics listed in the rows below on the sheet (one metric/row).

I need to write a code such that I can sort certain bound-together rows, not the entire sheet. For instance, I might need to sort the 28th-35th row. This will be passed to this program by the variable inRange. However, I also want to be able to configure the sort priority and how each column gets sorted everytime I run the macro. (note that a row can only change position as a whole, individual cells within the row cannot change position)

I have the following Global arrays which describe the headers:

headRow - contains an array of the header names as strings listed in order of the column

prLst - contains an array of integers (input as strings) that determine priority of each of the headers. The position of the integers in the array is the column number which they describe.

colIsString - contains Boolean determining if items listed in a given column are strings or integers. True = string, False = Integer. Again, position position of booleans in the array is the column number which they describe.

sortOrder - containing booleans specifying orientation of sort. "True" - ascending. "False" - descending. Yet again, position position of booleans in the array is the column number which they describe.***

With the data in the arrays already etablished, I have the following code to feed these arrays to .sort:

Dim numHdrs, final开发者_如何学PythonNumHdrs, 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

I am having trouble adding the sort fields appropriately, using the data I have in the array:

'ActiveSheet.Sort.SortFields.Add Key(headRow(finalNumHdrs)):= finalNumHdrs
'ActiveSheet.Sort.SortFields.Add Order(finalNumHdrs):=sortOrder(finalNumHdrs)

This is obviously not correct. So I created a function to concatenate headRow, prLst, and sortOrder to make it easier to feed into .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

Since arr2 is specifying the sort priority of a given column, I need to feed it to .sort in such a way that arr2 specifies the key number. As in if arr2 = 3, key3:= arr4(3,1), order3:= arr4(3,2). I am assuming that the order in which I elements to arr4 will not matter. (as in if I add arr4(4,1) before arr4(3,1) they will still be listed in the appropriate order)

This boils down to two questions:

For excel's .sort function: How do I add keys when I do not know how many keys (headers) a given sheet is going to have?

Am I doing this correctly?

*** Note I would have used collection objects had I heard about them earlier. However, since I am new to VBA, this is how I established the program. It would be too difficult given the code I have already written to go back and change all the arrays to collection objects.

NOTE: This is part of a larger program, whose description can be found here: Sorting Groups of Rows Excel VBA Macro


I think you expect the sort method to accept an array of sorting keys and orders which it can't do. The sort is limited to a max of 3 sorting columns (just like it is in the User interface)

You will need to make use of the trick that you can end up with the same sorting results by doing it column by column from the least important one to most important one. The next code is incomplete and won't exactly be what you need but is intended to explain the general idea

' 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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜