C # Эффективный способ перебора по листу Excel - PullRequest
0 голосов
/ 02 декабря 2018

У меня есть следующий код:

string result = "";
for(int i=2; i<=excelRange.Rows.Count; i++)
{
    result += excelRange.Cells[i, 2].Value2;
}

Для файла Excel с парой сотен записей это занимает 5 секунд.Возможно, есть более эффективный способ?Я хочу только значения от B2 до Bn.

Ответы [ 2 ]

0 голосов
/ 02 декабря 2018

Основной скелет выглядит следующим образом:

var xlApp = new Excel.Application { Visible = true };
var xlBook = xlApp.Workbooks.Open(@"C:\Temp\Results.xlsx");
var xlSheet = xlBook.Sheets[1] as Excel.Worksheet;
var arr = (object[,])xlSheet.Range["B2:B100000"].Value;
var sb = new StringBuilder();
for (int x = 1; x <= arr.GetUpperBound(0); ++x)
{
    sb.Append(arr[x, 1]);
}
var final_string = sb.ToString();

// Close workbook, close Excel...
0 голосов
/ 02 декабря 2018

Да, есть более эффективный способ.

  1. Создайте диапазон, который точно соответствует ячейкам, которые вам действительно нужны.

  2. Получить Value2 свойство этого диапазона.Результатом будет тип массива.

  3. Итерация по массиву

Проблема с вашим подходом заключается в большом количестве межпроцессных запросовмежду вашим приложением и Excel.Ваш подход требует двух или трех запросов на ячейку.Предложенный подход намного быстрее, поскольку требует нескольких предварительных запросов, но не дополнительных запросов на ячейку.

Обратите внимание, что это работает примерно до 4000 ячеек.Если вам нужно обработать больше ячеек, вам нужно разделить его на несколько диапазонов, каждый из которых содержит менее 4000 ячеек.

Обновление

Предполагается, что Excel уже работает, это будет выглядеть примерно так (правильное количество строк в столбце B выбирается автоматически):

var excelApp =  (Excel.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application");
Excel._Worksheet workSheet = (Excel.Worksheet)excelApp.ActiveSheet;
var range = (Excel.Range)workSheet.Range[workSheet.Range["B2"],
        workSheet.Range["B2"].End[Excel.XlDirection.xlDown]];
var cellData = (Object[,])range.Value2;

string result = "";
foreach (var cell in cellData) {
    result += cell.ToString();
}
...