Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Excel 如何比较两个多区域范围_Excel_Vba - Fatal编程技术网

Excel 如何比较两个多区域范围

Excel 如何比较两个多区域范围,excel,vba,Excel,Vba,我有两个类型为Range的变量,比如r1和r2。如何检查它们是否在同一范围内?如果是单个单元格或单个连续单元格范围,则很容易(我们可以假设它们位于同一张表上): 但如果它们是多区域范围(r1.Areas.Count>0),该怎么办?在大多数情况下,上述代码行仍然有效,但区域地址在r1和r2地址中的显示顺序可能不同。例如,在某些情况下,您会遇到以下问题: Debug.Print r1.Address Debug.Print r2.Address 可能导致 "$A$1,$B$2" "$B$2,$A

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

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

Debug.Print r1.Address
Debug.Print r2.Address
可能导致

"$A$1,$B$2"
"$B$2,$A$1"
它们显然是相同的范围,但上面IF语句中的条件将计算为false

理想情况下,我想说,如果r1=r2,那么,但这是行不通的。也许我可以尝试一下与工会

编辑:

我也试过了

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

我在其他地方找到了一个很好的解决方案,因此:

If (Intersect(r1,r2).Cells.Count = r1.Cells.Count) AND Intersect(r1,r2).Cells.Count = r2.Cells.Count Then
这是因为,如果两个范围不完全相同,那么两个范围的交点的单元格总是少于其中至少一个

编辑

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

正如Rusan指出的,如果r1和r2中的一个或两个都有重叠的单元格,就会出现问题。因此,我们需要首先“消除重叠”:

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
然后


我应该指出,下面Gary的学生答案为我的问题提供了正确答案,我会将其标记为正确答案,但我认为构建上面的“去重叠”函数会很有用,因为我可以看到许多需要它的情况。

基于@Gary的学生示例,可以构造病理范围,从调用到
Union
,其中
.Cells.Count
无法正常工作。它统计1到n次之间的重叠单元格,其中n是单元格重叠的次数。链接中给出的示例显示,
r1=Union(范围(“A1:B1”)、范围(“B1:B5”)、范围(“B1:C2”))
r2=Union(范围(“A1:C1”)、范围(“B2:C2”)、范围(“B3:B5”)
分别由11个单元格和8个单元格组成<代码>相交(r1,r2)=9谢谢。六羟甲基三聚氰胺六甲醚。。。有趣。在我看来,这可能会在很多情况下导致问题,例如,当您的代码依赖于用户选择或命名范围时。我认为这需要在做任何其他事情之前将范围“去重叠”。是的,这是正确的。您可以使用Gary的学生显式双循环。但是,如果您必须比较非常大的范围(只相差几个单元格),则可以使用基于字典的稍微可伸缩的解决方案。如果你还不知道我的意思,我会发布一些东西。
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