Excel VBA 将 Sheet 中的每一列复制到右侧的下一列

Excel VBA to Copy Every Column in a Sheet to the Next Column to the Right

我需要完成一些非常简单的事情:将一个完整的专栏复制到同一作品右侧的下一专栏sheet(我在一个 sheet 的一个 sheet 中有大约 300 个这样的专栏工作簿)意味着宏必须将范围内的每个奇数列复制到下一个偶数列,以便我最终得到一个充满重复列的范围。我知道我需要部分或全部使用以下公式:

cells(selection.row, columns.Count).end(xltoleft).offset(,1).select

完整的宏是什么?搜索每个可用的板,只找到具有自定义条件的解决方案。我的应该很简单。感谢您的意见。

尝试(可能需要一些错误处理)。我没有复制整列,而是使用 A 列来确定 sheet 中的最后一行数据(您可以更改它),然后循环偶数列,将它们设置为等于先前的奇数列。

Option Explicit

Sub test()

    Dim loopRange As Range

    Set loopRange = ThisWorkbook.ActiveSheet.Columns("A:AE")

    Dim lastRow As Long

    With ThisWorkbook.ActiveSheet

        lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row

    End With

    Dim currentColumn As Long

    With loopRange

        For currentColumn = 2 To .Columns.Count Step 2

            .Range(.Cells(1, currentColumn), .Cells(lastRow, currentColumn)) = .Range(.Cells(1, currentColumn - 1), .Cells(lastRow, currentColumn - 1)).Value

        Next currentColumn

    End With

End Sub

如果你知道最后一行:

 Option Explicit

    Sub test()

        Dim loopRange As Range

        Set loopRange = ThisWorkbook.ActiveSheet.Columns("A:AE")

        Const lastRow As Long = 108

        Dim currentColumn As Long

        With loopRange

            For currentColumn = 2 To .Columns.Count Step 2

                .Range(.Cells(1, currentColumn), .Cells(lastRow, currentColumn)) = .Range(.Cells(1, currentColumn - 1), .Cells(lastRow, currentColumn - 1)).Value

            Next currentColumn

        End With

    End Sub

我不完全确定我理解了这个问题,但请在下面找到建议。代码可能有点乱,因为我用的是录制的宏:

Sub CopyRows()

Range("A1").Activate

While Not IsEmpty(ActiveCell)
    ActiveCell.Columns("A:A").EntireColumn.Select
    Selection.Copy
    ActiveCell.Offset(0, 1).Columns("A:A").EntireColumn.Select
    Selection.Insert Shift:=xlToRight
    ActiveCell.Offset(0, 1).Range("A1").Select
Wend

End Sub

如果您希望通过在右侧插入每一列的副本来基本上复制每一列,我认为您需要以下代码。

即这会复制列:

A | B | C 
---------
A | B | C 
1 | 2 | 3 

A | B | C | D | E | F
---------------------
A | A | B | B | C | C
1 | 1 | 2 | 2 | 3 | 3

VBA

Option Explicit

Sub CopyAllColsOneToRight()

    Dim ws As Worksheet
    Dim lastCol As Long
    Dim lastRow As Long
    Dim currentCopyCol As Long

    Application.ScreenUpdating = False 'optimise performance by not updating the screen as we move stuff
    Set ws = ActiveSheet
    lastCol = GetLastUsedColumn(ws).Column
    lastRow = GetLastUsedRow(ws).Row

    For currentCopyCol = lastCol To 1 Step -1
        CopyColumnInsertRight ws, lastRow, currentCopyCol
        'CopyColumn ws, lastRow, currentCopyCol, lastRow, currentCopyCol * 2
        'CopyColumn ws, lastRow, currentCopyCol, lastRow, currentCopyCol * 2 - 1
    Next

End Sub

Sub CopyColumnInsertRight(ByRef ws As Worksheet, fromLastRow, fromCol)
    Dim fromRange As Range
    Set fromRange = ws.Range(ws.Cells(1, fromCol), ws.Cells(fromLastRow, fromCol))
    fromRange.Copy
    fromRange.Insert Shift:=XlDirection.xlToRight
End Sub

'Sub CopyColumn(ByRef ws As Worksheet, fromLastRow, fromCol, toLastRow, toCol)
'   Dim fromRange As Range
'   Dim toRange As Range
'   Set fromRange = ws.Range(ws.Cells(1, fromCol), ws.Cells(fromLastRow, fromCol))
'   Set toRange = ws.Range(ws.Cells(1, toCol), ws.Cells(toLastRow, toCol))
'   toRange.Value2 = fromRange.Value2
'End Sub

Function GetLastUsedColumn(ByRef ws As Worksheet) As Range
    Set GetLastUsedColumn = ws.Cells.Find( _
        What:="*" _
        , After:=ws.Cells(1, 1) _
        , LookIn:=XlFindLookIn.xlFormulas _
        , LookAt:=XlLookAt.xlPart _
        , SearchOrder:=XlSearchOrder.xlByColumns _
        , SearchDirection:=XlSearchDirection.xlPrevious _
        , MatchCase:=False _
    )
End Function

Function GetLastUsedRow(ByRef ws As Worksheet) As Range
    Set GetLastUsedRow = ws.Cells.Find( _
        What:="*" _
        , After:=ws.Cells(1, 1) _
        , LookIn:=XlFindLookIn.xlFormulas _
        , LookAt:=XlLookAt.xlPart _
        , SearchOrder:=XlSearchOrder.xlByRows _
        , SearchDirection:=XlSearchDirection.xlPrevious _
        , MatchCase:=False _
    )
End Function

代码注释:

  • 我们禁用屏幕更新;这避免了在宏运行时刷新 UI,从而使过程更有效率。
  • 我们得到了最后填充的列,这样我们就可以将复制的列限制为产生差异的列(即使用少于全部列数的电子表格更快;这将大多数情况下都是如此)
  • 我们得到了最后填充的行,这样我们就不会复制整个列,而是只复制填充的行。我们可以检查每行最后使用的单元格,但这可能效率较低,因为通常最后一行对于范围内的大多数列都是相同的。此外,在使用插入方法时,需要确保 xlToRight 不会导致单元格移入错误的列。
  • 我们的 for 循环有 Step -1,因为如果我们从左到右,我们会在复制其他列时覆盖右侧的列(例如,将 A 复制到 B 会覆盖 B 中的内容,然后当我们复制 B 时到 C 我们实际上是在复制副本)。相反,我们向后工作,以便我们始终复制到空白列或我们之前复制的列。
  • 我提供了一个仅复制值(比复制格式更快)的注释掉的版本,以及另一个使用 Insert 创建新列的版本。一个可能比另一个表现更好,但到目前为止我还没有测试过(注意:副本必须复制两倍的单元格,因为它不保留原件但创建 2 个副本,而插入方法保留原件并插入右侧的副本,但有复制格式化数据的额外开销)。