Excel VBA 数组排序
作者:parno 日期:2009-05-19
使用EXCEL的VBA编程时,经常会用到数组,有时需要对数组进行排序,在这里介绍一下数字数组排序的常用方法以及带有EXCEL特色的函数排序方法(所举例子均以升序排列数组)。
在介绍具体方法之前,先给个数组生成过程。(将数组a(1 to 50)定义成公用数组)
1、快速排序法
2、冒泡排序法
3、桶排序法
4、希尔排序法
5、选择排序法
以上五种排序方法均是数组排序的常用方法,优点是不需借助辅助单元格。执行效率视数组成员的相对有序性的不同而不同。以附件中的50位一维数组为例,快速排序法的循环次数是745次、冒泡法的循环次数是1225次、桶排序法的循环次数是704次、希尔排序法的循环次数是347次、选择排序法的循环次数为1225次。
下面再介绍两种用EXCEL函数的排序方法,一般来说使用EXCEL自带函数或方法的执行效率会高一些,但限于函数参数的限制有的不得不借助于辅助单元格。
6、SMALL函数法
原数组不变,生成一个新的按升序排列的数组。
同理也可以用LARGE函数。我个人觉得用这种方法较快。
7、RANK函数法
此方法的缺点是需要借助辅助单元格。当然如果借助辅助单元格的话完全可以用EXCEL的排序功能,在这里就没必要详述了。
上述内容如有错误之处,请会员们指正。如有其它好的排序方法也可以跟贴补充。希望对大家能有所帮助。
在介绍具体方法之前,先给个数组生成过程。(将数组a(1 to 50)定义成公用数组)
复制内容到剪贴板 程序代码
Sub MakeArr()
For i = 1 To 50
a(i) = Int(Rnd(1) * 890 + 10)
Next i
End Sub
For i = 1 To 50
a(i) = Int(Rnd(1) * 890 + 10)
Next i
End Sub
1、快速排序法
复制内容到剪贴板 程序代码
Sub FastSort()
M = 1
For i = 1 To 49
If a(i) <= a(i + 1) Then
If i > M Then
M = i
Else
i = M
End If
GoTo kk:
Else
x = a(i)
a(i) = a(i + 1)
a(i + 1) = x
If i <> 1 Then i = i - 2
End If
kk:
Next i
End Sub
M = 1
For i = 1 To 49
If a(i) <= a(i + 1) Then
If i > M Then
M = i
Else
i = M
End If
GoTo kk:
Else
x = a(i)
a(i) = a(i + 1)
a(i + 1) = x
If i <> 1 Then i = i - 2
End If
kk:
Next i
End Sub
2、冒泡排序法
复制内容到剪贴板 程序代码
Sub BubbleSort()
For i = 1 To 49
For j = i + 1 To 50
If a(i) > a(j) Then
TEMP = a(j)
a(j) = a(i)
a(i) = TEMP
End If
Next j
Next i
End Sub
For i = 1 To 49
For j = i + 1 To 50
If a(i) > a(j) Then
TEMP = a(j)
a(j) = a(i)
a(i) = TEMP
End If
Next j
Next i
End Sub
3、桶排序法
复制内容到剪贴板 程序代码
Sub Bucket()
Dim Index
Dim tempnum
For i = 2 To 50
tempnum = a(i)
Index = i
Do
If Index > 1 Then
If tempnum < a(Index - 1) Then
a(Index) = a(Index - 1)
Index = Index - 1
Else
Exit Do
End If
Else
Exit Do
End If
Loop
a(Index) = tempnum
Next
End Sub
Dim Index
Dim tempnum
For i = 2 To 50
tempnum = a(i)
Index = i
Do
If Index > 1 Then
If tempnum < a(Index - 1) Then
a(Index) = a(Index - 1)
Index = Index - 1
Else
Exit Do
End If
Else
Exit Do
End If
Loop
a(Index) = tempnum
Next
End Sub
4、希尔排序法
复制内容到剪贴板 程序代码
Sub ShellSort()
Dim skipnum
Dim Index
Dim i
Dim tempnum
Size = 50
skipnum = Int((Size / 2)) - 1
Do While skipnum > 0
i = 1 + skipnum
For j = i To 50
Index = j
Do
If Index >= (1 + skipnum) Then
If a(Index) < a(Index - skipnum) Then
tempnum = a(Index)
a(Index) = a(Index - skipnum)
a(Index - skipnum) = tempnum
Index = Index - skipnum
Else
Exit Do
End If
Else
Exit Do
End If
Loop
Next
skipnum = (skipnum - 1) / 2
Loop
End Sub
Dim skipnum
Dim Index
Dim i
Dim tempnum
Size = 50
skipnum = Int((Size / 2)) - 1
Do While skipnum > 0
i = 1 + skipnum
For j = i To 50
Index = j
Do
If Index >= (1 + skipnum) Then
If a(Index) < a(Index - skipnum) Then
tempnum = a(Index)
a(Index) = a(Index - skipnum)
a(Index - skipnum) = tempnum
Index = Index - skipnum
Else
Exit Do
End If
Else
Exit Do
End If
Loop
Next
skipnum = (skipnum - 1) / 2
Loop
End Sub
5、选择排序法
复制内容到剪贴板 程序代码
Sub SelectionSort()
Dim Index
Dim Min
Dim i
Dim tempnum
BzArr
i = 1
While (i < 50)
Min = 50
Index = Min - 1
While (Index >= i)
If a(Index) < a(Min) Then
Min = Index
End If
Index = Index - 1
Wend
tempnum = a(Min)
a(Min) = a(i)
a(i) = tempnum
i = i + 1
Wend
End Sub
Dim Index
Dim Min
Dim i
Dim tempnum
BzArr
i = 1
While (i < 50)
Min = 50
Index = Min - 1
While (Index >= i)
If a(Index) < a(Min) Then
Min = Index
End If
Index = Index - 1
Wend
tempnum = a(Min)
a(Min) = a(i)
a(i) = tempnum
i = i + 1
Wend
End Sub
以上五种排序方法均是数组排序的常用方法,优点是不需借助辅助单元格。执行效率视数组成员的相对有序性的不同而不同。以附件中的50位一维数组为例,快速排序法的循环次数是745次、冒泡法的循环次数是1225次、桶排序法的循环次数是704次、希尔排序法的循环次数是347次、选择排序法的循环次数为1225次。
下面再介绍两种用EXCEL函数的排序方法,一般来说使用EXCEL自带函数或方法的执行效率会高一些,但限于函数参数的限制有的不得不借助于辅助单元格。
6、SMALL函数法
复制内容到剪贴板 程序代码
Sub SmallSort()
Dim b(1 To 50)
For i = 1 To 50
b(i) = Application.WorksheetFunction.Small(a, i)
Next
End Sub
Dim b(1 To 50)
For i = 1 To 50
b(i) = Application.WorksheetFunction.Small(a, i)
Next
End Sub
原数组不变,生成一个新的按升序排列的数组。
同理也可以用LARGE函数。我个人觉得用这种方法较快。
7、RANK函数法
复制内容到剪贴板 程序代码
Sub RankSort()
BzArr
Dim b(1 To 50)
For i = 1 To 50
Sheet2.Cells(i, 1) = a(i)
Next
Set rankrange = Sheet2.Range("a1:a50")
For i = 1 To 50
For k = 0 To Application.WorksheetFunction.CountIf(rankrange, Sheet2.Cells(i, 1)) - 1
j = Application.WorksheetFunction.Rank(Sheet2.Cells(i, 1), rankrange, 1)
a(j + k) = Sheet2.Cells(i, 1)
Next
Next
For i = 1 To 50
Sheet1.Cells(i + 2, 7) = a(i)
Next
End Sub
BzArr
Dim b(1 To 50)
For i = 1 To 50
Sheet2.Cells(i, 1) = a(i)
Next
Set rankrange = Sheet2.Range("a1:a50")
For i = 1 To 50
For k = 0 To Application.WorksheetFunction.CountIf(rankrange, Sheet2.Cells(i, 1)) - 1
j = Application.WorksheetFunction.Rank(Sheet2.Cells(i, 1), rankrange, 1)
a(j + k) = Sheet2.Cells(i, 1)
Next
Next
For i = 1 To 50
Sheet1.Cells(i + 2, 7) = a(i)
Next
End Sub
此方法的缺点是需要借助辅助单元格。当然如果借助辅助单元格的话完全可以用EXCEL的排序功能,在这里就没必要详述了。
上述内容如有错误之处,请会员们指正。如有其它好的排序方法也可以跟贴补充。希望对大家能有所帮助。
[本日志由 parno 于 2009-12-15 04:49 AM 编辑]
上一篇: VB 中的 Unicode 和 Ansi 下一篇: 创建 CorelDRAW 的 COM Add-in
文章来自: 网络
引用通告: 查看所有引用 | 我要引用此文章
Tags: VBA VisualBasic Excel 数组 排序
相关日志:
评论: 0 | 引用: 0 | 查看次数: 12346
发表评论