ワークシートのすべての行/列を実際にループすることなく、特定のワークシートにデータがあるかどうかをすばやく検出するプロセス。
私の現在のプロセスでは、現在シート全体をループしており、インポートに顕著なラグタイムがあります。
ワークシートのすべての行/列を実際にループすることなく、特定のワークシートにデータがあるかどうかをすばやく検出するプロセス。
私の現在のプロセスでは、現在シート全体をループしており、インポートに顕著なラグタイムがあります。
ループを回避し、ほぼ瞬時の実行速度を利用するには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 は 2D 配列 ([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;
}