在Excel Automation中获得Range“设置差异”的最有效方法是什么?

时间:2009-02-27 22:24:56

标签: excel automation

给定一对范围,其中一个范围包含另一个范围的元素:

src = ActiveSheet.UsedRange
sel = src.SpecialCells(xlCellTypeVisible)

获得代表设定差异的新范围的最有效方法是什么 这两个范围之间,即srcsel中的单元格?

这可以使用src中的单元格上的循环来完成,但这需要m * n自动调用mn范围,但不是很性能良好,我希望能有更少的远程API调用。

4 个答案:

答案 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行来完成工作。