使用VBA编写排序代码(Sort方法)

看看下面的Excel界面截图,“排序”和“筛选”往往在一起,这大概是很多数据需要先排序后筛选吧!


在Excel 2007中新增了Sort对象,在录制宏时Excel会自动用到这个对象,但我们今天不会讲解这个对象,待以后再详解。今天主要讲解Range对象的Sort方法,对于3个以内的字段排序很方便。其语法如下:

Range对象.Sort(Key1,Order1 As XlSortOrder, _

Key2,Type,Order2As XlSortOrder, _

Key3,Order3As XlSortOrder, _

HeaderAs XlYesNoGuess, _

OrderCustom,MatchCase,_

OrientationAs XlSortOrientation, _

SortMethodAs XlSortMethod, _

DataOption1As XlSortDataOption, _

DataOption2As XlSortDataOption, _

DataOption3As XlSortDataOption)

说明

l所有参数均可选。

l参数Key1、Key2、Key3指定排序字段,确定要排序的值,但参数Key2、Key3不能用于排序数据透视表。

l参数Order1、Order2、Order3,分别确定参数Key1、Key2、Key3指定值的排序顺序,相应的常量值是xlDescending或者xlAscending(默认)。

l参数Type,指定要排序的元素。仅用于数据透视表,可以指定为xlSortLabels或者xlSortValues。

l参数Header,指定是否第一行包含标题信息,默认为xlNo。如果想要Excel尝试确定标题,那么指定其值为xlGuess。

l参数OrderCustom,指定一个基于1的整数偏移量到自定义排序顺序列表,使用自定义的排序顺序进行排序。

l参数MatchCase,设置为True执行区分大小写的排序,为False则执行不区分大小写的排序,不能用于数据透视表。

l参数Orientation,默认按行进行排序且数据是垂直排列。如果数据是水平排列的,通过指定该参数使其按列进行排序。相应的常量值是xlSortRows或者xlSortColumn。

l参数SortMethod,指定排序方法,适用于除英语以外的语言。

l参数DataOption,有3个参数,用来指定排序时对单元格中文本和数字的处理。如果指定其值为xlSortTextAsNumbers,将文本当作数据进行排序,默认值是xlSortNormal,分别对数字和文本数据排序。不能应用于数据透视表排序。

参数DataOption1用于指定如何排序在Key1中指定的单元格区域中的文本。

参数DataOption2,用于指定如何排序在Key2中指定的单元格区域中的文本。

参数DataOption3,用于指定如何排序在Key3中指定的单元格区域中的文本。

下面以下图所示的工作表来演示,以理解Sort方法及其参数。主要是介绍前面几个参数,其它的参数将会在以后的文章中涉及时再进行相应讲解。

首先以“性别”作为排序字段,升序排列,并且第一行作为标题信息,代码如下:

Sub testSort1()

Dim rng As Range

'设置要排序的区域

Set rng = Range("A1:G10")

'排序

rng.Sort Key1:="性别",

Order1:=xlAscending, Header:=xlYes

End Sub

运行代码后的结果如下图:

接下来,再添加排序字段:以“性别”作为第1排序字段升序排列,以“总分”作为第2排序字段降序排列。代码如下:

Sub testSort2()

Dim rng As Range

'设置要排序的区域

Set rng = Range("A1:G10")

'排序

rng.Sort Key1:="性别",

Order1:=xlAscending, _

Key2:="总分",

Order2:=xlDescending, _

Header:=xlYes

End Sub

Excel将会以“性别”作为主要关键字升序排列,以“总分”作为次要关键字降序排列,即主关键字排序相同的,再以次关键字排序。结果如下图所示:

示例1:查找满足某项条件的所有数据并按顺序排列

仍以上面的工作表为例,我们需要所有男同学的成绩并以总分从高到低的顺序排列。将排序与自动筛选结合,可达到我们的目的。

代码如下:

Sub testSort3()

Dim rng As Range

'设置要排序的区域

Set rng = Range("A1:G10")

'排序

rng.Sort Key1:="性别",

Order1:=xlAscending, _

Key2:="总分", Order2:=xlDescending,

_

Header:=xlYes

'筛选

rng.AutoFilter Field:=3, Criteria1:="男"

End Sub

运行代码后的效果如下图:

示例2:查找满足某项条件的不重复数据

