如何比较两个多区域范围

How to compare two multi-area ranges

我有两个范围类型的变量,比如 r1 和 r2。我如何检查它们是否在同一范围内?如果它是单个单元格或单个连续的单元格区域,这很容易(我们可以假设它们在同一张纸上):

If r1.Address = r2.Address Then

但是如果它们是多区域范围 (r1.Areas.Count > 0) 怎么办?在大多数情况下,上述代码行仍然有效,但区域地址在 r1 和 r2 地址中出现的顺序可能不同。例如,在某些情况下您将遇到以下情况:

Debug.Print r1.Address
Debug.Print r2.Address

可以导致

"$A,$B"
"$B,$A"

它们显然是相同的范围,但上面 IF 语句中的条件将计算为 false。

理想情况下,我想说 IF r1 = r2 Then,但这行不通。也许我可以试试 Union...

编辑:

我也试过了

If r1 Is r2 Then

但这也不管用。

考虑一个简单的双循环:

Sub SameCheck(R1 As Range, R2 As Range)
Dim r As Range

For Each r In R1
    If Intersect(r, R2) Is Nothing Then
        MsgBox "not the same"
        Exit Sub
    End If
Next r

For Each r In R2
    If Intersect(r, R1) Is Nothing Then
        MsgBox "not the same"
        Exit Sub
    End If
Next r

MsgBox "the same"
End Sub

测试如下:

Sub MAIN()
    Call SameCheck(Range("A1:Z100"), Range("B9"))
    Call SameCheck(Range("A1:C3"), Range("A1:C3"))
End Sub

我在 SO 的其他地方遇到了一个很好的解决方案:

If (Intersect(r1,r2).Cells.Count = r1.Cells.Count) AND Intersect(r1,r2).Cells.Count = r2.Cells.Count Then

这是可行的,因为如果两个范围不完全相同,那么两个范围的交集的单元格将始终少于其中至少一个单元格。

编辑

根据下面 Rusan 的评论,很明显,在某些情况下,即使 r1 和 r2 是 "same",上述条件也会计算为 False。我使用引号是因为它需要被定义,我说它们是 "same" 范围的意思:如果你在 r1 的外边缘周围画一个边界,在 r2 的外边缘周围画一个边界,那么边界必须是沿着完全相同的路径。

正如 Rusan 指出的那样,如果 r1 和 r2 中的一个或两个具有重叠的单元格,则会出现问题。因此我们需要先"de-overlap"他们:

Public Function GetNonOverlappedRange(r As Range) As Range

Dim cell As Range, area As Range, newRange As Range

For Each area In r.Areas
    For Each cell In area
        If newRange Is Nothing Then
            Set newRange = cell
        Else
            If Intersect(cell, newRange) Is Nothing Then
                Set newRange = Union(newRange, cell)
            End If
        End If
    Next
Next

Set GetNonOverlappedRange = newRange

End Function

然后

Set r3 = GetNonOverlappedRange(r1)
Set r4 = GetNonOverlappedRange(r2)

If (Intersect(r3,r4).Cells.Count = r3.Cells.Count) AND Intersect(r3,r4).Cells.Count = r4.Cells.Count Then
    'If this is true then r1 and r2 are the "same" range

我应该指出,Gary 的学生在下面的回答提供了我问题的正确答案,我会将其标记为正确答案,但我认为构建上面的 "de-overlapping" 函数还是很有用的,因为我可以看到很多需要它的情况。