快速检测给定工作表中是否有数据的过程,而无需实际循环遍历工作表的所有行/列。
对于我当前的流程,我目前正在遍历整个工作表,并且在我的导入中有一些明显的滞后时间。
快速检测给定工作表中是否有数据的过程,而无需实际循环遍历工作表的所有行/列。
对于我当前的流程,我目前正在遍历整个工作表,并且在我的导入中有一些明显的滞后时间。
为避免循环并利用近乎瞬时的执行速度,您可以使用该Excel.WorksheetFunction.CountA
方法,该方法返回与 =CountA() 工作表函数相同的结果。
假设您的 Excel.Application 引用被命名为“excelApp”并且您的 Excel.Worksheet 引用被命名为“worksheet”,您可以在 C# 4.0 中使用如下代码:
// C# 4.0
int dataCount = (int)excelApp.WorksheetFunction.CountA(worksheet.Cells);
if (dataCount == 0)
{
// All cells on the worksheet are empty.
}
else
{
// There is at least one cell on the worksheet that has non-empty contents.
}
在 C# 3.0 及更低版本中,它有点冗长,因为您必须显式提供缺少的可选参数:
// C# 3.0 and below
int dataCount = (int)excelApp.WorksheetFunction.CountA(
worksheet.Cells,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
if (dataCount == 0)
{
// All cells on the worksheet are empty.
}
else
{
// There is at least one cell on the worksheet that has non-empty contents.
}
我使用 VSTO 和 Excel 有一段时间了,工作强度非常高,所以我希望我能与你分享我在这段时间里学到的东西。
根据您提供的信息,我建议转换为对象数组并使用该信息。基本上,您可以通过以下方式访问这些值:
object[,] arrayValues = (object[,])ExcelRange.Value2;
arrayValues 是一个二维数组 ([row,column])。Excel 以极快的速度填充数组,当然对数组的操作将非常高效(不要担心装箱的性能,相信我,这不是问题)。
我找到了以下解决方案,它也是即时的,但我不确定它有多准确......到目前为止它已经通过了我的所有测试。
这里是给任何想知道的人:
Worksheet sheet = (Worksheet)this.Application.ActiveSheet;
Range usedRange = sheet.UsedRange;
bool isUsed = (usedRange.Count > 1);
if (usedRange.Count == 1)
{
isUsed = (usedRange.Value2 != null) &&
(!string.IsNullOrEmpty(usedRange.Value2.ToString()));
}
if(isUsed)
{
// worksheet cells not empty
}
我想这比每次检查或计算工作表中的所有非空单元格时都炸毁剪贴板要简单得多。谢谢 Mikael 和 Mike,感谢您的回答。
怎么样?
public static bool IsSheetEmpty(int sheetNo)
{
bool isEmpty = false;
if (sheetNo <= Globals.ThisAddIn.Application.Worksheets.Count)
{
Worksheet ws = Globals.ThisAddIn.Application.Worksheets[sheetNo];
if (ws.UsedRange.Address.ToString() == "$A$1" && String.IsNullOrWhiteSpace(ws.get_Range("A1").Value2))
{
isEmpty = true;
}
}
else
{
// or add your own error handling when sheetNo is not found
}
return isEmpty;
}
示例调用
bool isFirstEmpty = IsSheetEmpty(1);
这应该很快:
private void CheckForContent()
{
Worksheet activeSheet = ActiveSheet;
var range = activeSheet.get_Range("A1", GetExcelColumnName(activeSheet.Columns.Count)+activeSheet.Rows.Count.ToString() );
range.Select();
range.Copy();
string text = Clipboard.GetText().Trim();
if(string.IsNullOrEmpty(text))
{
MessageBox.Show("No text");
}
}
private string GetExcelColumnName(int columnNumber)
{
int dividend = columnNumber;
string columnName = String.Empty;
int modulo;
while (dividend > 0)
{
modulo = (dividend - 1) % 26;
columnName = Convert.ToChar(65 + modulo).ToString() + columnName;
dividend = (int)((dividend - modulo) / 26);
}
return columnName;
}