我正在尝试根据B列的顺序对A列进行排序。
在这里提出了类似的问题,但是该解决方案未按预期工作。 Order a column based on another column
以下是我的数据示例:
这是我正在运行的VBA:
Sub sort_a_b()
Application.ScreenUpdating = False
Range("A1:B12").Copy Destination:=Range("G1:H12")
Range("G1:H12").Sort Key1:=Range("H1:H12"), Order1:=xlAscending
Range("G1:G12").Copy Destination:=Range("A1:A12")
Range("G1:H12").Clear
Application.ScreenUpdating = True
End Sub
这是我运行它时看到的结果:
我不确定发生了什么。我希望根据B列的顺序看到5月,8月,11月,12月,但这种方式无法正常工作。请注意,我的实际列表有500个变量!
任何建议都将不胜感激-手册或宏。谢谢!
答案 0 :(得分:4)
如果您有权访问Excel 365和SORTBY
公式,那么您很幸运。如您所见,公式解决方案非常简单-
=SORTBY(A1:A4,MATCH(A1:A4,$B$1:$B$12,0))
中间参数MATCH
基本上是分配给定月份的数字顺序-
答案 1 :(得分:2)
或者不使用Excel 365
“如果您有权访问Excel 365和SORTBY公式,那么您很幸运。”
除了后面的帖子中的有效答案之外,该帖子还打算通过动态Excel 365功能之前的方法帮助“不太幸运的人” 解决问题:
主要过程ReorderBy
使用
Application.Match
和冒泡排序例程(对包含找到的索引的基于1的2维数据字段数组进行排序)和Application.Index()
函数重新排列数组的一种未知的方法-c.f. ►{Some pecularities of the Application.Index()
function Sub ReorderBy(data, pattern) ' data: Aug,Nov,Dec,May
With Application
'a) fill 2-dim array with pattern indices and sort it
Dim indices: indices = .Match(data, pattern, 0) ' ~> 8,11,12,5
BubbleSort2Dim indices ' ~> 5,8,11,12
'b) reorder data based on pattern indices
data = Application.Index(pattern, indices, Array(1)) ' ~> May,Aug,Nov,Dec
End With
End Sub
Sub BubbleSort2Dim(arr, Optional colNo As Long = 1)
Dim cnt As Long, nxt As Long, temp
For cnt = LBound(arr) To UBound(arr) - 1
For nxt = cnt + 1 To UBound(arr)
If arr(cnt, colNo) > arr(nxt, colNo) Then
temp = arr(cnt, colNo)
arr(cnt, colNo) = arr(nxt, colNo)
arr(nxt, colNo) = temp
End If
Next nxt
Next cnt
End Sub
示例呼叫
使用
[1]
帮助功能getData()
用于获取列数据并最终调用[2]
主例程ReorderBy
: ad [1]
)请注意,getData()
中的工作表参数在这里作为CodeName引用(例如Sheet1
)传递到当前项目。
Sub ExampleCall()
'[1] define data and pattern arrays
Dim data: data = getData(Sheet1, "A") '[A2:A5]
Dim pattern: pattern = getData(Sheet1, "B") '[B2].Resize(12))
'[2] reorder data
ReorderBy data, pattern ' << call main routine (By Ref arguments!)
'[3] write results to any target
Sheet1.Range("D2").Resize(UBound(data), 1) = data
End Sub
Function getData(ws As Worksheet, ByVal col, Optional ByVal StartRow& = 2) As Variant()
' Purpose: assign column data to variant array
If IsNumeric(col) Then col = Split(ws.Cells(1, col).Address, "$")(1)
Dim LastRow As Long
LastRow = ws.Range(col & Rows.Count).End(xlUp).Row
getData = ws.Range(col & StartRow & ":" & col & LastRow).Value2
End Function