Reputation: 11
I am trying to do some array math in Excel which requires me to reverse a number of 1-dimensional ranges a good amount of times, so I want to write a function for it, rather than create reverses in the spreadsheet.
I have written a reverse() function in VBA but it returns #VALUE! errors in the spreadsheet. This happens no matter array size, nor whether inputting a same size array function or enclosing with a summary function like SUM(). I verified that the reversing logic works as a Sub. This leads me to believe the issue is with passing/returning the range/array but I don't understand what is wrong.
Function reverse(x As Range) As Variant()
' Array formula that reverses a one-dimensional array (1 row, x columns)
Dim oldArray() As Variant, newArray() As Variant
Dim rows As Long: i = x.rows.Count
Dim cols As Long: i = x.Columns.Count
ReDim oldArray(1 To rows, 1 To cols), newArray(1 To rows, 1 To cols)
oldArray = x.Value
newArray = oldArray
For i = 1 To cols / 2 Step 1
newArray(1, i) = oldArray(1, cols - i + 1)
newArray(1, cols - i + 1) = oldArray(1, i)
Next
reverse = newArray
End Function
Keep in mind, I may extend it to reverse 2 dimensional arrays, but that's the trivial part. My question is just trying to ensure the function works on a (1, N) range.
Thanks!
Upvotes: 1
Views: 2790
Reputation: 3188
The following code is more versatile, it use optional arguments to determine if rows, columns or both (or none) should be reversed. By default it will reverse columns.
Function ReverseRange(Source As Range, Optional ReverseRows As Boolean = False, Optional ReverseColumns As Boolean = True) As Variant()
Dim SourceArray() As Variant
Dim DestArray() As Variant
SourceArray = Source.value
Dim nRows As Long, nColumns As Long
nRows = UBound(SourceArray, 1)
nColumns = UBound(SourceArray, 2)
ReDim DestArray(1 To nRows, 1 To nColumns)
Dim r As Long, r2 As Long, c As Long, c2 As Long
For r = 1 To nRows
r2 = IIf(ReverseRows, nRows - r + 1, r)
For c = 1 To nColumns
c2 = IIf(ReverseColumns, nColumns - c + 1, c)
DestArray(r2, c2) = SourceArray(r, c)
Next c
Next r
ReverseRange = DestArray
End Function
Note that there is no verification on the range validity.
Upvotes: 1
Reputation:
This will reverse the columns in the range no matter the row count.
Function reverse(Source As Range) As Variant()
Dim Data, RevData
Dim x As Long, y As Long, y1 As Long
Data = Source.Value
ReDim RevData(1 to UBound(Data, 1),1 to UBound(Data, 2))
For x = 1 To UBound(Data, 1)
y1 = UBound(Data, 2)
For y = 1 To UBound(Data, 2)
RevData(x, y1) = Data(x, y)
y1 = y1 - 1
Next
Next
reverse = RevData
End Function
Upvotes: 0
Reputation: 1132
Find below code....
Function reverse(x As Range) As Variant()
' Array formula that reverses a one-dimensional array (1 row, x columns)
Dim oldArray() As Variant, newArray() As Variant
Dim rows As Long
rows = x.rows.Count
Dim cols As Long
cols = x.Columns.Count
ReDim oldArray(1 To rows, 1 To cols), newArray(1 To rows, 1 To cols)
oldArray = x.Value
newArray = oldArray
For i = 1 To cols / 2 Step 1
newArray(1, i) = oldArray(1, cols - i + 1)
newArray(1, cols - i + 1) = oldArray(1, i)
Next
reverse = newArray
End Function
Upvotes: 2