如本文开头所示的工作表,要求获取男女同学中总分最高的同学数据记录。将排序与高级筛选相结合,可以达到我们的目的。

Sub testSort4()

Dim rng As Range

'设置要排序的区域

Set rng = Range("A1:G10")

'排序

rng.Sort Key1:="性别",

Order1:=xlAscending, _

Key2:="总分",

Order2:=xlDescending, _

Header:=xlYes

'筛选

rng.Columns(3).AdvancedFilterAction:=xlFilterInPlace, _

Unique:=True

End Sub

代码中的:

rng.Columns(3)

表示单元格区域rng中的第3列,即“性别”字段列。

运行代码后的效果如下图:

示例3:双击列标题自动排序

在本文的示例工作表中,双击列标题,会升序排列该标题下的内容,再次双击该列标题,降序排列。代码如下:

'声明变量,用于存储升序降序值及排序列号

Dim iDirection As Integer

Dim iColumn As Integer

Private Sub

Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)

Dim rng As Range

'设置排序的单元格区域

Set rng =Range("A1").CurrentRegion

'限定在前8列第1行

If Target.Column < 8 And Target.Row = 1Then

If Target.Column <> iColumn Then

iColumn = Target.Column

'默认设置为升序排列

iDirection = xlAscending

Else

'在升序与降序之间切换

If iDirection = xlAscending Then

iDirection = xlDescending

Else

iDirection = xlAscending

End If

End If

'排序

rng.Sort Key1:=rng.Cells(1, iColumn), _

Order1:=iDirection, _

Header:=xlYes

End If

End Sub

说明

l代码位于工作表模块的Worksheet_BeforeDoubleClick事件中,在工作表单元格中双击鼠标时发生该事件。(关于工作表事件,将在本系列文章后面的Worksheet对象系列中详细讲解)

l在模块顶部子过程外面声明变量,表明该变量可用于该模块下所有的子过程。本程序代码之所以在模块顶部声明变量,是为了保存双击事件发生前变量的值,以便与双击事件发生后相关值比较,从而实现升序和降序的切换。(关于变量作用范围,将在本系列文章后面详细讲解)

lRange("A1").CurrentRegion获取单元格A1所在的区域,可参阅《Excel

VBA解读(38):快速确定自已的地盘——CurrentRegion属性》。

示例4:根据活动单元格排序

在上文所示的工作表中,当单元格在A1:G10区域内移动时,将根据活动单元格所处的位置对其所在列按降序排序。代码如下:

Private Sub

Worksheet_SelectionChange(ByVal Target As Range)

Dim rng As Range

Set rng = Range("A1:G10")

'将范围限定在列A至列G和1至10行

If Target.Column < 8 And Target.Row <11 Then

rng.Sort Key1:=ActiveCell,Order1:=xlDescending, Header:=xlYes

End If

End Sub

说明

l代码位于工作表模块的Worksheet_SelectionChange事件中,当活动单元格发生变化时触发该事件。(关于工作表事件,将在本系列文章后面的Worksheet对象系列中详细讲解)

示例5:根据颜色排序

这是Excel 2013 VBA帮助文档中Sort方法的示例,按单元格的背景色进行排序。示例代码如下:

Sub SortbyColor()

Dim lngLastRow As Long

Dim i As Long

'列A中最后一个单元格

lngLastRow = Range("A" &Rows.Count).End(xlUp).Row

'遍历列A中的单元格并将其背景色索引值放置在列C中相应单元格

For i = 2 To lngLastRow

Cells(i, 3) = Cells(i,1).Interior.ColorIndex

Next i

'基于列C中的数据排序

Range("C1") = "索引值"

Columns("A:C").SortKey1:=Range("C1"), _

Order1:=xlAscending, Header:=xlYes

'清除列C中用于排序的临时值

Columns(3).ClearContents

End Sub

说明

l代码中,首先使用ColorIndex属性获取列A中单元格颜色索引值,并将这些值存储在列C中的相应行,然后对列C排序,从而达到对列A按颜色排序的效果。

lClearContents方法用于清除单元格中的内容。

l代码运行的过程及结果如下图所示:

示例6:排序有部分相同数据的行

如下图所示,课程的组合有3种,分别是“语文、数学、英语”,“数学、体育、历史”,“体育、化学、生物”,但上课的时间不同,要求将相同组合的课程排在一起。

代码如下:

Sub SortSameData()

Dim rng As Range

Dim str As String

Dim i As Long, j As Long

