跳转至

07 排序筛选

VBA 排序方法

在 Excel VBA 里排序是数据处理的基本操作之一,而最常用也是最“参数最多”的方法就是:

Range("A1:D100").Sort

这看起来简单,但它的参数多达 14 个,很多初学者看见就懵。本文将 逐个参数解释 + 多种案例代码 + 常见坑点总结,一步步带你掌握它的用法。(也可以参考微软官方文档对它的说明:微软学习)

一、Range.Sort 是什么?

Range.Sort 是 Excel VBA 中用于对某个区域按指定条件排序的方法。简单来说,它可以:

  • 单个字段排序
  • 多个字段排序(最多 3 层)
  • 控制是否有表头、排序方向、排序方式(比如中文拼音/笔画)
  • 对文本和数字的处理方式做出控制

其完整语法如下(为了方便理解,我按语义分组展示):

1
2
3
4
expression.Sort( _
  Key1, Order1, Key2, Type, Order2, Key3, Order3, _
  Header, OrderCustom, MatchCase, Orientation, _
  SortMethod, DataOption1, DataOption2, DataOption3)

其中:

  • expression = 要排序的 Range 区域
  • Key1~3 = 排序关键字(最多 3 个)
  • Order1~3 = 每个关键字的排序顺序

二、逐个参数详细解释

(1) Key1 / Order1 — 主排序关键字段及顺序

Key1:=Range("B1")
Order1:=xlAscending

表示:以 B 列为主排序字段,按升序排列(小 → 大,A → Z)。Key1 必须是一个 Range 对象,不是列号、也不是字符串。

(2)Key2 / Order2 — 第二排序字段(可选)

当 Key1 排序后出现相同的数据,再按 Key2 进行排序。比如我们想按成绩降序,如果成绩相同,再按姓名升序:

Key1:=Range("D1"), Order1:=xlDescending, _
Key2:=Range("A1"), Order2:=xlAscending
Key3 / Order3 — 第三排序字段也可以选择使用,但是最多支持三个层级排序,另外需要注意的是在Key2Order2中间有一个Type参数,是对透视表使用的,我们一般不会用到,写的时候注意隔开。

(3)Header — 是否有表头(非常关键)

Header:=xlYes
  • xlYes:有表头,第一行不参与排序
  • xlNo:无表头,全表参与排序
  • xlGuess:让 Excel 自动判断(不推荐,因为有可能会猜错)

(4) Orientation — 排序方向

默认是按列排序,也就是:Orientation:=xlTopToBottom,一般我们对行排序比较少,如果非要使用,则可以按这种方式书写:Orientation:=xlLeftToRight,这样就是横向排序。

(5)MatchCase — 是否区分大小写

MatchCase:=True代表区分大小写,而MatchCase:=False:表示不区分(这个是默认值),通常在英文字母排序时才有意义。

(6)SortMethod — 排序方法(对中文有用)

SortMethod:=xlPinYin    '按拼音排序
SortMethod:=xlStroke    '按笔画排序
其他的参数,比如OrderCustom自定义顺序,DataOption1/2/3定义文本排序方式都用的比较少,所以这里不展开介绍

三、最实用的排序案例代码

01 单列升序排序:比如A列是姓名列,我们按姓名升序排序。

1
2
3
4
Sub SortByName()
    Range("A1:D100").Sort _
        Key1:=Range("A1"), Order1:=xlAscending, Header:=xlYes
End Sub
02 单列降序排序:也可以按数值排序,例如D列是成绩列,我们可以按成绩由高到低排序:

1
2
3
4
Sub SortByScoreDesc()
    Range("A1:D100").Sort _
        Key1:=Range("D1"), Order1:=xlDescending, Header:=xlYes
End Sub
03 多字段排序(组合条件):可以进行多条件排序,先按部门(B列)升序,再按成绩(D列)降序:

