C#UsedRange计数错误

时间:2017-01-14 19:35:52

标签: c# excel excel-interop

我使用UsedRange对象的Excel.Worksheet属性来获取行数和列数。如果我尝试删除列或行,则UsedRange计数应相应减少。但是,经过大量调试后,按一定的顺序更改了列的Hidden属性和列宽。计数不会相应改变,这应该表明为单元格设置了锚点。请帮忙解释一下(因为它会影响我的代码)。

测试代码:

Worksheet worksheet = Globals.ThisAddIn.Application.ActiveSheet;
Debug.WriteLine("Used Range Column Count 1: " + worksheet.UsedRange.Columns.Count);

worksheet.Range["A1"].Formula = "1";
worksheet.Range["B1"].Formula = "1";
worksheet.Range["C1"].Formula = "1";
worksheet.Range["D1"].Formula = "1";
Debug.WriteLine("Used Range Column Count 2: " + worksheet.UsedRange.Columns.Count);

Range column = worksheet.Columns[4];
column.Delete();
Debug.WriteLine("Used Range Column Count 3: " + worksheet.UsedRange.Columns.Count);

worksheet.Range["D1"].Formula = "1";
column = worksheet.Columns[4];
column.ColumnWidth = 20.0;
column.Hidden = true;
column.Hidden = false;
column.Delete();
Debug.WriteLine("Used Range Column Count 4: " + worksheet.UsedRange.Columns.Count);

worksheet.Range["D1"].Formula = "1";
column = worksheet.Columns[4];
column.Hidden = true;
column.Hidden = false;
column.ColumnWidth = 20.0;
column.Delete();
Debug.WriteLine("Used Range Column Count 5: " + worksheet.UsedRange.Columns.Count);

结果:

使用范围列数1:1(预期)
使用范围列数2:4(预期)
使用范围列数3:3(预期)
使用范围列数4:4(未预期)
使用范围列数5:3(预期)

有关正确使用范围计数的必要性的进一步说明:

我正在开发一个可以增强excel界面的应用程序。例如,用户有一个库存清单和采购成本,最后是子总价或平均价格线。 (实际的子总线将比总和和平均值复杂得多)因此,列表应该是可扩展的,但子总线不能。因此,我需要跟踪是否添加或删除了新行或新列,因此我需要根据历史(缓存)计数交叉检查excel工作表中的计数。由于新行或列可能没有实际数据,因此我使用UsedRange属性来确定显示的当前行/列数。因此,UsedRange包含已删除的行/列的事实使我的计算无法进行。

虽然我找不到解除锚定效果的方法,但我终于找到了一种方法来完成这项工作:

使用单个单元格名称范围标记工作表的最后一个单元格,使用UsedRange属性初始化范围。

如果您需要避免向用户显示该范围,可以尝试将数据保存在工作表中的自定义属性中。但是,这种方法需要对用户操作跟踪进行更多考虑(如果添加行/列,命名范围引用将自动更改)

1 个答案:

答案 0 :(得分:0)

好吧,UsedRange不能很好地确定最后一行和一列。相反,您可以使用此代码:

// get last row
var WorksheetLastRow = worksheet.Cells.Find(
    What: "*",
    SearchOrder: Excel.XlSearchOrder.xlByRows,
    SearchDirection: Excel.XlSearchDirection.xlPrevious,
    MatchCase: false
).Row;

// get last column
var WorksheetLastCol = worksheet.Cells.Find(
    What: "*",
    SearchOrder: Excel.XlSearchOrder.xlByColumns,
    SearchDirection: Excel.XlSearchDirection.xlPrevious,
    MatchCase: false
).Column;