Interop.Excel - 使用 output.,Rows[i].Delete() 将行向上移动,以便 for 循环不检查最近移动的行
Interop.Excel - using output.,Rows[i].Delete() is shifting the rows up so that the most recent shifted row is not checked by for loop
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 循环会递增,然后检查 'new' 行 2001,这意味着 'old' 行向上移动跳过位置 2000。
我第一个明显的解决方案是每当删除发生时递减 i,以便用新行重新检查当前 i 位置,但这不起作用。
您减少 i
的想法很好,但您也应该减少 LastRow
以防止出现 IndexOutOfRangeException。
output.Rows[i].Delete();
i--;
LastRow--;
您可以直接在 for 循环中检查行数,而不是每次递减 LastRow
。
for (int i = 2; i <= output.UsedRange.Rows.Count; i++)
更好的是,正如 Zhiven 所建议的,您可以反转循环。这样您就不必在每次删除时都更新 i
,并且您一定要检查每一行。
for (int i = output.UsedRange.Rows.Count; i >= 2; i--)
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 循环会递增,然后检查 'new' 行 2001,这意味着 'old' 行向上移动跳过位置 2000。
我第一个明显的解决方案是每当删除发生时递减 i,以便用新行重新检查当前 i 位置,但这不起作用。
您减少 i
的想法很好,但您也应该减少 LastRow
以防止出现 IndexOutOfRangeException。
output.Rows[i].Delete();
i--;
LastRow--;
您可以直接在 for 循环中检查行数,而不是每次递减 LastRow
。
for (int i = 2; i <= output.UsedRange.Rows.Count; i++)
更好的是,正如 Zhiven 所建议的,您可以反转循环。这样您就不必在每次删除时都更新 i
,并且您一定要检查每一行。
for (int i = output.UsedRange.Rows.Count; i >= 2; i--)