Как указано в ответе SmStroble, и я упомянул ранее. Если вы запуститесь в TOP файла excel и удалите пустые строки, вы столкнетесь с проблемой индексирования при удалении строки и смещении других, индексирование строк в цикле будет сброшено. В коде цикла for
вы указали эту переменную i
. Использование этого подхода пропустит пустые строки и, возможно, удалит непустые строки.
Ответ SmStroble - это правильный способ исправить эту проблему, однако есть несколько проблем. Сначала, как мы прокомментировали, мы хотим удалить строки снизу вверх, поэтому решение SmStroble - это цикл строк, чтобы найти индексы строк для пустых строк и поместить их в List<int>
. Единственная проблема здесь в том, что при использовании цикла foreach
здесь он начинается с первого элемента, помещенного в список, а не из последнего.
Вторая проблема, с которой вы можете столкнуться, - это время выполнения. Цикл через строки Excel может быть дорогостоящим. При использовании следующей MySheet.UsedRange
линии в for
цикле:
for (int i = 1; i < MySheet.UsedRange.Rows.Count; i++) {…
Эта линия является дорогостоящим. Если на листе много строк, это может занять значительное количество времени. Есть и другие решения для этого, однако простое решение, чтобы просто сделать в int
переменную для хранения количества строк и использовать его в петлю for
, как показано ниже:
int totalRows = MySheet.UsedRange.Rows.Count;
for (int i = 1; i < totalRows; i++) {
Это небольшое изменение позволит ускорить выполнение значительно в зависимости от количество строк в электронной таблице. Используя тестовый лист с 730 + строками, он занял 2447 миллисекунд с UsedRange
в цикле for
и 1118 миллисекунд, когда usedRange
находился за пределами цикла for
. Надеюсь это поможет.
string filePath = @"C:\YourPathToExcelFile\YourExcelFile.xls";
Microsoft.Office.Interop.Excel.Application ExcelApp = new Microsoft.Office.Interop.Excel.Application();
ExcelApp.Visible = true;
Workbooks wbs = ExcelApp.Workbooks;
Workbook xlWorkbook = wbs.Open(filePath, 0, false, 5, "", "", false, XlPlatform.xlWindows, "", true, false, 0, true, false, false);
Excel._Worksheet MySheet = xlWorkbook.Sheets[1];
const int aCol = 1;
const int bCol = 2;
const int cCol = 3;
List<int> rowsToDelete = new List<int>();
int totalRows = MySheet.UsedRange.Rows.Count;
for (int i = totalRows; i > 0; i--) {
if ((MySheet.Cells[i, aCol].Value ?? "").ToString() == "" &&
(MySheet.Cells[i, bCol].Value ?? "").ToString() == "" &&
(MySheet.Cells[i, cCol].Value ?? "").ToString() == "") {
rowsToDelete.Add(i);
}
}
foreach (int row in rowsToDelete) {
((Range)(MySheet.Rows[row])).Delete(XlDirection.xlUp);
}
xlWorkbook.Save();
xlWorkbook.Close();
ExcelApp.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlWorkbook);
System.Runtime.InteropServices.Marshal.ReleaseComObject(ExcelApp);
Console.WriteLine("Fished processing! Press any key to exit");
Console.ReadKey();
EDIT: изменил код выше, чтобы петли из нижней части файла первенствовать к вершине. Это позволяет избежать изменения списка rowsToDelete
.
Я пробовал, но по какой-то причине он не удаляет пустые строки. –
Попробуйте переключиться. Значения .Value2 ячейки могут иметь некоторое форматирование (например, дату/время), которое возвращает тип с не пустым значением по умолчанию. – SMStroble
@JohnG Дерьмо ваше право. Клянусь, я сделал это изменение, я думаю, это не повлияло на мой ответ. Исправлена. – SMStroble