我尝试阅读您的代码,但不是很成功。很明显,您正在尝试从上到下循环:
For i = 1 To LastRow
If ws.Cells(i, lastCol) = "" Then
ws.Cells(i, ws.Cells(i, 1).End(xlToRight).Column).Cut
ws.Cells(i,lastCol)
End If
Next i
但是您没有对行进行足够深的评估以识别最后三个单元格,您实际上并没有移动任何数据,而且我认为您会在第一次迭代时抛出错误。
看起来您正在尝试以嵌套 For 循环的“简单”方式执行此操作,而您报告的缓慢几乎证实了这一点。嵌套 For 循环快速且易于编写,但如果您选择或更改数千个单元格,它们可能需要很长时间才能运行。您可以通过最小化您激活/更改的单元格数量以及关闭屏幕更新来提高速度。
如果粘贴到新模块中,下面的代码应该可以工作。我尝试遵循与您的示例相同的逻辑,但有所偏差。
Sub move_data()
Dim LastRow As Long, LastCol As Long, LastCell As Long
Dim ws As Worksheet
Dim ColLimit as Integer
Dim i As Integer, j As Integer
Application.ScreenUpdating = False
Set ws = ActiveSheet
ColLimit = 2 ' [0 through 2] = 3, # of columns to populate
LastRow = ws.UsedRange.Rows.Count
LastCol = ws.UsedRange.Columns.Count
Cells.EntireColumn.AutoFit
For i = 1 To LastRow
LastCell = LastCol
For j = 0 To ColLimit
LastCell = ws.Cells(i, LastCol - j).End(xlToLeft).Column
If LastCell > 0 And ws.Cells(i, LastCol - j) = "" Then
LastCell = ws.Cells(i, LastCol - j).End(xlToLeft).Column
ws.Cells(i, LastCell).Copy ws.Cells(i, LastCol - j)
ws.Cells(i, LastCell) = ""
End If
Next j
Next i
Application.ScreenUpdating = True
End Sub
`
如果速度是一个问题,那么您应该远离这些循环并使用
数组和范围。它们的速度明显更快。
对于咯咯笑,这是可以在大约 30 秒内手动完成的方法,并且可能还有一种我还没有见过的更简单的方法!
Highlight the data range
Ribbon, Data tab, From Table/Range (opens query editor)
Ribbon, Transform tab, Transpose
Ribbon, Transform tab, Reverse Rows
File, Close and load, to worksheet
Highlight the data range
Ribbon, Design, Convert to Range
Goto Blanks (Ctrl G - Special - Blanks)
Delete blanks - Move Cells up (Alt E, D)
现在,顶行包含列中的所有值。如果您希望它们在列中但不关心列是否反转,您可以复制和粘贴特殊转换。
但如果你想要那些完全相同的列:
Highlight the data range
Ribbon, Data tab, From Table/Range (opens query editor)
Ribbon, Transform tab, Reverse Rows
Ribbon, Transform tab, Transpose
File, Close and load, to worksheet
现在您的列在右侧。当然 Power Query 可以用 VBA 编码,但我还没有解决这个问题。