Как найти непрерывный набор непустых ячеек, которые скрыты в Excel - PullRequest
0 голосов
/ 05 марта 2019

Я использую C # для надстройки Excel.
Мне нужно найти все непустые ячейки в скрытой строке.Эти клетки не являются смежными и не следуют шаблону.Вот пример:

enter image description here

Я пытался использовать 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.Find:

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, однако я не думаю, что это вообще надежно, плюс он также получит пустые ячейки.

Есть ли чистыйи эффективный способ добиться того, что я пытаюсь сделать?

1 Ответ

0 голосов
/ 06 марта 2019

Вы можете сделать это несколькими способами.я дам вам способ вывода ячеек из несмежного набора ячеек (называемых областями в модели 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<Excel.Range> cellList = GetCellListFromAreas(GetCellsWithValues(Excel.ActiveSheet.Rows[row]));

Хотя мы предпочитаем, если вы квалифицируете листы явно по имени листа, а не по ActiveSheet.

Обратите также внимание, что вы можете отказаться от Коллекции / Списка диапазонов Excel (ячеек) и поместить значения вмассив или что-то в этом роде ...

Итак, очевидно, что вы могли бы сразу поместить в Список прямо и вырезать шаги Union по диапазонам, чем разворачивать Области.Так как:

    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;
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...