实例需求:某学校体育活动统计表如下图左侧表格所示,数据按照班级排列,现在需要根据如下规格对表格进行排序
- “幼儿”班级排列在表格最后
- 按照“次数”降序排列
- “幼儿”班级同样按“次数”降序排列
排序结果如下图中右侧表格所示。
示例代码如下。
Sub Demo1()
Dim i As Long, lastRow As Long
lastRow = Range("A1").End(xlDown).Row
Const HELPER = 4
For i = 2 To lastRow
Cells(i, HELPER) = IIf(Left(Cells(i, 1), 2) = "幼儿", 0, 1)
Next
With Range("A1").CurrentRegion
.Sort key1:=.Columns(HELPER), order1:=xlDescending, _
key2:=.Columns(HELPER - 1), order2:=xlDescending, Header:=xlYes
End With
Columns(HELPER).Clear
End Sub
【代码解析】
第3行代码获取数据总行数。
第4行代码定义辅助列的位置。
第5~7行代码根据班级填充辅助列,“幼儿”班级填充0,其他班级填充1,根据辅助列降序排列,“幼儿”班级将移至最后。
第8~11行代码对数据表排序,辅助列为第一关键列,“次数”为第二关键列,两列都使用降序排列。
第12行代码清空辅助列。
使用VBA进行排序,通常思路是将数据表读取到数组中,然后使用排序算法进行排序(例如:冒泡法),由于Excel已经提供了强大的排序功能,通过构建辅助列可以更高效地实现排序。
如果限于工作表布局,无法使用辅助列(例如:D列有其他数据,也无法使用插入新列),这里提供一种变通实现方式。
Sub Demo2()
Dim i As Long, lastRow As Long
Const I_OFFSET = -9999
lastRow = Range("A1").End(xlDown).Row
For i = 2 To lastRow
If Left(Cells(i, 1), 2) = "幼儿" Then Cells(i, 3) = Cells(i, 3) + I_OFFSET
Next
With Range("A1").CurrentRegion
.Sort key1:=.Columns(3), order1:=xlDescending, Header:=xlYes
End With
For i = 2 To lastRow
If Left(Cells(i, 1), 2) = "幼儿" Then Cells(i, 3) = Cells(i, 3) - I_OFFSET
Next
End Sub
【代码解析】
第5~7行代码根据班级修改“次数”列,如果班级包含“幼儿”,则将次数减去一个足够大的数
。
第8~10行代码对数据表按“次数”列降序排列,“幼儿”班级将被排列在最后。
第12行代码恢复“次数”列的原始数据。