Excel VBA: 如何在同一列中交换两个选定的单元格范围(不仅是两个值)?

Excel VBA: How to swap two selected cell ranges (not only two values) within the same column?

我想在同一列中交换选定的单元格范围,而无需自动调整其他列中的附加公式。这些单元格范围几乎总是大小不等。

我找到了一个 VBA 代码,它对两个选定的单元格执行此操作,但恐怕这对我没有太大帮助。

Sub SwapCells()
    Dim sHolder As String

    If Selection.Cells.Count = 2 Then
        With Selection
            sHolder = .Cells(1).Formula
            If .Areas.Count = 2 Then  ' Cells selected using Ctrl key
                .Areas(1).Formula = .Areas(2).Formula
                .Areas(2).Formula = sHolder
            Else                      ' Adjacent cells are selected
                .Cells(1).Formula = .Cells(2).Formula
                .Cells(2).Formula = sHolder
            End If
        End With
    Else
        MsgBox "Select only TWO cells to swap", vbCritical
    End If
End Sub

我知道另一种选择是在移动单元格范围时保持 'shift'(效果非常好),但是所有附加的公式都会更改我不想要的引用(例如,如果我有引用单元格 A1 的公式,我在某处交换 A1,公式将引用 A1 的新位置,但我希望公式仍引用 A1)。

我认为另一种选择是使用 INDIRECT("G" & ROW()) 来修复它,但由于它是一个相当耗费资源的公式,我希望看到一个替代方案。

最重要的是,后两个选项不允许我使用表格(出于其他原因我更喜欢表格),因为您不能交换表格中的单元格。这就是为什么我非常喜欢 VBA 选项。

希望大家能帮帮我,谢谢!也许只需要稍微调整VBA代码即可。

亲切的问候, 马可

编辑:如果交换两个相等的单元格范围(例如,每个包含 5 个单元格)要容易得多,那么这也是一个很好的解决方案。

Sub SwapTwoSelectedRanges()

    Dim initialRng As Range
    Set initialRng = Selection

    If initialRng.Areas.Count <> 2 Then
        Debug.Print "Select 2 areas!"
        Exit Sub
    End If

    If initialRng.Areas(1).Cells.Count <> initialRng.Areas(2).Cells.Count Then
        Debug.Print "The cells should be the same number!"
        Exit Sub
    End If

    Dim intermediateRng As Variant
    intermediateRng = initialRng.Areas(1).Cells.Value2

    initialRng.Areas(1).Cells.Value2 = initialRng.Areas(2).Cells.Value2
    initialRng.Areas(2).Cells.Value2 = intermediateRng

End Sub

如果您使用的是中间值,则交换两个值被认为是一项简单的任务。对于范围,在交换它们之前需要执行两个重要的检查:

  1. 选中的区域是否正好是2个;
  2. 每个区域的单元格数是否相等;
  3. 然后用一个intermediateRng作为3.变量,进行交换;
  4. 这仅在区域按列排列时才有效。如果按行进行选择,则结果不会像预期的那样;

关于颜色的交换,如果每个区域的所有单元格的颜色完全相同,这将可行:

Dim intermediateRng As Variant
Dim intermediateClr As Variant

intermediateRng = initialRng.Areas(1).Cells.Value2
intermediateClr = initialRng.Areas(1).Cells.Interior.Color

With initialRng
    .Areas(1).Cells.Value2 = .Areas(2).Cells.Value2
    .Areas(1).Cells.Interior.Color = .Areas(2).Cells.Interior.Color

    .Areas(2).Cells.Value2 = intermediateRng
    .Areas(2).Cells.Interior.Color = intermediateClr
End With

但是,如果每个区域的单元格颜色不同,那么最简单的方法是将第一个范围复制+粘贴到一个单独的范围,然后从那里开始工作。