简体   繁体   English

Excel vba Union方法复制重叠的单元格

[英]Excel vba Union method duplicates cells that overlap

I expected the following macro to display 6 but it displays 8. I understand that this is because Union duplicates cells that overlap as do cells b1:b2 in my example: 我希望下面的宏显示6,但它显示8.我明白这是因为Union重复了重叠的单元格,就像我的例子中的单元格b1:b2一样:

Sub a()
Dim myRange As Range
Set myRange = Application.Union(Range("a1:b2"), Range("b1:b4"))
MsgBox myRange.Count
End Sub

I found this solution to the problem but I'm interested to know why this is the way Union works and if there is any other way to get around this besides writing a new function as suggested by the above link. 我找到了这个问题的解决方案,但我很想知道为什么这是Union工作的方式,如果还有其他方法来解决这个问题,除了编写上述链接所建议的新功能。

Yes, the Union operator is really more like a UNION ALL statement in SQL. 是的,Union运算符实际上更像是SQL中的UNION ALL语句。 Excel's Union operator does not return the distinct set of cells. Excel的联盟运营商不会返回不同的一组细胞。

I find it somewhat pointless to speculate much about 20-year old closed-source design decisions, although it is interesting to note that the way that Excel-VBA handles Union meshes with the way Excel treats multiple range selections in spreadsheet functions. 我发现很多关于20年前闭源设计决策的推测有点没有意义,尽管有趣的是要注意Excel-VBA处理Union网格的方式与Excel处理电子表格函数中的多个范围选择的方式。 In this: 在这:

在此输入图像描述

the sum evaluates to 12 and not 10. Thus it seems likely that VBA's approach was an attempt to come up with a Range object that corresponds to how Excel itself treats overlapping selections. 总和评估为12而不是10.因此,VBA的方法似乎是尝试提出一个Range对象,该对象与Excel本身如何处理重叠选择相对应。 This would push back the design-decision to pre-VBA Excel. 这会将设计决策推迟到VBA之前的Excel。

If Union doesn't do what you want, then you need to write a different function. 如果Union没有做你想做的事,那么你需要编写一个不同的功能。 Chip Pearson is an extremely good VBA programmer, so I would be surprised if there is any easy work-around that he missed. Chip Pearson是一位非常优秀的VBA程序员,所以如果他错过任何简单的解决方案,我会感到惊讶。 Your actual question discussed the count of the union. 你的实际问题讨论了工会的数量 If that is what you want, you could write a smaller function: 如果这是你想要的,你可以编写一个较小的函数:

Function UnionCount(A As Range, B As Range) As Long
    Dim adjustment As Long
    If Not Intersect(A, B) Is Nothing Then
        adjustment = Intersect(A, B).Cells.Count
    End If
    UnionCount = Union(A, B).Cells.Count - adjustment
End Function

Then UnionCount(Range("A1:B2"), Range("B1:B4")) evaluates to 6. 然后UnionCount(Range("A1:B2"), Range("B1:B4"))评估为6。

hil, HIL,

The union method creates a range with n areas. union方法创建一个包含n个区域的范围。

It is interesting that this Application.Union(Range("a1:c2"), Range("a1:c2"), Range("a1:c2")) creates a single area. 有趣的是,这个Application.Union(Range("a1:c2"), Range("a1:c2"), Range("a1:c2"))创建了一个区域。 And in fact for the case where one of the ranges contains all the others entirely you will only get back the 1 area. 事实上,对于其中一个范围完全包含所有其他范围的情况,您将只返回1个区域。 eg Application.Union(Range("a1:f2"), Range("b2:d2")) . 例如Application.Union(Range("a1:f2"), Range("b2:d2")) Another interesting example is Application.Union(Range("a1:f2"), Range("b2:d3"), Range("d2:e3")) this merged range(b2:e3) and created 2 areas. 另一个有趣的例子是Application.Union(Range("a1:f2"), Range("b2:d3"), Range("d2:e3"))这个合并范围(b2:e3)并创建了2个区域。

A point to make at this point is that contiguous ranges have to be rectangular. 此时要说明的是,连续范围必须是矩形。

So Union will create the most efficient contiguous blocks of ranges, but there may still be some overlap. 因此,Union将创建最有效的连续范围块,但可能仍存在一些重叠。

CPearson's website has been around since the dawn of time, so it is very unlikely that you will find a better source for many problems. CPearson的网站从一开始就存在,所以你不太可能找到更好的问题来源。 ( I am not CPearson ). 我不是CPearson )。

Regards Gareth 关心加雷思

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM