使用VBA編寫排序代碼(Sort方法)

看看下面的Excel界面截圖,“排序”和“篩選”往往在一起,這大概是很多數(shù)據(jù)需要先排序后篩選吧!


在Excel 2007中新增了Sort對象,在錄制宏時Excel會自動用到這個對象,但我們今天不會講解這個對象,待以后再詳解。今天主要講解Range對象的Sort方法,對于3個以內(nèi)的字段排序很方便。其語法如下:

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所有參數(shù)均可選。

l參數(shù)Key1、Key2、Key3指定排序字段,確定要排序的值,但參數(shù)Key2、Key3不能用于排序數(shù)據(jù)透視表。

l參數(shù)Order1、Order2、Order3,分別確定參數(shù)Key1、Key2、Key3指定值的排序順序,相應的常量值是xlDescending或者xlAscending(默認)。

l參數(shù)Type,指定要排序的元素。僅用于數(shù)據(jù)透視表,可以指定為xlSortLabels或者xlSortValues。

l參數(shù)Header,指定是否第一行包含標題信息,默認為xlNo。如果想要Excel嘗試確定標題,那么指定其值為xlGuess。

l參數(shù)OrderCustom,指定一個基于1的整數(shù)偏移量到自定義排序順序列表,使用自定義的排序順序進行排序。

l參數(shù)MatchCase,設置為True執(zhí)行區(qū)分大小寫的排序,為False則執(zhí)行不區(qū)分大小寫的排序,不能用于數(shù)據(jù)透視表。

l參數(shù)Orientation,默認按行進行排序且數(shù)據(jù)是垂直排列。如果數(shù)據(jù)是水平排列的,通過指定該參數(shù)使其按列進行排序。相應的常量值是xlSortRows或者xlSortColumn。

l參數(shù)SortMethod,指定排序方法,適用于除英語以外的語言。

l參數(shù)DataOption,有3個參數(shù),用來指定排序時對單元格中文本和數(shù)字的處理。如果指定其值為xlSortTextAsNumbers,將文本當作數(shù)據(jù)進行排序,默認值是xlSortNormal,分別對數(shù)字和文本數(shù)據(jù)排序。不能應用于數(shù)據(jù)透視表排序。

參數(shù)DataOption1用于指定如何排序在Key1中指定的單元格區(qū)域中的文本。

參數(shù)DataOption2,用于指定如何排序在Key2中指定的單元格區(qū)域中的文本。

參數(shù)DataOption3,用于指定如何排序在Key3中指定的單元格區(qū)域中的文本。

下面以下圖所示的工作表來演示,以理解Sort方法及其參數(shù)。主要是介紹前面幾個參數(shù),其它的參數(shù)將會在以后的文章中涉及時再進行相應講解。

首先以“性別”作為排序字段,升序排列,并且第一行作為標題信息,代碼如下:

Sub testSort1()

Dim rng As Range

'設置要排序的區(qū)域

Set rng = Range("A1:G10")

'排序

rng.Sort Key1:="性別",

Order1:=xlAscending, Header:=xlYes

End Sub

運行代碼后的結(jié)果如下圖:

接下來,再添加排序字段:以“性別”作為第1排序字段升序排列,以“總分”作為第2排序字段降序排列。代碼如下:

Sub testSort2()

Dim rng As Range

'設置要排序的區(qū)域

Set rng = Range("A1:G10")

'排序

rng.Sort Key1:="性別",

Order1:=xlAscending, _

Key2:="總分",

Order2:=xlDescending, _

Header:=xlYes

End Sub

Excel將會以“性別”作為主要關鍵字升序排列,以“總分”作為次要關鍵字降序排列,即主關鍵字排序相同的,再以次關鍵字排序。結(jié)果如下圖所示:

示例1:查找滿足某項條件的所有數(shù)據(jù)并按順序排列

仍以上面的工作表為例,我們需要所有男同學的成績并以總分從高到低的順序排列。將排序與自動篩選結(jié)合,可達到我們的目的。

代碼如下:

Sub testSort3()

Dim rng As Range

'設置要排序的區(qū)域

Set rng = Range("A1:G10")

'排序

rng.Sort Key1:="性別",

Order1:=xlAscending, _

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

_

Header:=xlYes

'篩選

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

End Sub

運行代碼后的效果如下圖:

示例2:查找滿足某項條件的不重復數(shù)據(jù)

如本文開頭所示的工作表,要求獲取男女同學中總分最高的同學數(shù)據(jù)記錄。將排序與高級篩選相結(jié)合,可以達到我們的目的。

Sub testSort4()

Dim rng As Range

'設置要排序的區(qū)域

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)

表示單元格區(qū)域rng中的第3列,即“性別”字段列。

運行代碼后的效果如下圖:

示例3:雙擊列標題自動排序

在本文的示例工作表中,雙擊列標題,會升序排列該標題下的內(nèi)容,再次雙擊該列標題,降序排列。代碼如下:

'聲明變量,用于存儲升序降序值及排序列號

Dim iDirection As Integer

Dim iColumn As Integer

Private Sub

Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)

Dim rng As Range

'設置排序的單元格區(qū)域

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事件中,在工作表單元格中雙擊鼠標時發(fā)生該事件。(關于工作表事件,將在本系列文章后面的Worksheet對象系列中詳細講解)

