Interop.Excel - 使用输出。,行[i] .Delete()将行向上移动,以便最近移位的行不会被for循环检查

问题描述 投票:0回答:1
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位置,但是这不起作用。

c# asp.net algorithm excel-interop
1个回答
0
投票

你减少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--)
© www.soinside.com 2019 - 2024. All rights reserved.