问题描述
我已经定义了以下阵列暗淡myArray的(10,5),只要
,并想对它进行排序。什么是做到这一点的最好的方法?
我将需要处理很多像1000×5矩阵的数据。它主要包含数字和日期,需要按照一定的列进行排序它
下面是一个多列和VBA单柱快速排序,从发表吉姆·雷赫在Usenet一个code样品修改。
注:
您会注意到,我做一个的很多的防御性的编码比你在大多数的code样品看出来有网站:这是一个Excel论坛,你已经得到,如果你的源阵列来自(说)第三方实时市场数据源预见阵列空值和空值...或嵌套数组和对象。
空值和无效项被发送到列表的末尾。
您的通话将是:
快速排序MYARRAY ,,, 2
...传递到排序上2列并排除通过上面的可选参数和搜索域名的下限。
将帖子 - 固定在&lt奇数格式毛刺; code>标签,这似乎有一个问题,在code注释的超链接。
我切除超链接是探测阵列的变体,VBA
公用Sub QuickSortArray(为ByRef SortArray为Variant,可选lngMin只要= -1,可选lngMax只要= -1,可选lngColumn只要= 0)
在错误恢复下一页 '排序的2维数组 SampleUsage:排序arrData按列3的内容
QuickSortArray arrData,3
发贴者吉姆·雷赫10/20/98 Excel.Programming 修改后,奈杰尔·赫弗南: ''逃生空变异比较失败
''防御性编码:检查输入 昏暗我只要
昏暗Ĵ只要
昏暗varMid为Variant
昏暗arrRowTemp为Variant
昏暗lngColTemp只要 如果为IsEmpty(SortArray)然后
退出小组
万一
如果INSTR(类型名(SortArray),())下; 1然后'IsArray的()是有点破:寻找在类型名称中括号
退出小组
万一
如果lngMin = -1然后
lngMin = LBOUND(SortArray,1)
万一
如果lngMax = -1然后
lngMax = UBound函数(SortArray,1)
万一
如果lngMin> = lngMax然后'无需排序
退出小组
万一 I = lngMin
J = lngMax varMid =空
varMid = SortArray((lngMin + lngMax)\\ 2,lngColumn) 我们送'空'和无效的数据项的列表的末尾:
如果则IsObject(varMid)然后请注意,我们不检查则IsObject(SortArray(N)) - varMid *威力*拿起一个有效的默认成员或财产
I = lngMax
J = lngMin
elseif的的IsEmpty(varMid)然后
I = lngMax
J = lngMin
elseif的ISNULL(varMid)然后
I = lngMax
J = lngMin
elseif的varMid =那
I = lngMax
J = lngMin
elseif的VarType函数(varMid)= vbError然后
I = lngMax
J = lngMin
elseif的VarType函数(varMid)GT; 17以后
I = lngMax
J = lngMin
万一 虽然我< = j的
虽然SortArray(I,lngColumn)LT; varMid和I< lngMax
I = I + 1
WEND
虽然varMid< SortArray(J,lngColumn)和J> lngMin
当J = J - 1
WEND 如果我< = j的再
交换行
使用ReDim arrRowTemp(LBOUND(SortArray,2)向UBound函数(SortArray,2))
为lngColTemp = LBOUND(SortArray,2)向UBound函数(SortArray,2)
arrRowTemp(lngColTemp)= SortArray(I,lngColTemp)
SortArray(I,lngColTemp)= SortArray(J,lngColTemp)
SortArray(J,lngColTemp)= arrRowTemp(lngColTemp)
接下来lngColTemp
擦除arrRowTemp I = I + 1
当J = J - 1
万一
WEND 如果(lngMin< j)条然后调用QuickSortArray(SortArray,lngMin,J,lngColumn)
如果(I< lngMax)然后调用QuickSortArray(SortArray,我,lngMax,lngColumn)结束小组
公用Sub QuickSortVector(为ByRef SortArray为Variant,可选lngMin只要= -1,可选lngMax只要= -1)
在错误恢复下一页 排序一维数组 SampleUsage:排序arrData
QuickSortVector arrData
原帖由吉姆·雷赫10/20/98 Excel.Programming
修改后,奈杰尔·赫弗南:
''逃生与数组中的空变异比较失败
''防御性编码:检查输入 昏暗我只要
昏暗Ĵ只要
昏暗varMid为Variant
昏暗VARx前提为Variant 如果为IsEmpty(SortArray)然后
退出小组
万一
如果INSTR(类型名(SortArray),())下; 1然后'IsArray的()是有点破:寻找在类型名称中括号
退出小组
万一
如果lngMin = -1然后
lngMin = LBOUND(SortArray)
万一
如果lngMax = -1然后
lngMax = UBound函数(SortArray)
万一
如果lngMin> = lngMax然后'无需排序
退出小组
万一 I = lngMin
J = lngMax varMid =空
varMid = SortArray((lngMin + lngMax)\\ 2) 我们送'空'和无效的数据项的列表的末尾:
如果则IsObject(varMid)然后请注意,我们不检查则IsObject(SortArray(N)) - varMid *威力*拿起一个默认成员或属性
I = lngMax
J = lngMin
elseif的的IsEmpty(varMid)然后
I = lngMax
J = lngMin
elseif的ISNULL(varMid)然后
I = lngMax
J = lngMin
elseif的varMid =那
I = lngMax
J = lngMin
elseif的VarType函数(varMid)= vbError然后
I = lngMax
J = lngMin
elseif的VarType函数(varMid)GT; 17以后
I = lngMax
J = lngMin
万一 虽然我< = j的 而SortArray(I)所述; varMid和I< lngMax
I = I + 1
WEND
虽然varMid< SortArray(J)和J> lngMin
当J = J - 1
WEND 如果我< = j的再
交换项目
VARx前提= SortArray(I)
SortArray(ⅰ)= SortArray(j)条
SortArray(J)= VARx前提 I = I + 1
当J = J - 1
万一 WEND 如果(lngMin< j)条然后调用QuickSortVector(SortArray,lngMin,J)
如果(I< lngMax)然后调用QuickSortVector(SortArray,我,lngMax)结束小组
公用Sub冒泡(为ByRef InputArray,可选SortColumn为整数= 0,可选降序由于布尔= FALSE)
排序1或2维数组。
昏暗iFirstRow作为整数
昏暗iLastRow作为整数
昏暗iFirstCol作为整数
昏暗iLastCol作为整数
昏暗我作为整数
昏暗Ĵ作为整数
昏暗的K作为整数
昏暗varTemp为Variant
昏暗OutputArray为Variant昏暗iDimensions作为整数iDimensions = ArrayDimensions(InputArray) 选择案例iDimensions
情况1 iFirstRow = LBOUND(InputArray)
iLastRow = UBound函数(InputArray) 对于i = iFirstRow要iLastRow - 1
对于J = + 1 iLastRow
如果InputArray(一)> InputArray(J)然后
varTemp = InputArray(J)
InputArray(J)= InputArray㈠
InputArray(ⅰ)= varTemp
万一
下面j
接下来,我 案例2 iFirstRow = LBOUND(InputArray,1)
iLastRow = UBound函数(InputArray,1) iFirstCol = LBOUND(InputArray,2)
iLastCol = UBound函数(InputArray,2) 如果SortColumn InputArray(J,SortColumn)然后
对于k = iFirstCol要iLastCol
varTemp = InputArray(J,K)
InputArray(J,K)= InputArray(I,K)
InputArray(I,K)= varTemp
下面k
万一
下面j
接下来,我 结束选择
如果遂降 OutputArray = InputArray 对于i = LBOUND(InputArray,1)UBound函数(InputArray,1) K = 1 + UBound函数(InputArray,1) - 我
对于j = LBOUND(InputArray,2)向UBound函数(InputArray,2)
InputArray(I,J)= OutputArray(K,J)
下面j
接下来,我 擦除OutputArray 万一
结束小组
这答案可能已经到达有点晚了,当你需要解决你的问题,但其他人将它捡起来,他们在谷歌针对类似的问题的答案。
Empty values and invalid items are sent to the end of the list.
QuickSort MyArray,,,2...Passing '2' as the column to sort on and excluding the optional parameters that pass the upper and lower bounds of the search domain.
[EDITED] - fixed an odd formatting glitch in the <code> tags, which seem to have a problem with hyperlinks in code comments.
The Hyperlink I excised was Detecting an Array Variant in VBA.
Public Sub QuickSortArray(ByRef SortArray As Variant, Optional lngMin As Long = -1, Optional lngMax As Long = -1, Optional lngColumn As Long = 0)
On Error Resume Next
'Sort a 2-Dimensional array
' SampleUsage: sort arrData by the contents of column 3
'
' QuickSortArray arrData, , , 3
'
'Posted by Jim Rech 10/20/98 Excel.Programming
'Modifications, Nigel Heffernan:
' ' Escape failed comparison with empty variant
' ' Defensive coding: check inputs
Dim i As Long
Dim j As Long
Dim varMid As Variant
Dim arrRowTemp As Variant
Dim lngColTemp As Long
If IsEmpty(SortArray) Then
Exit Sub
End If
If InStr(TypeName(SortArray), "()") < 1 Then 'IsArray() is somewhat broken: Look for brackets in the type name
Exit Sub
End If
If lngMin = -1 Then
lngMin = LBound(SortArray, 1)
End If
If lngMax = -1 Then
lngMax = UBound(SortArray, 1)
End If
If lngMin >= lngMax Then ' no sorting required
Exit Sub
End If
i = lngMin
j = lngMax
varMid = Empty
varMid = SortArray((lngMin + lngMax) \ 2, lngColumn)
' We send 'Empty' and invalid data items to the end of the list:
If IsObject(varMid) Then ' note that we don't check isObject(SortArray(n)) - varMid *might* pick up a valid default member or property
i = lngMax
j = lngMin
ElseIf IsEmpty(varMid) Then
i = lngMax
j = lngMin
ElseIf IsNull(varMid) Then
i = lngMax
j = lngMin
ElseIf varMid = "" Then
i = lngMax
j = lngMin
ElseIf VarType(varMid) = vbError Then
i = lngMax
j = lngMin
ElseIf VarType(varMid) > 17 Then
i = lngMax
j = lngMin
End If
While i <= j
While SortArray(i, lngColumn) < varMid And i < lngMax
i = i + 1
Wend
While varMid < SortArray(j, lngColumn) And j > lngMin
j = j - 1
Wend
If i <= j Then
' Swap the rows
ReDim arrRowTemp(LBound(SortArray, 2) To UBound(SortArray, 2))
For lngColTemp = LBound(SortArray, 2) To UBound(SortArray, 2)
arrRowTemp(lngColTemp) = SortArray(i, lngColTemp)
SortArray(i, lngColTemp) = SortArray(j, lngColTemp)
SortArray(j, lngColTemp) = arrRowTemp(lngColTemp)
Next lngColTemp
Erase arrRowTemp
i = i + 1
j = j - 1
End If
Wend
If (lngMin < j) Then Call QuickSortArray(SortArray, lngMin, j, lngColumn)
If (i < lngMax) Then Call QuickSortArray(SortArray, i, lngMax, lngColumn)
End Sub
... And the single-column array version:
Public Sub QuickSortVector(ByRef SortArray As Variant, Optional lngMin As Long = -1, Optional lngMax As Long = -1)
On Error Resume Next
'Sort a 1-Dimensional array
' SampleUsage: sort arrData
'
' QuickSortVector arrData
'
' Originally posted by Jim Rech 10/20/98 Excel.Programming
' Modifications, Nigel Heffernan:
' ' Escape failed comparison with an empty variant in the array
' ' Defensive coding: check inputs
Dim i As Long
Dim j As Long
Dim varMid As Variant
Dim varX As Variant
If IsEmpty(SortArray) Then
Exit Sub
End If
If InStr(TypeName(SortArray), "()") < 1 Then 'IsArray() is somewhat broken: Look for brackets in the type name
Exit Sub
End If
If lngMin = -1 Then
lngMin = LBound(SortArray)
End If
If lngMax = -1 Then
lngMax = UBound(SortArray)
End If
If lngMin >= lngMax Then ' no sorting required
Exit Sub
End If
i = lngMin
j = lngMax
varMid = Empty
varMid = SortArray((lngMin + lngMax) \ 2)
' We send 'Empty' and invalid data items to the end of the list:
If IsObject(varMid) Then ' note that we don't check isObject(SortArray(n)) - varMid *might* pick up a default member or property
i = lngMax
j = lngMin
ElseIf IsEmpty(varMid) Then
i = lngMax
j = lngMin
ElseIf IsNull(varMid) Then
i = lngMax
j = lngMin
ElseIf varMid = "" Then
i = lngMax
j = lngMin
ElseIf VarType(varMid) = vbError Then
i = lngMax
j = lngMin
ElseIf VarType(varMid) > 17 Then
i = lngMax
j = lngMin
End If
While i <= j
While SortArray(i) < varMid And i < lngMax
i = i + 1
Wend
While varMid < SortArray(j) And j > lngMin
j = j - 1
Wend
If i <= j Then
' Swap the item
varX = SortArray(i)
SortArray(i) = SortArray(j)
SortArray(j) = varX
i = i + 1
j = j - 1
End If
Wend
If (lngMin < j) Then Call QuickSortVector(SortArray, lngMin, j)
If (i < lngMax) Then Call QuickSortVector(SortArray, i, lngMax)
End Sub
I used to use BubbleSort for this kind of thing, but it slows down, severely, after the array exceeds 1024 rows. I include the code below for your reference: please note that I haven't provided source code for ArrayDimensions, so this will not compile for you unless you refactor it - or split it out into 'Array' and 'vector' versions.
Public Sub BubbleSort(ByRef InputArray, Optional SortColumn As Integer = 0, Optional Descending As Boolean = False) ' Sort a 1- or 2-Dimensional array. Dim iFirstRow As Integer Dim iLastRow As Integer Dim iFirstCol As Integer Dim iLastCol As Integer Dim i As Integer Dim j As Integer Dim k As Integer Dim varTemp As Variant Dim OutputArray As Variant Dim iDimensions As Integer iDimensions = ArrayDimensions(InputArray) Select Case iDimensions Case 1 iFirstRow = LBound(InputArray) iLastRow = UBound(InputArray) For i = iFirstRow To iLastRow - 1 For j = i + 1 To iLastRow If InputArray(i) > InputArray(j) Then varTemp = InputArray(j) InputArray(j) = InputArray(i) InputArray(i) = varTemp End If Next j Next i Case 2 iFirstRow = LBound(InputArray, 1) iLastRow = UBound(InputArray, 1) iFirstCol = LBound(InputArray, 2) iLastCol = UBound(InputArray, 2) If SortColumn InputArray(j, SortColumn) Then For k = iFirstCol To iLastCol varTemp = InputArray(j, k) InputArray(j, k) = InputArray(i, k) InputArray(i, k) = varTemp Next k End If Next j Next i End Select If Descending Then OutputArray = InputArray For i = LBound(InputArray, 1) To UBound(InputArray, 1) k = 1 + UBound(InputArray, 1) - i For j = LBound(InputArray, 2) To UBound(InputArray, 2) InputArray(i, j) = OutputArray(k, j) Next j Next i Erase OutputArray End If End Sub
This answer may have arrived a bit late to solve your problem when you needed to, but other people will pick it up when they Google for answers for similar problems.
这篇关于排序在VBA中multidimensionnal阵列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!