1
2
3
4
5
6
Sub MultiLevelSort()
    Range("A1:D150").Sort _
        Key1:=Range("B1"), Order1:=xlAscending, _
        Key2:=Range("D1"), Order2:=xlDescending, _
        Header:=xlYes
End Sub
04 中文名字按拼音排序:这里需要用到SortMethod方法,来定义排序的方式

1
2
3
4
5
Sub SortChineseByPinYin()
    Range("A1:C200").Sort _
        Key1:=Range("A1"), Order1:=xlAscending, _
        Header:=xlYes, SortMethod:=xlPinYin
End Sub
05 横向排序(从左到右):这个用的比较少,但是还是提一下,例如按第一行横向排序,需要指定Orientation

1
2
3
4
5
Sub HorizontalSort()
    Range("A1:K1").Sort _
        Key1:=Range("A1"), Order1:=xlAscending, _
        Header:=xlNo, Orientation:=xlLeftToRight
End Sub

四、常见坑 & 必知注意事项

1.没有指定 Header 导致误判:不写 Header 时,Excel 可能误判第一行为数据而参与排序。

2.只对列排序不包含其它列 → 容易产生数据错位! 例如错误写法:

Range("A1:A100").Sort Key1:=Range("A1")
这样只有 A列 排序了,其它列不动,数据不再一行对应。正确写法应该是:

Range("A1:D100").Sort Key1:=Range("A1")
3.合并单元格会导致排序失败:排序前尽量避免合并单元格,否则结果可能不确定。

4.数字文本排序结果怪异:如果某列既有文本数字又有数字,排序可能不按“数值大小,需要先统一格式。

5.超过三层排序就用 Sort 对象更灵活:如果需要 4+ 层排序,建议用新式的 SortFields 方法替代如下,因为 Range.Sort 一次最多三个关键字,并且参数杂乱,所以 Excel 提供了更现代的排序 API:

Sub test()
    With Sheet1.Sort
        .SortFields.Clear '清除所有排序字段
        .SortFields.Add Key:=Sheet1.Range("E2:E11"), Order:=xlDescending '按E列降序
        .SortFields.Add Key:=Sheet1.Range("F2:F11"), Order:=xlDescending '按F列降序
        .SortFields.Add Key:=Sheet1.Range("G2:G11"), Order:=xlAscending '按G列升序
        .SortFields.Add Key:=Sheet1.Range("C2:C11"), Order:=xlDescending '按C列降序
        .SetRange Sheet1.Range("C1:H11") '设置排序范围为C1:H11
        .Header = xlYes '第一行是标题
        .Apply '应用排序
    End With
End Sub
这个 API 更适合 多条件动态排序与复杂规则排序,方法的好处是不影响一整行,而是只对SetRange设置的区域有效。


VBA筛选方法

在 Excel VBA 中,AutoFilter 是进行条件筛选最常用、也是最基础的方法之一。它很贴近日常 Excel 操作,几乎所有“像人手点筛选一样”的需求,都可以通过 AutoFilter 实现。

一、AutoFilter 的基本作用

AutoFilter 用于对 列表 / 表格区域 按指定条件进行筛选,效果等同于: Excel → 数据 → 筛选 → 下拉筛选条件,特点是:

  • 不改变原数据结构
  • 支持文本 / 数值 / 日期 / 颜色 / 动态筛选
  • 可多列叠加筛选
  • 语法相对简洁,适合 80% 的业务场景

语法可以表示为下式,通常我们只会用到前 1~4 个参数

Range.AutoFilter(Field, Criteria1, Operator, Criteria2, SubField, VisibleDropDown)

尤其是SubField参数,一般在透视表里用,所以我们这里不作介绍

二、参数详解(逐一拆解)

(1) Field —— 筛选列编号

比如Field := 1, 表示第几列,这个第几列是 从筛选区域的最左列开始计数,第一列为 1,而不是 Excel 的列号,比如下面这句话表示对 C 列进行筛选:

Range("B1:D100").AutoFilter Field:=2

(2) Criteria1 —— 筛选条件 1(最重要)

