public void deleteInvalidEmployees(string path)
{
Application app = new Application();
Workbook wb = app.Workbooks.Open(path);
Worksheet output = wb.ActiveSheet;
Range range = output.UsedRange;
var LastRow = output.UsedRange.Rows.Count;
Console.ForegroundColor = ConsoleColor.Green;
for (int i = 2; i <= LastRow; i++)
{
bool containsLetters = false;
string value = Convert.ToString(output.Cells[i, 2].Value);
if (value != null && value != "")
{
if (Regex.IsMatch(value.ToUpper(), "[A-Z]"))
{
Console.WriteLine("Contains letters for row " + i);
containsLetters = true;
}
}
if (value == "" || containsLetters == true || value == null)
{
Console.WriteLine("Deleting empty row " + i);
output.Rows[i].Delete();
}
}
wb.Save();
wb.Close();
app.Quit();
}
如上所述,我只是简单地删除了一行,但问题是在它删除行之后将行向上移动(我想要的)但是这意味着Forloop会跳过最近移位的行。例如,如果删除了行2000,则行2001被移动到第2000行的位置,因此for循环增加,然后检查“新”行2001,这意味着向上移动到位置2000的“旧”行是跳过。
我的第一个明显的解决方案是每当删除发生时减少i,以便用新行重新检查当前i位置,但是这不起作用。
你减少i
的想法很好,但你也应该减少LastRow
以防止IndexOutOfRangeException。
output.Rows[i].Delete();
i--;
LastRow--;
您可以直接在for-loop中检查行数,而不是每次都减少LastRow
。
for (int i = 2; i <= output.UsedRange.Rows.Count; i++)
甚至更好,正如zhiven建议的那样,你可以扭转你的循环。然后你不必在每次删除时更新i
,你一定要检查每一行。
for (int i = output.UsedRange.Rows.Count; i >= 2; i--)