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