J'ai posté un peu de code en réponse à une question sur StackOverflow:
Tri d'une multidimensionnal tableau en VBA
Les exemples de code dans ce thread comprennent:
- Un tableau de vecteurs Quicksort;
- Un multi-colonne de la matrice de QuickSort;
- Un BubbleSort.
Alain optimisée de Quicksort est très brillant: j'ai juste fait une base de split-et-recurse, mais l'exemple de code ci-dessus a un "déclenchement" fonction qui coupe vers le bas sur redondante des comparaisons de valeurs dupliquées. D'autre part, j'ai le code pour Excel, et il y a un peu plus dans le sens de la défense de codage - être averti, vous en aurez besoin si votre tableau contient le pernicieuse " Empty()' variante, qui va briser votre While... Wend opérateurs de comparaison et de piéger votre code dans une boucle infinie.
Notez que quicksort algorthms - et tout algorithme récursif - peut remplir la pile et de crash Excel. Si votre matrice a moins de 1024 membres, j'aimerais utiliser un rudimentaire BubbleSort.
Public Sub QuickSortArray(ByRef SortArray Comme Variante, _
En option lngMin Tant = -1, _
En option lngMax Tant = -1, _
En option lngColumn Tant = 0)
On Error Resume Next
"Trier un tableau en 2 Dimensions
'SampleUsage: tri arrData par le contenu de la colonne 3
'
'QuickSortArray arrData, , , 3
'
'Posté par Jim Rech 10/20/98 Excel.Programmation
'Modifications, Nigel Heffernan:
'"Échapper échec de la comparaison avec vide variante
'La" défense de codage: vérifier l'état des entrées
Dim i as Long
Dim j as Long
Dim varMid Comme Variante
Dim arrRowTemp Comme Variante
Dim lngColTemp Tant
If IsEmpty(SortArray) Puis
Exit Sub
Fin De Si
Si InStr(TypeName(SortArray), "()") < 1 then 'IsArray() est un peu cassé: recherchez les parenthèses dans le nom du type
Exit Sub
Fin De Si
Si lngMin = -1, Alors
lngMin = LBound(SortArray, 1)
Fin De Si
Si lngMax = -1, Alors
lngMax = UBound(SortArray, 1)
Fin De Si
Si lngMin >= lngMax Puis " pas de tri nécessaire
Exit Sub
Fin De Si
i = lngMin
j = lngMax
varMid = Vide
varMid = SortArray((lngMin + lngMax) \ 2, lngColumn)
'Nous envoyer le "Vide", et des données non valides éléments à la fin de la liste:
Si IsObject(varMid) Puis ' noter que nous n'avons pas vérifier isObject(SortArray(n)) - varMid peut ramasser valides par défaut un membre ou une propriété
i = lngMax
j = lngMin
Sinon si Estvide(varMid) Puis
i = lngMax
j = lngMin
ElseIf IsNull(varMid) Puis
i = lngMax
j = lngMin
ElseIf varMid = "" Then
i = lngMax
j = lngMin
ElseIf varType(varMid) = vbError Alors
i = lngMax
j = lngMin
ElseIf varType(varMid) > 17
i = lngMax
j = lngMin
Fin De Si
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
Si (lngMin < j) Puis d'Appeler QuickSortArray(SortArray, lngMin, j, lngColumn)
Si (i < lngMax) Puis d'Appeler QuickSortArray(SortArray, j', lngMax, lngColumn)
End Sub