l在模塊頂部子過程外面聲明變量,表明該變量可用于該模塊下所有的子過程。本程序代碼之所以在模塊頂部聲明變量,是為了保存雙擊事件發(fā)生前變量的值,以便與雙擊事件發(fā)生后相關值比較,從而實現(xiàn)升序和降序的切換。(關于變量作用范圍,將在本系列文章后面詳細講解)

lRange("A1").CurrentRegion獲取單元格A1所在的區(qū)域,可參閱《Excel

VBA解讀(38):快速確定自已的地盤——CurrentRegion屬性》。

示例4:根據(jù)活動單元格排序

在上文所示的工作表中,當單元格在A1:G10區(qū)域內(nèi)移動時,將根據(jù)活動單元格所處的位置對其所在列按降序排序。代碼如下:

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事件中,當活動單元格發(fā)生變化時觸發(fā)該事件。(關于工作表事件,將在本系列文章后面的Worksheet對象系列中詳細講解)

示例5:根據(jù)顏色排序

這是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中的數(shù)據(jù)排序

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方法用于清除單元格中的內(nèi)容。

l代碼運行的過程及結(jié)果如下圖所示:

示例6:排序有部分相同數(shù)據(jù)的行

如下圖所示,課程的組合有3種,分別是“語文、數(shù)學、英語”,“數(shù)學、體育、歷史”,“體育、化學、生物”,但上課的時間不同,要求將相同組合的課程排在一起。

代碼如下:

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

'設置排序數(shù)據(jù)區(qū)域并按課程組合排序

Set rng = rng.Resize(, 5)

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

'清除輔助列內(nèi)容

rng.Columns(5).ClearContents

End Sub

說明

l技巧:將多列組合成一列,并將該列作為排序列,從而達到相同數(shù)據(jù)排序在一起的目的。

示例7:自定義排序

如下圖所示,我們想按單元格區(qū)域I1:I5中的順序?qū)卧駞^(qū)域A1:G10進行排序。也就是說,無論數(shù)據(jù)如何變化,在單元格區(qū)域I1:I5中的5名同學都是按照這樣的順序排列。

代碼如下:

Sub CustomSort()

Dim iListNum As Integer

'添加自定義列表

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

'獲取列表編號

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

'使用自定義列表排序

'注意,應使用iListNum+1作為參數(shù)OrderCustom的值

‘指定自定義列表(參見OrderCustom參數(shù)說明)

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)

添加自定義列表,用于自定義自動填充或自定義排序。其中,參數(shù)ListArray必需,指定自定義排序數(shù)據(jù),可以是字符串數(shù)組或者Range對象。參數(shù)ByRow可選,僅用于當參數(shù)ListArray是Range對象時;設置為True時從單元格區(qū)域中的行創(chuàng)建自定義列表,設置為False時從單元格區(qū)域的列創(chuàng)建自定義列表;如果忽略該參數(shù)且單元格區(qū)域中的列比行多,那么將從單元格區(qū)域行創(chuàng)建自定義列表。

注意,如果試圖添加的列表已存在,那么該方法不會執(zhí)行任何操作,會報出錯消息。

lGetCustomListNum方法的語法如下:

Application對象.GetCustomListNum(ListArray)

返回字符串數(shù)組的自定義列表編號,可以用于匹配內(nèi)置列表和自定義列表。其中,參數(shù)ListArray必需,指定字符串數(shù)組。

注意,如果沒有相應的列表,那么該方法將導致錯誤。

lDeleteCustomList方法的語法如下:

Application對象.DeleteCustomList(ListNum)

刪除自定義列表。其中,參數(shù)ListNum必需,指定自定義列表編號。編號必須大于或等于5,因為Excel有4個內(nèi)置的不可刪除的自定義列表。

注意,如果列表編號小于5或者沒有相匹配的自定義列表,那么該方法將導致錯誤。(這是Excel 2013幫助文檔中的說明,實際上Excel 2007中就有11個內(nèi)置的不可刪除的列表。)

運行代碼后的結(jié)果如下圖:


本文首發(fā)于完美Excel公眾號:excelperfect

原標題為《Excel VBA解讀(54):排序——Sort方法》,轉(zhuǎn)載請注明來源。

歡迎分享與交流。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • 本例為設置密碼窗口 (1) If Application.InputBox(“請輸入密碼:”) = 1234 Th...
    浮浮塵塵閱讀 14,663評論 1 20
  • 在面對大量數(shù)據(jù)時,我們可以使用Excel的篩選功能,濾出我們需要的信息。在本文中,我們先從Excel中的“篩選”命...
    完美Excel閱讀 66,122評論 0 16
  • 1.1 VBA是什么 直到90年代早期,使應用程序自動化還是充滿挑戰(zhàn)性的領域.對每個需要自動化的應用程序,人們不得...
    浮浮塵塵閱讀 22,136評論 6 49
  • 入庫單的輸入,查找,刪除與修改 一 查找功能 在VBA中查找主要有三種方法,第一是使用循環(huán)查找(在單元格中查找效率...
    肉丸子豆閱讀 846評論 2 3
  • 這個標題有點不一樣! 月底的最后兩個半小時,我在趕作業(yè),也是在逼迫自己,其實這算不上逼迫,不過是練習,一點一點想象...
    海豚的世界閱讀 354評論 0 0

友情鏈接更多精彩內(nèi)容