Set rng = Range("A1:D10")

'提取课程组合并放置在排序辅助列

For i = 2 To rng.Rows.Count

str = ""

For j = 2 To rng.Columns.Count

str = str & Cells(i, j)

Next j

Cells(i, j) = str

Next i

'设置排序数据区域并按课程组合排序

Set rng = rng.Resize(, 5)

rng.Sort Key1:=rng.Columns(5),Order1:=xlDescending, Header:=xlYes

'清除辅助列内容

rng.Columns(5).ClearContents

End Sub

说明

l技巧:将多列组合成一列,并将该列作为排序列,从而达到相同数据排序在一起的目的。

示例7:自定义排序

如下图所示,我们想按单元格区域I1:I5中的顺序对单元格区域A1:G10进行排序。也就是说,无论数据如何变化,在单元格区域I1:I5中的5名同学都是按照这样的顺序排列。

代码如下:

Sub CustomSort()

Dim iListNum As Integer

'添加自定义列表

Application.AddCustomListListArray:=Range("I1:I5")

'获取列表编号

iListNum =Application.GetCustomListNum(Range("I1:I5").Value)

'使用自定义列表排序

'注意,应使用iListNum+1作为参数OrderCustom的值

‘指定自定义列表(参见OrderCustom参数说明)

Range("A1:G10").Sort Key1:=Range("B1"),Order1:=xlAscending, _

Header:=xlYes,OrderCustom:=iListNum + 1

'移除自定义列表,以便于再次运行代码

Application.DeleteCustomList iListNum

End Sub

说明

l这段程序代码中有3个我们以前没有见过的方法,即Application对象的AddCustomList方法、GetCustomListNum方法、DeleteCustomList方法。与排序相匹配使用的。(注:也与自动填充相匹配)

lAddCustomList方法的语法如下:

Application对象.AddCustomList(ListArray,ByRow)

添加自定义列表,用于自定义自动填充或自定义排序。其中,参数ListArray必需,指定自定义排序数据,可以是字符串数组或者Range对象。参数ByRow可选,仅用于当参数ListArray是Range对象时;设置为True时从单元格区域中的行创建自定义列表,设置为False时从单元格区域的列创建自定义列表;如果忽略该参数且单元格区域中的列比行多,那么将从单元格区域行创建自定义列表。

注意,如果试图添加的列表已存在,那么该方法不会执行任何操作,会报出错消息。

lGetCustomListNum方法的语法如下:

Application对象.GetCustomListNum(ListArray)

返回字符串数组的自定义列表编号,可以用于匹配内置列表和自定义列表。其中,参数ListArray必需,指定字符串数组。

注意,如果没有相应的列表,那么该方法将导致错误。

lDeleteCustomList方法的语法如下:

Application对象.DeleteCustomList(ListNum)

删除自定义列表。其中,参数ListNum必需,指定自定义列表编号。编号必须大于或等于5,因为Excel有4个内置的不可删除的自定义列表。

注意,如果列表编号小于5或者没有相匹配的自定义列表,那么该方法将导致错误。(这是Excel 2013帮助文档中的说明,实际上Excel 2007中就有11个内置的不可删除的列表。)

运行代码后的结果如下图:


本文首发于完美Excel公众号:excelperfect

原标题为《Excel VBA解读(54):排序——Sort方法》,转载请注明来源。

欢迎分享与交流。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容

  • 本例为设置密码窗口 (1) If Application.InputBox(“请输入密码:”) = 1234 Th...
    浮浮尘尘阅读 13,609评论 1 20
  • 在面对大量数据时,我们可以使用Excel的筛选功能,滤出我们需要的信息。在本文中,我们先从Excel中的“筛选”命...
    完美Excel阅读 64,639评论 0 16
  • 1.1 VBA是什么 直到90年代早期,使应用程序自动化还是充满挑战性的领域.对每个需要自动化的应用程序,人们不得...
    浮浮尘尘阅读 21,715评论 6 49
  • 入库单的输入,查找,删除与修改 一 查找功能 在VBA中查找主要有三种方法,第一是使用循环查找(在单元格中查找效率...
    肉丸子豆阅读 700评论 2 3
  • 这个标题有点不一样! 月底的最后两个半小时,我在赶作业,也是在逼迫自己,其实这算不上逼迫,不过是练习,一点一点想象...
    海豚的世界阅读 298评论 0 0