【问题标题】:Reverse rows of a range反转范围的行
【发布时间】:2023-03-30 17:53:01
【问题描述】:

我必须反转范围的行。我编写的代码在 2 分钟、18 秒、587 毫秒内恢复了 1000 行 x 1000 列的范围。有人可以提供更快的代码吗?

1000 行 x 1000 列的平均时间:2 分钟、18 秒、587 毫秒

(Intel i7-6700 4 GHz,32 GB RAM)(Windows 10 Home x64)(Excel Office 365 MSO(16.0.11328.20144) 32 位)

我不需要关闭计算,单元格没有公式。 GMalc 代码很短而且非常快:8 秒,23 毫秒,但@Rory 建议更快,正如罗恩所说:1 秒,195 毫秒!!!谢谢

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

【问题讨论】:

  • 你关闭计算了吗?
  • 我怀疑使用 2D 数组会更快,在内存中循环处理行和列,然后一键将其写回工作表。
  • 我打算和@Rory 一样建议你可以说a()=range("a1:aa1000") 然后在一个新数组aReveresed 中做你需要做的事情,然后range("a1:aa1000")=aReversed 新数组的所有维度都可以也可以从范围的列/行或第一个数组中获取。
  • 该范围内有任何公式吗?
  • 假设数组的内容不包括公式,@Rory 在我的机器上的建议 - 我认为比你的慢(I7-3770K) - 粗略计算大约需要两秒钟。

标签: excel vba


【解决方案1】:

我根据@Rory 和 Ron Rosenfeld 的建议分享代码。我已经包括关闭计算,以便它允许包括公式。这是最快的代码:我的第一个代码的 1.2 s vs 2'18.6" !!! 谢谢

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

【讨论】:

    【解决方案2】:

    这段代码在 1 分 28 秒内并没有快多少 (1k x 1k),但更简单。

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-04
      • 1970-01-01
      • 1970-01-01
      • 2016-04-18
      • 2016-05-17
      • 1970-01-01
      • 1970-01-01
      • 2016-09-13
      相关资源
      最近更新 更多