Итерация по строкам Excel пропускает число КАЖДЫЙ РАЗ, когда он проходит через цикл foreach, извлекая неправильные значения ячеек. Почему

У меня есть этот метод, который принимает два строковых параметра и перебирает каждую строку на листе Excel, чтобы найти совпадение в двух столбцах. когда он находит совпадение, он возвращает номер строки, чтобы этот номер можно было использовать для определения (в другом методе), какую строку нужно ОБНОВИТЬ.

    public int IterateRows(string f, string l)
    {

        Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
        Microsoft.Office.Interop.Excel.Workbook xlWorkbook = xlApp.Workbooks.Open(locationAndNameOfExcelFile, 0, true, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
        Microsoft.Office.Interop.Excel._Worksheet xlWorksheet = (Microsoft.Office.Interop.Excel._Worksheet)xlWorkbook.Sheets[1];

        //Iterate the rows in the used range
        foreach (Microsoft.Office.Interop.Excel.Range row in xlWorksheet.UsedRange.Rows)
        {
            var familyNameCellValue = row.Cells[row.Row, 2].Value2.ToString();
            var firstNameCellValue = row.Cells[row.Row, 3].Value2.ToString();;

            if (f == familyNameCellValue && firstNameCellValue == l)
            {
                return row.Row;
            }
        }
        return -1;
    }

Проблема в том, что при отладке каждой итерации foreach при наведении курсора на значения «row.Row» я замечаю, что они верны (например, НЕ пропуская строку Excel). Я точно знаю, думал, что значения для определенного значения ячейки должны быть чем-то другим. Кажется, перескочил на такое, что

  • если "row.Row" имеет значение 2, оно имеет значение ячейки 3-й строки,
  • если "row.Row" имеет значение 3, оно имеет значение ячейки 5-й строки,
  • если "row.Row" имеет значение 4, оно имеет значение ячейки 7-й строки,
  • если "row.Row" имеет значение 5, оно имеет значение ячейки 9-й строки,
  • если "row.Row" имеет значение 6, оно имеет значение ячейки 11-й строки,
  • и т. д., если строка, которую я ищу, является нечетным числом, она, очевидно, вернет «row.Row»

может кто-нибудь объяснить, почему он пропускает?


person user2403316    schedule 12.05.2016    source источник


Ответы (2)


Решил это (это немного грязно, и я до сих пор не понимаю, почему он пропускает строку в каждой итерации foreach, но я добавил «var i», чтобы отслеживать строку, в которой я нахожусь. учитывая разброс в каждой итерации, он повышается на один. поэтому я просто установил новый "var r" для представления строки на основе тернарного оператора. Поскольку первая строка является заголовком, она всегда работает

    public int IterateRows(string f, string l)
    {
        Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
        Microsoft.Office.Interop.Excel.Workbook xlWorkbook = xlApp.Workbooks.Open(locationAndNameOfExcelFile, 0, true, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
        Microsoft.Office.Interop.Excel._Worksheet xlWorksheet = (Microsoft.Office.Interop.Excel._Worksheet)xlWorkbook.Sheets[1];

        var rowsRanged = xlWorksheet.UsedRange.Rows;
        var i = 1;
        //Iterate the rows in the used range
        foreach (Microsoft.Office.Interop.Excel.Range row in rowsRanged)
        {
            var r = row.Row > 1 ? row.Row - i : row.Row;
            var familyNameCellValue = row.Cells[r, 2].Value2.ToString();
            var firstNameCellValue = row.Cells[r, 3].Value2.ToString();
            //var familyNameCellValue = row.Cells[i, 2].Value2.ToString();
            //var firstNameCellValue = row.Cells[i, 3].Value2.ToString();

            if (f == familyNameCellValue && firstNameCellValue == l)
            {
                return i - 1;
            }
            i++;
        }
        return -1;
    }
person user2403316    schedule 13.05.2016

Просто провел целое утро, пытаясь найти решение той же проблемы, и кажется, что небольшое дополнение все еще может быть полезным. Ваша ошибка в том, что вы обращаетесь к ячейкам в строке, как к ячейкам во всем диапазоне, тогда как строка — это просто обычная горизонтальная линия ячеек: Cell[1,1], Cell[1,2] ... неважно насколько велик был исходный индекс этой строки в таблице.

Итак, вместо этого

var familyNameCellValue = row.Cells[row.Row, 2].Value2.ToString();

просто напишите так:

var familyNameCellValue = row.Cells[1, 2].Value2.ToString();

Для меня работает как швейцарские часы.

person Nyasha    schedule 07.05.2019