В VSTO Excel, Как обнаружить данные в ячейках?
Мне было интересно, знает ли кто-нибудь, как быстро определить, есть ли данные в данном листе или нет, без фактического цикла через все строки/столбцы листа, чтобы понять это.
Я пишу импортера, который будет импортировать данные прямо на активном листе (если он не был изменен), или создать новый лист и импортировать в него вместо этого. В настоящее время я просматриваю весь лист, и в моем импорт.
Я был бы признателен за любую помощь в этом вопросе. Спасибо!
5 ответов
чтобы избежать цикла и воспользоваться почти мгновенной скоростью выполнения, вы можете использовать Excel.WorksheetFunction.CountA
метод, который возвращает тот же результат, что и функция =CountA() листа.
предполагая, что ваш Excel.Ссылка на приложение называется "excelApp" и ваш Excel.Справочный лист называется 'лист', вы можете использовать следующий код в 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-это 2D-массив ([строка,столбец]). Excel заполняет массив невероятно быстро, и, конечно же, операции с массивом будут очень performant (не беспокойтесь о производительности бокса, это не проблема, поверьте мне).
HTH, Джеймс!--2-->
Я нашел следующее решение, которое также мгновенно, но я не уверен, насколько точны это... он прошел все мои испытания.
вот он для всех, кто хочет знать:
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
}
Я полагаю, что это намного проще, чем взрывать буфер обмена каждый раз, когда я делаю проверку или подсчет всех непустых ячеек на листе. Спасибо Майклу и майку, я ценю оба ваших ответа.
Как насчет?
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" && 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;
}