Criteria1 的写法非常灵活,常见形式如下:

  • 等于某个值:可以写作 Criteria1:="张三" 或者Criteria1:=100
  • 比较运算(必须是字符串):例如 Criteria1:=">80"Criteria1:="<=100"或者Criteria1:="<>0"
  • 支持通配符筛选(文本):例如Criteria1:="张*" 或者 Criteria1:="*有限公司"
  • 数组筛选(多值 OR):等价于 Excel 中勾选多个值,如下
Criteria1:=Array("北京", "上海", "广州")
Operator:=xlFilterValues

(3) Operator —— 运算关系

1.xlAndxlOr这两种情况,分别表示 (同时满足)与(满足其一)的关系,比如筛选 60~90 分之间的成绩:

1
2
3
4
5
Range("A1:D100").AutoFilter _
    Field:=4, _
    Criteria1:=">=60", _
    Operator:=xlAnd, _
    Criteria2:="<=90"
注意只有使用了 xlAndxlOr的情况下我们才会用到Criteria2

2.xlFilterValues(多选值筛选),比如同时筛选北京和上海:

1
2
3
4
Range("A1:D100").AutoFilter _
    Field:=2, _
    Criteria1:=Array("北京", "上海"), _
    Operator:=xlFilterValues

3.Top / Bottom 系列(数值排行)

1
2
3
4
Range("A1:D100").AutoFilter _
    Field:=4, _
    Criteria1:=10, _
    Operator:=xlTop10Items
具体是前百分之几或者是前几个,根据Criteria1来进行赋值,其他支持的情况如下表

Operator 说明 Operator 说明
xlTop10Items 前 N 个 xlTop10Percent 前 N%
xlBottom10Items 后 N 个 xlBottom10Percent 后 N%

4.颜色筛选:主要包括xlFilterCellColor(筛选单元格颜色) 和 xlFilterFontColor(筛选字体颜色)两种方式

1
2
3
4
5
6
```vba
Range("A1:D100").AutoFilter _
    Field:=3, _
    Criteria1:=RGB(255, 0, 0), _
    Operator:=xlFilterCellColor
```

5.动态筛选(xlFilterDynamic):这是 AutoFilter 最容易被忽略、但非常强大的功能,比如我们筛选高于平均值的数据

1
2
3
4
Range("A1:D100").AutoFilter _
    Field:=4, _
    Operator:=xlFilterDynamic, _
    Criteria1:=xlFilterAboveAverage

常见枚举值可参考下面这张表,参数可以自己修改,比如xlFilterAllDatesInPeriodAprilApril改成June就是6月:

Criteria1 说明 Criteria1 说明
xlFilterAboveAverage 高于平均值 xlFilterBelowAverage 低于平均值
xlFilterToday 今天 xlFilterThisMonth 本月
xlFilterThisYear 本年 xlFilterAllDatesInPeriodApril 4 月

(4)VisibleDropDown —— 是否显示筛选箭头VisibleDropDown:=True显示,否则不显示,默认是显示的,所以一般不写

三、常见实用代码段

1.AutoFilter 可以多次调用,筛选会叠加,例如下面这样等价于 “城市 = 北京” 并且 “成绩 > 80

1
2
3
4
With Range("A1:D100")
    .AutoFilter Field:=2, Criteria1:="北京"
    .AutoFilter Field:=4, Criteria1:=">80"
End With
2.清除筛选条件,也就是展开所有数据,可以使用ShowAllData方法

1
2
3
If ActiveSheet.FilterMode Then
    ActiveSheet.ShowAllData
End If
3.判断是否开启了自动筛选,可以用下面这段代码:

1
2
3
If ActiveSheet.AutoFilterMode Then
    ' 已开启筛选
End If
4.完全关闭筛选功能,直接设置AutoFilterMode = False 即可

本期系统给大家介绍了VBA的排序和筛选功能,基本能够涵盖工作中80%以上的应用场景