c# Excel自动化:使用SpecialCells()在AutoFilter()之后检索行似乎不能正常工作

本文关键字:不能 工作 常工作 检索 AutoFilter 自动化 Excel 使用 SpecialCells 之后 | 更新日期: 2023-09-27 18:10:59

第一次在这里张贴海报:)。我有以下问题自动化Excel 2010从WinForms c#应用程序。我的测试表如下所示:

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"行)。但是,如果我尝试使用自动筛选器来获取所有"BBB"行,就像这样

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

在filtererange Range中只得到表的第一行(列名)。如果我实际上在Excel中打开表,我可以看到它被正确过滤("BBB"行)被过滤,但不知怎的,Range.SpecialCells()方法的行为不像预期的那样,只返回第一行。我已经尝试了我能想到的所有方法,但由于我是Excel自动化的新手,也许我遗漏了一些东西,所以我想你们可能能帮上忙。我唯一想到的是,在第一种情况下("AAA"),所有可见的行都是连续的—列名在第1行,"AAA"行分别是2、3和4。在第二种情况下,名称在第1行,但"BBB"行索引为5、6和7,即表中有一个"洞"。这会影响SpecialCells()方法吗?

提前感谢您的任何输入!

c# Excel自动化:使用SpecialCells()在AutoFilter()之后检索行似乎不能正常工作

好吧,我解决了我自己的问题,但我想分享这个解决方案,因为其他一些可怜的灵魂可能有一天会遇到同样的问题。基本上,我的第一个想法是问题可能是行不是连续的,这让我找到了正确的答案。只要所有过滤的值都在表第一行的正下方,SpecialCells()方法就返回一个单独的区域,因此filtererange在其Value2成员中显示所有所需的值(在上面的测试用例中,所有"AAA")行。但是,如果过滤的行位于表的更下端,如"BBB"的情况,SpecialCells()方法将返回多个区域,在本例中为两个—第一个区域仅包含列名行,第二个区域包含三个"BBB"行。解决方案是遍历filtererange中的所有区域,并从中提取/操作值:

        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...

就是这样。

尝试如下:

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

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

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].
     }
}