C#Excel Automation:使用SpecialCells()在AutoFilter()之后检索行似乎无法正常工作

时间:2011-10-12 14:58:13

标签: c# excel autofilter

这里的第一次海报:)。我从WinForms C#应用程序自动化Excel 2010时遇到以下问题。我的测试表看起来如下:

Index    Value1  Value2
AAA        2       3   
AAA        3       4
AAA        3       8
BBB        2       2
BBB        5       6
BBB        3       5
CCC        1       2
CCC        2       2
DDD        2       5

我成功打开工作簿并从C#应用程序加载工作表。之后我运行以下代码:

        Excel.Range range = xlSheet.UsedRange;
        range.AutoFilter(1, "AAA", Excel.XlAutoFilterOperator.xlAnd, Type.Missing, true);
        Excel.Range filteredRange = range.SpecialCells(Excel.XlCellType.xlCellTypeVisible);

这按预期工作,filterRange现在包含我的测试表的前四行(列名和所有“AAA”行)。但是,如果我尝试使用AutoFilter来获取所有“BBB”行,就像这样

        range.AutoFilter(1, "BBB", Excel.XlAutoFilterOperator.xlAnd, Type.Missing, true);
        Excel.Range filteredRange = range.SpecialCells(Excel.XlCellType.xlCellTypeVisible);

我最终只得到filteredRange范围中表格(列名称)的第一行。如果我实际打开Excel中的表,我可以看到它被正确过滤(“BBB”行)被过滤,但不知何故,Range.SpecialCells()方法没有按预期运行,只返回第一行。 我已经尝试了所有我能想到的东西,但由于我是Excel自动化的新手,也许我错过了一些东西,所以我认为你们可能会提供帮助。我唯一想到的是,在第一种情况下(“AAA”),所有可见行都是连续的 - 列名在第1行,“AAA”行分别是2,3和4。在第二种情况下,名称在第1行,但“BBB”行在索引5,6和7,即表中有一个“洞”。这可能会影响SpecialCells()方法吗?

提前感谢您提供的任何输入!

3 个答案:

答案 0 :(得分:8)

好吧,我解决了自己的问题,但我想分享解决方案,因为其他一些可怜的灵魂有一天可能会遇到同样的问题。基本上,我的第一个想法是问题可能是行不连续导致我得到了正确的答案。只要所有过滤的值都在表的第一行下面,SpecialCells()方法返回一个区域,因此filteredRange在其Value2成员中显示所有所需的值(在上面的测试用例中,所有“AAA”)行。但是,如果过滤的行在表中进一步向下,就像“BBB”的情况一样,则SpecialCells()方法返回多个区域,在这种情况下,两个 - 第一个区域仅包含列名称行,第二个区域包含第二个区域包含三个“BBB”行。解决方案是遍历filteredRange中的所有区域,并从那里提取/操作值:

        for (int areaId = 1; areaId <= filteredRange.Areas.Count; areaId++)
        {
            Excel.Range areaRange = filteredRange.Areas.get_Item(areaId);
            object[,] areaValues = areaRange.Value2;
            // Do something with the values here...

就是这样。我希望有一天能帮助别人......

答案 1 :(得分:1)

尝试以下方法:

var rowcount = filteredRange.Count / filteredRange.Columns.Count;

答案 2 :(得分:1)

我使用下面的这种方法来获取范围内的数据,

foreach (Excel.Range area in visibleCells.Areas)

  {
     foreach (Excel.Range row in area.Rows)
     {
         int index = row.Row; // now index is the present Row index within the range.you
         string test = Mysheet.Cells[index,4].Values // Mysheet is my present working sheet. After this test will contain the values pointing to the values.cells[index,4].
     }
}