Reputation: 27
I have to reverse the rows of a range. The code I have written reverts a range of 1000 rows x 1000 columns in 2 min, 18 s, 587 ms. Can someone provide a faster code?
Average time 1000 rows x 1000 columns : 2 min, 18 s, 587 ms
(Intel i7-6700 4 GHz, 32 GB RAM) (Windows 10 Home x64) (Excel Office 365 MSO(16.0.11328.20144) 32 bits)
I do not need to turn calculation off, cells do not have formulas. GMalc code is short and very fast: 8s, 23 ms but @Rory suggestion is faster as Ron said: 1s, 195 ms !!! Thanks
Sub InvertRangeRows(ByRef rngRange_IO As Range)
Dim RowI&, RowRange&, RowArray&, RowFirst As Long
Dim RowLast&, ColumnFirst&, ColumnLast As Long
Dim ArrayRange As Variant, ArrayInverted As Variant
Dim RowCurrent As Variant
Application.ScreenUpdating = False
ArrayRange = rngRange_IO
ReDim ArrayInverted(1 To UBound(ArrayRange))
For RowI = UBound(ArrayRange) To LBound(ArrayRange) Step -1
RowCurrent = Application.WorksheetFunction.Index(ArrayRange, RowI, 0)
RowRange = RowRange + 1
ArrayInverted(RowRange) = RowCurrent
Next RowI
With rngRange_IO
RowFirst = .Row
RowLast = RowFirst + UBound(ArrayRange) - 1
ColumnFirst = .Column
ColumnLast = ColumnFirst + UBound(ArrayRange, 2) - 1
End With
With rngRange_IO.Worksheet
For RowI = RowFirst To RowLast
RowArray = RowArray + 1
.Range(.Cells(RowI, ColumnFirst), .Cells(RowI, ColumnLast)) _
= ArrayInverted(RowArray)
Next RowI
End With
Application.ScreenUpdating = False
End Sub
Upvotes: 1
Views: 398
Reputation: 27
I share the code according to the suggestion of @Rory and Ron Rosenfeld. I have included turn calculation off so that it allows to include formulas. This is the fastest code: 1.2 s vs 2'18.6" of my first code !!! Thank you
Sub InvertRangeRows(ByRef rngRange_IO As Range)
Dim RowI&, RowCurrent&, ColumnI As Long
Dim ArrayRange As Variant, ArrayInverted As Variant
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
ArrayRange = rngRange_IO
ReDim ArrayInverted(1 To UBound(ArrayRange), 1 To UBound(ArrayRange, 2))
For RowI = UBound(ArrayRange) To 1 Step -1
RowCurrent = RowCurrent + 1
For ColumnI = 1 To UBound(ArrayRange, 2)
ArrayInverted(RowCurrent, ColumnI) = ArrayRange(RowI, ColumnI)
Next ColumnI
Next RowI
rngRange_IO = ArrayInverted
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub
Upvotes: 0
Reputation: 2628
This code is not much faster (1k x 1k) in 1 min 28 sec, but is easier.
Dim ws As Worksheet, lRow As Long, i As Long
Set ws = ThisWorkbook.Worksheets("Sheet1")
lRow = ws.Cells(Rows.Count, 1).End(xlUp).Row
Application.Calculation = xlCalculationManual
For i = 2 To lRow
ws.Cells(i, 1).EntireRow.Cut
ws.Cells(1, 1).EntireRow.Insert Shift:=xlDown
Next i
Application.Calculation = xlCalculationAutomatic
Upvotes: 1