给定一对范围,其中一个范围包含另一个范围的元素:
src = ActiveSheet.UsedRange
sel = src.SpecialCells(xlCellTypeVisible)
获得代表设定差异的新范围的最有效方法是什么
这两个范围之间,即src
中不的sel
中的单元格?
这可以使用src
中的单元格上的循环来完成,但这需要m * n
自动调用m
到n
范围,但不是很性能良好,我希望能有更少的远程API调用。
答案 0 :(得分:4)
您是否尝试使用Excel的内置公式来过滤数据?例如,如果在D列中找到单元格A2中的值,则以下公式将打印“是”。在您的情况下,您可以简单地抓取所有没有相应“是”的单元格。
=IF(MATCH(A2,D:D, 0)>0,"Yes","No")
答案 1 :(得分:2)
我认为没有比循环遍历src中的每个单元更好的方法了。 Excel.Application对象具有Intersect函数,该函数告诉您两个或多个范围中包含哪些单元格,但不是相反。你也可以执行一个联合,它只给你一个范围,包含两个或多个范围内的所有单元格......
但我认为你将不得不通过src中的每个单元格来查看它是否在sel ...
Function GetInvisibleCells() As Range
Dim src As Range, sel As Range
Set src = ActiveSheet.UsedRange
Set sel = src.SpecialCells(xlCellTypeVisible)
Dim Isection As Range
Set Isection = Application.Intersect(src, sel)
Dim Result As Range
Dim cl As Range
For Each cl In src ' Go find all the cells in range2 that aren't in Isection
If Application.Intersect(cl, Isection) Is Nothing Then
' Cl is not in sel
If Not Result Is Nothing Then
Set Result = Range(Result, cl)
Else
Set Result = cl
End If
' Debug.Print Cl.Address & " is in " & src.Address & " and not in " & sel.Address
End If
Next cl
Application.Intersect
Set GetInvisibleCells = Result
End Function
有一些详细的方法here
答案 2 :(得分:2)
为了扩展Tom E的答案,我遇到的一个问题是,当没有匹配时,=MATCH()
会返回#N/A
,这是整个函数不喜欢的。
要解决此问题,您可以对等式进行以下更改:
=IF(ISNA(MATCH(A2,D:D, 0)),"No","Yes")
ISNA()
有效地将数字转换为Yes
和#N/A
(不匹配)为No
,这正是我们想要的。请注意,由于ISNA()
的功能如何,我不得不翻转“是”和“否”的顺序。
答案 3 :(得分:0)
这是另一种解决方法。
根据{{1}}方法reference from MSDN:
“返回一个ColumnDifferences
对象,该对象表示其内容与每列中的比较单元格不同的所有单元格”。
基于此,我采用了以下策略:
(1)将Range
的内容存储到src
。
(2)用完全随机的东西替换Variant
的内容。
(3)使用sel
方法获得所需的范围。
(4)返回ColumnDifferences
中存储的src
的原始值。
以上步骤的实施如下:
Variant
Dim src As Range, sel As Range, rngDiff As Range, varTempStorage As Variant
Dim icnt1 As Long, icnt2 As Long
Set src = ActiveSheet.UsedRange
Set sel = src.SpecialCells(xlCellTypeVisible)
' Store the src values in a variant
varTempStorage = src.Value
' Fill up the visible range with something random
sel.Value = "something completely random"
' Will return an error if nothing is found so needs appropriate error handling
' If it works, it should set rngDiff to point to the hidden cells only
Set rngDiff = src.ColumnDifferences(Comparison:=src(1,1))
' Pass data from variant to range - method taken from CPearson's website
Set src = src(1, 1)
src.Resize(UBound(varTempStorage, 1), UBound(varTempStorage, 2)).Value = varTempStorage
' Have a look at the output
For icnt1 = 1 To rngDiff.Rows.Count
For icnt2 = 1 To rngDiff.Columns.Count
Debug.Print " address: "; rngDiff(icnt1, icnt2).Address; " value: "; rngDiff(icnt1, icnt2)
Next icnt2
Next icnt1
方法应该给出相同的结果 - 这是因为我们替换了可见范围内的所有单元格,因此两种方法的行为方式相同。
我通过在第1 - 17行和第A - U列中生成随机数来检查上述内容,并通过隐藏第7 - 10行来完成工作。