Interop ライブラリを使用して、Excel ファイルから余分な空白の行と列をすべて削除しようとしています。
私はこの質問をフォローしましたInterop を使用して Excel ファイルから空の行と列を削除する最も速い方法そしてそれは役に立つと思います。
しかし、Excelファイルには小さなデータセットが含まれていますが、空の行と列がたくさんあります(最後の空でない行 (または列) からワークシートの最後まで)
行と列をループしようとしましたが、ループに何時間もかかります。
最後の空でない行と列のインデックスを取得して、1行で空の範囲全体を削除できるようにしたいと考えています。
XlWks.Range("...").EntireRow.Delete(xlShiftUp)
注: データを含む最後の行を取得して、余分な空白をすべて削除しようとしています (この行または列の後)
助言がありますか?
注: コードはSSISスクリプトタスク環境と互換性がある必要があります。
ベストアンサー1
アップデート1
C#を使用してExcelデータをインポートすることが目的の場合、ワークシートで最も多く使用されているインデックスを特定したと仮定します。(投稿した画像では、Col = 10、Row = 16です)、最大使用インデックスを文字に変換してJ16
、使用範囲のみを選択して、OLEDBCommand
SELECT * FROM [Sheet1$A1:J16]
そうでなければ、もっと速い方法を見つけるのは簡単ではないと思います。
インデックスをアルファベットに変換し、OLEDB を使用して Excel に接続するには、次の記事を参照してください。
最初の回答
あなたが言ったように、あなたは次の質問から始めました:
そしてあなたは「データを含む最後の行を取得し、余分な空白をすべて削除します(この行または列の後)。」
したがって、受け入れ回答(ジョンG)、最後に使用した行と列を取得するコードを追加することができます。
空の行は整数のリストに格納されますrowsToDelete
次のコードを使用すると、最後の空行よりも小さいインデックスを持つ最後の空でない行を取得できます。
List<int> NonEmptyRows = Enumerable.Range(1, rowsToDelete.Max()).ToList().Except(rowsToDelete).ToList();
NonEmptyRows.Max() < rowsToDelete.Max()
そして、最後の空でない行がNonEmptyRows.Max()
空でない場合worksheet.Rows.Count
、最後の使用された行の後に空の行はありません。
同じことをして、最後の空でない列を取得できます。
コードは次のように編集されDeleteCols
、DeleteRows
機能します。
private static void DeleteRows(List<int> rowsToDelete, Microsoft.Office.Interop.Excel.Worksheet worksheet)
{
// the rows are sorted high to low - so index's wont shift
List<int> NonEmptyRows = Enumerable.Range(1, rowsToDelete.Max()).ToList().Except(rowsToDelete).ToList();
if (NonEmptyRows.Max() < rowsToDelete.Max())
{
// there are empty rows after the last non empty row
Microsoft.Office.Interop.Excel.Range cell1 = worksheet.Cells[NonEmptyRows.Max() + 1,1];
Microsoft.Office.Interop.Excel.Range cell2 = worksheet.Cells[rowsToDelete.Max(), 1];
//Delete all empty rows after the last used row
worksheet.Range[cell1, cell2].EntireRow.Delete(Microsoft.Office.Interop.Excel.XlDeleteShiftDirection.xlShiftUp);
} //else last non empty row = worksheet.Rows.Count
foreach (int rowIndex in rowsToDelete.Where(x => x < NonEmptyRows.Max()))
{
worksheet.Rows[rowIndex].Delete();
}
}
private static void DeleteCols(List<int> colsToDelete, Microsoft.Office.Interop.Excel.Worksheet worksheet)
{
// the cols are sorted high to low - so index's wont shift
//Get non Empty Cols
List<int> NonEmptyCols = Enumerable.Range(1, colsToDelete.Max()).ToList().Except(colsToDelete).ToList();
if (NonEmptyCols.Max() < colsToDelete.Max())
{
// there are empty rows after the last non empty row
Microsoft.Office.Interop.Excel.Range cell1 = worksheet.Cells[1,NonEmptyCols.Max() + 1];
Microsoft.Office.Interop.Excel.Range cell2 = worksheet.Cells[1,NonEmptyCols.Max()];
//Delete all empty rows after the last used row
worksheet.Range[cell1, cell2].EntireColumn.Delete(Microsoft.Office.Interop.Excel.XlDeleteShiftDirection.xlShiftToLeft);
} //else last non empty column = worksheet.Columns.Count
foreach (int colIndex in colsToDelete.Where(x => x < NonEmptyCols.Max()))
{
worksheet.Columns[colIndex].Delete();
}
}