Hi,
I have an Array which has 3 columns:
Data1 2 23
Data2 5 11
Data3 1 15
Data4 1 17
I have declared the Array as MyArray ( 0 to 500, 0 to 2)
I want to sort the Array by the 3rd column in descending order.
Ho do I do this?
Thanks
Hi,
I have an Array which has 3 columns:
Data1 2 23
Data2 5 11
Data3 1 15
Data4 1 17
I have declared the Array as MyArray ( 0 to 500, 0 to 2)
I want to sort the Array by the 3rd column in descending order.
Ho do I do this?
Thanks
One tricky way to achieve this is, insert a new sheet and write your array onto it and sort the third column and rewrite the sorted values back into array and delete the sheet you inserted like below...
Dim ws As Worksheet Dim x Sheets.Add Set ws = ActiveSheet ws.Range("A1").Resize(UBound(myarr, 1) + 1, UBound(myarr, 2) + 1).Value = myarr ws.Range("A1").CurrentRegion.Sort key1:=Range("C1"), order1:=xlDescending, Header:=xlNo x = ws.Range("A1").CurrentRegion.Value For i = 1 To UBound(x, 1) For j = 1 To UBound(x, 2) myarr(i - 1, j - 1) = x(i, j) Next j Next i Application.DisplayAlerts = False ws.Delete Application.DisplayAlerts = True
Regards
sktneer
Treat people the way you want to be treated. Talk to people the way you want to be talked to.
Respect is earned NOT given.
One way to do this would be to create a one dimensional indexing array and sort that array on the custom LT function.
The indexing array is an array of row numbers and LT returns whether the third column of the indicated row is less than the other.Function LT(a As Long, b As Long) As Boolean LT = (MyArray(a, 3) < MyArray(b, 3)) End Function
The full routine would look like this.
This uses a bubble sort algorithm and for small data sets sktneer's use of Excel's built in sort is faster, but for larger data sets the indexing array approach is faster if one uses a quick sort rather than a bubble sort.Dim myArray As Variant Sub SortMyArray() Dim IndexArray() As Long Dim SortedArray() As Variant Dim i As Long, j As Long, temp As Long Dim SortDescending As Boolean Rem Get myArray (for testing purposes) ReDim myArray(0 To 500, 0 To 2) For i = LBound(myArray) To UBound(myArray) myArray(i, 2) = Rnd() Next i Rem creste indexing array ReDim IndexArray(LBound(myArray, 1) To UBound(myArray, 1)) For i = LBound(IndexArray) To UBound(IndexArray) IndexArray(i) = i Next i Rem sort index array ' this uses a bubble sort, other sorting algorithms could be used SortDescending = True For i = LBound(IndexArray) To UBound(IndexArray) - 1 For j = i + 1 To UBound(IndexArray) If LT(IndexArray(i), IndexArray(j)) Xor SortDescending Then Rem swap indicies temp = IndexArray(i) IndexArray(i) = IndexArray(j) IndexArray(j) = temp End If Next j Next i Rem index array is now sorted ' myArray(IndexArray(1), 2) > myArray(IndexArray(2), 2) > myArray(IndexArray(3), 2) > ..... Rem build sorted array ReDim SortedArray(LBound(myArray, 1) To UBound(myArray, 1), LBound(myArray, 2) To UBound(myArray, 2)) For i = LBound(myArray, 1) To UBound(myArray, 1) For j = LBound(myArray, 2) To UBound(myArray, 2) SortedArray(i, j) = myArray(IndexArray(i), j) Next j Next i End Sub Function LT(a As Long, b As Long) As Boolean LT = (myArray(a, 2) < myArray(b, 2)) End Function
I've generalized this routine quite a bit. The array does not need to be 0-based and the SortDescending variable could be used to sort ascending.
Last edited by mikerickson; 11-06-2016 at 02:09 PM.
_
...How to Cross-post politely...
..Wrap code by selecting the code and clicking the # or read this. Thank you.
Below is some code for a quicker sort than the bubble sort if you can put your data into a userdefined type such as struct_State below. Basic sort code is copied from a posting on the internet and adapted for userdefined types..I'm not good enough to write the code from scratch.
Sub Sort_StateAbbv(st() As struct_State) 'sorts state array of type struct_State by the abbreviation where: 'Type struct_State ' Abv As String ' Name As String 'End Type 'Can be adaped to sort by name by changing the .ABV's in the routine to .Name Dim varPivot As Variant, varTmp As struct_State Dim tmpLow As Integer, tmpHi As Integer, hi As Integer, lo As Integer lo = LBound(str): hi = UBound(str) tmpLow = lo: tmpHi = hi tmpLow = lo: tmpHi = hi varPivot = st((lo + hi) \ 2).Abv Do While tmpLow <= tmpHi Do While st(tmpLow).Abv < varPivot And tmpLow < hi tmpLow = tmpLow + 1 Loop Do While varPivot < st(tmpHi).Abv And tmpHi > lo tmpHi = tmpHi - 1 Loop If tmpLow <= tmpHi Then varTmp = st(tmpLow) st(tmpLow) = st(tmpHi) st(tmpHi) = varTmp tmpLow = tmpLow + 1 tmpHi = tmpHi - 1 End If Loop If lo < tmpHi Then Sort_StateAbbv st, lo, tmpHi If tmpLow < hi Then Sort_StateAbbv st, tmpLow, hi End Sub
There are currently 1 users browsing this thread. (0 members and 1 guests)
Bookmarks