简体   繁体   English

Excel C#Interop-将选定范围缩小到仅填充的单元格

[英]Excel C# Interop - narrow selected range to populated cells only

I have a VSTO solution that corrects data in highlighted cells. 我有一个VSTO解决方案,可以纠正突出显示的单元格中的数据。 The issue I am having is if the user selects an entire row/column, the program cycles through thousands of empty cells, long after the last populated cell has been processed. 我遇到的问题是,如果用户选择整个行/列,则在处理完最后一个填充的单元很长时间之后,该程序将循环遍历数千个空单元格。

My code looks like this: 我的代码如下所示:

        var addIn = Globals.ThisAddIn;
        Excel.Worksheet sheet = addIn.Application.ActiveSheet;
        Excel.Range range = addIn.Application.Selection;

        foreach (Excel.Range cell in range.Cells)
        {
            var val = cell.Value2;
            if (val == null)
                continue;

I've seen threads on how to use: 我看过有关如何使用的线程:

AdvancedFilter(Excel.XlFilterAction.xlFilterInPlace, Type.Missing)

But I can't seem to tie the two. 但是我似乎无法将两者捆绑在一起。 I either want my "range" object to be limited to only populated cells or to be able to short-circuit my foreach loop when I have supassed the last value. 我要么希望我的“范围”对象仅限于填充的单元格,要么希望当我超过最后一个值时能够使我的foreach循环短路。

I thought of doing something like this: 我想到做这样的事情:

if (cell.Row > populatedRange.Row ||
    cell.Column > populatedRange.Column)
    break;

But this has the potential of breaking the code if something other than an entire row/column is selected (user selects a cell outside of the populated range, and all subsequent populated cells are ignored). 但是,如果选择了除整个行/列以外的内容,则有可能破坏代码(用户选择一个不在填充范围内的单元格,而所有后续填充的单元格都将被忽略)。

I know I'm missing something simple, but my attempts (and searches) have not yielded the answer. 我知道我缺少一些简单的东西,但是我的尝试(和搜索)没有给出答案。

You can use the Range.SpecialCells method on the sheet to find the last cell. 您可以在工作表上使用Range.SpecialCells方法查找最后一个单元格。 Then you can modify your loop to exit when you move beyond the last row or column. 然后,您可以修改循环以在移至最后一行或最后一列时退出。 The following snippet will give your the row and column number of the last cell. 以下代码段将为您提供最后一个单元格的行号和列号。 You may still process some empty cells, but you won't be going all the way down to row 1048574. 您可能仍会处理一些空单元格,但不会一直到1048574行。

Excel.Range last = Globals.Sheet1.Cells.SpecialCells(Excel.XlCellType.xlCellTypeLastCell, Type.Missing);
int lastRowNumber = last.Row;
int lastColumnNumber = last.Column;

Why don't you convert your range range.Cells into an array and deal with this in memory. 为什么不将范围range.Cells转换为数组并在内存中处理呢? Its way faster than iterating through each cell and then you can use all memory power of Linq or whatever to filter and correct your data... then you just send back to excel the updated range. 它的方式比遍历每个单元的速度快,然后您可以使用Linq的所有内存功能或其他任何功能来过滤和更正数据...然后您只需发送回excel至更新范围即可。

Doing: 这样做:

var obj = range.Cell

will cast your range into object[,] of 2 dimensions. 会将您的范围转换为2维的object[,] I think 我认为

System.Array myArray = (System.Array)(range.Cells)

would work too. 也会工作。

Regards. 问候。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM