Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何查找Excel中隐藏的非连续非空单元格集_C#_Excel_Visual Studio_Excel Interop - Fatal编程技术网

C# 如何查找Excel中隐藏的非连续非空单元格集

C# 如何查找Excel中隐藏的非连续非空单元格集,c#,excel,visual-studio,excel-interop,C#,Excel,Visual Studio,Excel Interop,我正在使用C作为Excel加载项。 我需要在隐藏行中找到所有非空单元格。这些单元格是非连续的,不遵循模式。以下是一个例子: 我已尝试使用Range.SpecialCells: Range rangeToSearch = Excel.ActiveSheet.Rows[row].Cells; try { Range rangeMatch = rangeToSearch.SpecialCells(XlCellType.xlCellTypeFormulas | XlCellType.xlCel

我正在使用C作为Excel加载项。 我需要在隐藏行中找到所有非空单元格。这些单元格是非连续的,不遵循模式。以下是一个例子:

我已尝试使用Range.SpecialCells:

Range rangeToSearch = Excel.ActiveSheet.Rows[row].Cells;

try
{
    Range rangeMatch = rangeToSearch.SpecialCells(XlCellType.xlCellTypeFormulas | XlCellType.xlCellTypeValues)

    // Loop over rangeMatch
}
catch (COMException)
{
    // no matches
}
和范围。查找:

Range rangeToSearch = Excel.ActiveSheet.Rows[row].Cells;
Range rangeMatch = rangeToSearch.Find("*", Type.Missing, XlFindLookIn.xlValues, XlLookAt.xlPart, XlSearchOrder.xlByColumns);

// Check if null then loop using FindNext
这些方法只适用于可见行,而不适用于隐藏行。 我知道的解决问题的唯一方法是使用Worksheet.UsedRange,但我认为这根本不可靠,而且它也会得到空单元格


有没有一种干净有效的方法来实现我的目标?

你可以用几种方法来实现。我将提供一种方法,将Excel模型中非连续的单元格缩放区域集中的单元格输出到列表中

    static Excel.Range GetCellsWithValues(Excel.Range row)
    {
        Excel.Range r = null;
        // Cut out unneccessary calcs by using only the intersection of the Row with the UsedRange
        Excel.Range usedRow = row.Application.Intersect(row, row.Worksheet.UsedRange);
        if (usedRow != null)
        {
            foreach (Excel.Range cell in usedRow)
                if (cell.Value2 != null)  //if non-empty unite to r
                    r = (r == null) ? cell : row.Application.Union(r, cell);
        }
        return r;  // a non-contiguous Range will have Areas with blocks of contiguous Ranges
    }

    static List<Excel.Range> GetCellListFromAreas(Excel.Range r)
    {   // this will unwrap the cells from non-contiguous range into a List
        // choose other collections for your use
        List<Excel.Range> cellList = new List<Excel.Range>();
        Excel.Areas areas = r?.Areas;

        if (areas != null)
        { 
            // Unwrap the Areas (blocks of contiguous cells)
            foreach (Excel.Range area in areas)
                foreach (Excel.Range cell in area)
                    cellList.Add(cell);  // add each cell in each contiguous block
        }
        return cellList;
    }
这样称呼:

List cellList=GetCellListFromAreasGetCellsWithValuesExcel.ActiveSheet.Rows[row]

虽然我们更喜欢通过工作表名称而不是ActiveSheet明确限定工作表

另外请注意,您可以不使用Excel Rangescells的集合/列表,而是将值放入数组或其他任何内容中

因此,很明显,你可以第一次直接将其放入一个列表中,并将并集的步骤切割成范围,而不是展开区域。就像:

    static List<Excel.Range> GetCellListWithValues(Excel.Range row)
    {
        List<Excel.Range> cellList = new List<Excel.Range>();
        Excel.Range r = null;
        Excel.Range usedRow = row.Application.Intersect(row, row.Worksheet.UsedRange);
        if (usedRow != null)
        {
            foreach (Excel.Range cell in usedRow)
                if (cell.Value2 != null)
                    cellList.Add(cell);
        }
        return cellList;
    }

如果您通过异常处理来检测代码中的正或负情况,则应考虑其他方法。异常处理耗费资源和时间。这通常被认为是一种代码,我确实同意。我通常不依赖异常处理。在这种特殊情况下,Range.SpecialCells在找不到任何内容时将抛出一个COMException,因此在我看来,在本例中必须显示这一点,以保持一致性。另外,我不想用更多的异常处理来重载我的主题。Range.Find是我的第一个方法,我只是尝试使用SpecialCells,因为它失败了。您好,MacroMarc,非常感谢您的超级清晰的答案!我测试了它,它确实有效。事实上,我也有类似的解决方案。我希望我有办法直接检索我需要的所有单元格,而不必检查每个单元格中是否有值。但是,您的解决方案有效并回答了问题。另外,由于它与我所拥有的非常相似,我想您无法避免最后的迭代。我认为你的答案是正确的。感谢您的时间和这个解释得很好的答案!很乐意帮忙。谢谢