Скорость обработки Excel таблицы.
От: _Michail Украина  
Дата: 20.04.05 06:34
Оценка:
Привет Всем!

Есть веб проект, все что он делает, это открывает Excel Application, некую таблицу, и проходит по строкам, столбцам, начитывает ячейки.
Область размером 25x20, т.е. 500 ячеек, он обрабатывает около 30 сек, что по моему, очень много, думаю что обращаюсь к Excel "как то не так". Мой комп Celeron 1.7Ghz, 512Mb. Код приведен ниже, подскажите плиз, в чем моя вина?

Excel.Application excel = new Excel.Application();
excel.Visible = false;
Excel.Workbook workbook =
excel.Workbooks.Open(
path,
Type.Missing,
Type.Missing,
Type.Missing,
Type.Missing,
Type.Missing,
Type.Missing,
Type.Missing,
Type.Missing,
Type.Missing,
Type.Missing,
Type.Missing,
Type.Missing,
Type.Missing,
Type.Missing
);

Excel.Worksheet shit = (Excel.Worksheet)workbook.Worksheets.get_Item(1);
excel.ScreenUpdating = false;

for(int i = 1; i < 25; i++)
{
for(int j = 1; j < 20; j++)
{
TableCell cell = new TableCell();
Excel.Range myExcelCell = ((Excel.Range)shit.Cells[i,j]);
//Тут еще есть запись в файл, но на скорость она особо не влияет, проверял.
}
}
excel.ScreenUpdating = true;

Marshal.ReleaseComObject(shit);
shit = null;
Marshal.ReleaseComObject(workbook);
workbook = null;
excel.DisplayAlerts = false;
excel.Quit();
Marshal.ReleaseComObject(excel);
excel = null;
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
Re: Скорость обработки Excel таблицы.
От: alsadykov  
Дата: 20.04.05 06:48
Оценка:
Здравствуйте, _Michail, Вы писали:


Навскидку пара вариантов:
1. Открываешь книгу, в книге в какой-либо ячейке записываешь суммирующую формулу, считываешь значение из этой ячейки, закрываешь без сохранения.
2. Использовать не два цикла, а определить Range и бежать по нему циклом for each. Может будет побыстрее.
Re[2]: Скорость обработки Excel таблицы.
От: _Michail Украина  
Дата: 20.04.05 07:01
Оценка:
Здравствуйте, alsadykov, Вы писали:


По поводу певого варианта, не совсем понял...
Можно поподробнее?
Зараннее — спасибо!

A>Здравствуйте, _Michail, Вы писали:



A>Навскидку пара вариантов:

A>1. Открываешь книгу, в книге в какой-либо ячейке записываешь суммирующую формулу, считываешь значение из этой ячейки, закрываешь без сохранения.
A>2. Использовать не два цикла, а определить Range и бежать по нему циклом for each. Может будет побыстрее.
Re[3]: Скорость обработки Excel таблицы.
От: alsadykov  
Дата: 20.04.05 07:11
Оценка:
Здравствуйте, _Michail, Вы писали:

_M>Здравствуйте, alsadykov, Вы писали:



_M>По поводу певого варианта, не совсем понял...

_M>Можно поподробнее?
_M>Зараннее — спасибо!

По поводу первого варианта я немного поторопился — он годится только если тебе надо чего-то подсчитать. В этом случае в некую ячейку вставляешь не число или текст, а формулу типа =СУММ(F34:G40) (ну или какую-надо функцию, их там как у дурачка фантиков). Причем формула задается через свойство formulaR1C1: Worksheets("Sheet1").Range("B1").FormulaR1C1 = "=SQRT(R1C1)"
Re[4]: Скорость обработки Excel таблицы.
От: _Michail Украина  
Дата: 20.04.05 07:52
Оценка:
Здравствуйте, alsadykov, Вы писали:

Ок, спасибо, пока попробую второй.

A>Здравствуйте, _Michail, Вы писали:


_M>>Здравствуйте, alsadykov, Вы писали:



_M>>По поводу певого варианта, не совсем понял...

_M>>Можно поподробнее?
_M>>Зараннее — спасибо!

A>По поводу первого варианта я немного поторопился — он годится только если тебе надо чего-то подсчитать. В этом случае в некую ячейку вставляешь не число или текст, а формулу типа =СУММ(F34:G40) (ну или какую-надо функцию, их там как у дурачка фантиков). Причем формула задается через свойство formulaR1C1: Worksheets("Sheet1").Range("B1").FormulaR1C1 = "=SQRT(R1C1)"
Re[2]: Скорость обработки Excel таблицы.
От: _Michail Украина  
Дата: 20.04.05 11:28
Оценка:
Здравствуйте, alsadykov, Вы писали:

Можешь дать маленький пример по второму варианту?

A>Здравствуйте, _Michail, Вы писали:



A>Навскидку пара вариантов:

A>1. Открываешь книгу, в книге в какой-либо ячейке записываешь суммирующую формулу, считываешь значение из этой ячейки, закрываешь без сохранения.
A>2. Использовать не два цикла, а определить Range и бежать по нему циклом for each. Может будет побыстрее.
Re: Скорость обработки Excel таблицы.
От: EM Великобритания  
Дата: 20.04.05 11:39
Оценка:
Здравствуйте, _Michail, Вы писали:

_M>Привет Всем!


_M>Есть веб проект, все что он делает, это открывает Excel Application, некую таблицу, и проходит по строкам, столбцам, начитывает ячейки.

_M>Область размером 25x20, т.е. 500 ячеек, он обрабатывает около 30 сек, что по моему, очень много, думаю что обращаюсь к Excel "как то не так". Мой комп Celeron 1.7Ghz, 512Mb. Код приведен ниже, подскажите плиз, в чем моя вина?



Если тебе критична скорость, забери данные через clipboard — все будет летать.
Опыт — это такая вещь, которая появляется сразу после того, как была нужна...
Re[2]: Скорость обработки Excel таблицы.
От: _Michail Украина  
Дата: 20.04.05 11:47
Оценка:
Здравствуйте, EM, Вы писали:


Скорость критична.
Можешь дать маленький екзампл, как забрать данные через clipboard, и как потом пробежаться по ячейкам?
Заранее — спасибо!

EM>Здравствуйте, _Michail, Вы писали:


_M>>Привет Всем!


_M>>Есть веб проект, все что он делает, это открывает Excel Application, некую таблицу, и проходит по строкам, столбцам, начитывает ячейки.

_M>>Область размером 25x20, т.е. 500 ячеек, он обрабатывает около 30 сек, что по моему, очень много, думаю что обращаюсь к Excel "как то не так". Мой комп Celeron 1.7Ghz, 512Mb. Код приведен ниже, подскажите плиз, в чем моя вина?



EM>Если тебе критична скорость, забери данные через clipboard — все будет летать.
Re[3]: Скорость обработки Excel таблицы.
От: Хитрик Денис Россия RSDN
Дата: 20.04.05 11:49
Оценка:
Здравствуйте, _Michail, Вы писали:

Михаил, на этом форуме принято удалять лишние цитаты.
Правила нашего с вами форума.
Как правильно задавать вопросы. © 2001 by Eric S. Raymond; перевод: © 2002 Валерий Кравчук.
Re: Скорость обработки Excel таблицы.
От: Chupa_Kabra  
Дата: 20.04.05 12:07
Оценка:
Нужно вместо shit.Cells[i,j]); выделить Range и получить у него значение, будет массив
Все хотят хорошо провести время, но время не проведешь !
Re[2]: Скорость обработки Excel таблицы.
От: _Michail Украина  
Дата: 20.04.05 12:23
Оценка:
Здравствуйте, Chupa_Kabra,

Попробовал, все равно тормозит(жу), пример:

Excel.Range myExcelCellRange = ((Excel.Range)shit.get_Range(excel.Cells[1, 1], excel.Cells[25, 10]));
for(int i = 1; i < 25; i++)
{
TableRow row = new TableRow();
for(int j = 1; j < 10; j++)
{
TableCell cell = new TableCell();
Excel.Range myExcelCell = (Excel.Range)myExcelCellRange.Cells[i, j];
cell.Text = myExcelCell.Text.ToString();
... и т.д.

Как правильно взять Range?
Re: Скорость обработки Excel таблицы.
От: _Michail Украина  
Дата: 20.04.05 12:57
Оценка:
Привет Всем,

Тот же вопрос, немного с другой стороны, Excel это область неуправляемого кода,
есть ли возможность перенести часть ее(диапазон ячеек), на нашу сторону, т.е. в массив скажем?
Re[3]: Скорость обработки Excel таблицы.
От: EM Великобритания  
Дата: 20.04.05 13:41
Оценка: +1
Здравствуйте, _Michail, Вы писали:

_M>Здравствуйте, Chupa_Kabra,


_M>Попробовал, все равно тормозит(жу), пример:


Перепиши это макросом на VBA и дергай его — будет быстрее на порядок — основная причина тормозов в оффисной автоматизации — outproc вызовы
Опыт — это такая вещь, которая появляется сразу после того, как была нужна...
Re[3]: Скорость обработки Excel таблицы.
От: Chupa_Kabra  
Дата: 21.04.05 02:39
Оценка:
Здравствуйте, _Michail, Вы писали:

_M>Здравствуйте, Chupa_Kabra,


_M>Попробовал, все равно тормозит(жу), пример:


_M>Excel.Range myExcelCellRange = ((Excel.Range)shit.get_Range(excel.Cells[1, 1], excel.Cells[25, 10]));

_M>for(int i = 1; i < 25; i++)
_M>{
_M> TableRow row = new TableRow();
_M> for(int j = 1; j < 10; j++)
_M> {
_M> TableCell cell = new TableCell();
_M> Excel.Range myExcelCell = (Excel.Range)myExcelCellRange.Cells[i, j];
_M> cell.Text = myExcelCell.Text.ToString();
_M>... и т.д.

Ну это же НЕ ТО!


(object[,])((Excel.Range)shit.get_Range(excel.Cells[1, 1], excel.Cells[25, 10])).Value2


_M>Как правильно взять Range?

по имени или диапазону ...
Все хотят хорошо провести время, но время не проведешь !
Re[4]: Скорость обработки Excel таблицы.
От: _Michail Украина  
Дата: 21.04.05 06:35
Оценка:
Здравствуйте, Chupa_Kabra, Вы писали:

C_K>
C_K>(object[,])((Excel.Range)shit.get_Range(excel.Cells[1, 1], excel.Cells[25, 10])).Value2
C_K>


В этом случае я имею только массив Value2, мне еще нужну знать Text, формат ячейки, бордюры и т.д.
Если я делаю
(object[,])((Excel.Range)shit.get_Range(excel.Cells[1, 1], excel.Cells[25, 10])).Text к примеру, валиться
System.InvalidCastException: Specified cast is not valid.

Что то можно кроме Value2 взять?
Re[5]: Скорость обработки Excel таблицы.
От: Chupa_Kabra  
Дата: 21.04.05 07:14
Оценка:
Здравствуйте, _Michail, Вы писали:

_M>Здравствуйте, Chupa_Kabra, Вы писали:


_M>В этом случае я имею только массив Value2, мне еще нужну знать Text, формат ячейки, бордюры и т.д.

_M>Если я делаю
_M>(object[,])((Excel.Range)shit.get_Range(excel.Cells[1, 1], excel.Cells[25, 10])).Text к примеру, валиться
_M>System.InvalidCastException: Specified cast is not valid.
Ах, дак вам еще и форматирование нужно ... Можно попробовать по аналогии, но с этим я не возился.
А валится у вас совершенно правильно, с какого перепуга вы дергаете свойство Text ?
Это массив элементов, один раз его получили, потом делайте свой вложенный цикл и обращайтесь не через interop, а к этому массиву, по скорости разница существенная.
Все хотят хорошо провести время, но время не проведешь !
Re[6]: Скорость обработки Excel таблицы.
От: _Michail Украина  
Дата: 21.04.05 07:31
Оценка:
Здравствуйте, Chupa_Kabra, Вы писали:

C_K>Ах, дак вам еще и форматирование нужно ... Можно попробовать по аналогии, но с этим я не возился.

C_K>А валится у вас совершенно правильно, с какого перепуга вы дергаете свойство Text ?
C_K>Это массив элементов, один раз его получили, потом делайте свой вложенный цикл и обращайтесь не через interop, а к этому массиву, по скорости разница существенная.

Мне нужно иметь доступ ко всем свойствам ячеки, те что предоставлят Excel.Range, с вариантом Value2 все работает чудесно и быстро, так же кроме Value2 работает FormulaXXXX, но это по моему все...
Почему нельзя получить в свой локальный массив или переменную, Range? И обращяться к этому массиву?

Вся задача то сводиться к тому, что нужно БЫСТРО пробежаться по диапазону ячеек, и полчуть 5-6 свойств, ну не верю я что это невозможно!
Re[7]: Скорость обработки Excel таблицы.
От: Chupa_Kabra  
Дата: 21.04.05 07:35
Оценка:
Здравствуйте, _Michail, Вы писали:

_M>Здравствуйте, Chupa_Kabra, Вы писали:


C_K>>Ах, дак вам еще и форматирование нужно ... Можно попробовать по аналогии, но с этим я не возился.

C_K>>А валится у вас совершенно правильно, с какого перепуга вы дергаете свойство Text ?
C_K>>Это массив элементов, один раз его получили, потом делайте свой вложенный цикл и обращайтесь не через interop, а к этому массиву, по скорости разница существенная.

_M>Мне нужно иметь доступ ко всем свойствам ячеки, те что предоставлят Excel.Range, с вариантом Value2 все работает чудесно и быстро, так же кроме Value2 работает FormulaXXXX, но это по моему все...

_M>Почему нельзя получить в свой локальный массив или переменную, Range? И обращяться к этому массиву?

_M>Вся задача то сводиться к тому, что нужно БЫСТРО пробежаться по диапазону ячеек, и полчуть 5-6 свойств, ну не верю я что это невозможно!

Просто основная идея была минимизировать число обращений к екселю.
На крайний случай попробуйте foreach вызвать. Возможно перебор ячеек будет делаться быстрее, хотя опыт работы с экселем показывает, что достоверно не знаешь, где найдешь где потеряешь
Все хотят хорошо провести время, но время не проведешь !
Скорость обработки Excel таблицы.
От: Аноним  
Дата: 20.04.05 07:13
Оценка:
Можно получить нужный Excel.Range, где хранятся данные, и взять у него Value2, в котором будет object[,] с данными. Это гораздо быстрее чем бегать по отдельным ячейкам.


данное сообщение получено с www.gotdotnet.ru
ссылка на оригинальное сообщение
Re: Скорость обработки Excel таблицы.
От: Аноним  
Дата: 20.04.05 13:35
Оценка:
>Тот же вопрос, немного с другой стороны, Excel это область неуправляемого кода,
есть ли возможность перенести часть ее(диапазон ячеек), на нашу сторону, т.е. в массив скажем?


Так Вам же говорят — возьмите Range и у него в Value2 будет массив object[,]


данное сообщение получено с www.gotdotnet.ru
ссылка на оригинальное сообщение
Re[5]: Скорость обработки Excel таблицы.
От: v0l0d  
Дата: 16.11.05 01:43
Оценка:
Здравствуйте, _Michail, Вы писали:

_M>Здравствуйте, Chupa_Kabra, Вы писали:


C_K>>
C_K>>(object[,])((Excel.Range)shit.get_Range(excel.Cells[1, 1], excel.Cells[25, 10])).Value2
C_K>>


_M>В этом случае я имею только массив Value2, мне еще нужну знать Text, формат ячейки, бордюры и т.д.

_M>Если я делаю
_M>(object[,])((Excel.Range)shit.get_Range(excel.Cells[1, 1], excel.Cells[25, 10])).Text к примеру, валиться
_M>System.InvalidCastException: Specified cast is not valid.

_M>Что то можно кроме Value2 взять?

Вы не подскажете мне как получить из Value2 дату, а не double?
У меня в ячейке стоит дата, но когда я получаю значение через Value2, то результатом является double (
Огромное спасибо.
Владимир.
Re: Скорость обработки Excel таблицы.
От: Andrbig  
Дата: 16.11.05 08:29
Оценка:
Здравствуйте, _Michail, Вы писали:

_M>Excel.Worksheet shit = (Excel.Worksheet)workbook.Worksheets.get_Item(1);

_M>excel.ScreenUpdating = false;

_M>for(int i = 1; i < 25; i++)

_M>{
_M> for(int j = 1; j < 20; j++)
_M> {
_M> TableCell cell = new TableCell();
_M> Excel.Range myExcelCell = ((Excel.Range)shit.Cells[i,j]);
_M> //Тут еще есть запись в файл, но на скорость она особо не влияет, проверял.
_M> }
_M>}
_M>excel.ScreenUpdating = true;

_M>Marshal.ReleaseComObject(shit);

_M>shit = null;
_M>Marshal.ReleaseComObject(workbook);
_M>workbook = null;
_M>excel.DisplayAlerts = false;
_M>excel.Quit();
_M>Marshal.ReleaseComObject(excel);
_M>excel = null;
_M>GC.Collect();
_M>GC.WaitForPendingFinalizers();
_M>GC.Collect();



За последние три строки руки оторвать надо.
Re[2]: Скорость обработки Excel таблицы.
От: IDecember Россия  
Дата: 16.11.05 08:39
Оценка:
Здравствуйте, Andrbig, Вы писали:

_M>>GC.Collect();

_M>>GC.WaitForPendingFinalizers();
_M>>GC.Collect();


A>За последние три строки руки оторвать надо.


Кстати, а почему? Тоже встречал такой код, но не понял, зачем его используют.
Re[3]: Скорость обработки Excel таблицы.
От: TK Лес кывт.рф
Дата: 16.11.05 09:37
Оценка:
Hello, "IDecember"
>
> Кстати, а почему? Тоже встречал такой код, но не понял, зачем его
> используют.

В некоторых случаях (особенно при работе с ActiveX/COM) проще запустить
явную сборку мусора чем, париться с учетом всех используемых ресурсов.
Например, Windows.Forms в некоторых случаях так делает. в целом, для
клиетского процесса принудительный запуск сборщика мусора это не такая уж и
страшная вещь (если, не увлекаться).

Так же, в некоторых случаях без обращения к сборщику мусора тоже тяжело
обойтись:
PRB: The Garbage Collector Does Not Release a COM Object That Handles
Events as You Expect

PRB: Managed Object Is Not Garbage Collected When the Managed Object
Handles an Event for an Unmanaged (COM) Object

BUG: The XmlValidatingReader Class Does Not Close the Stream When the XML
Document References a DTD That Has Errors


Что касается примера из оригинального топика то, в случае использования
Excel в клиентском приложении
GC.Collect();GC.WaitForPendingFinalizers(); это вполне адекватное
решение (достаточно посмотреть для скольких объектов там не сделан
Marshal.ReleaseComObject и выбрать что будет проще — отслеживать все самому
либо, один раз вызвать сборщик мусора).

Конечно, можно для дополнительной красоты решения вынести сборку мусора в
отдельный класс тогда, сборка мусора будет не так сильно бросаться в глаза.
Posted via RSDN NNTP Server 2.0 beta
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[2]: Скорость обработки Excel таблицы.
От: Аноним  
Дата: 16.11.05 09:31
Оценка:
>Кстати, а почему? Тоже встречал такой код, но не понял, зачем его используют.

Потому что без него excel.exe остается висеть в памяти. А многих это беспокоит. Вот пример:

Excel.Application xl = new Excel.ApplicationClass();
Excel.Workbook wb = xl.Workbooks.Add(Excel.XlWBATemplate.xlWBATWorksheet);
xl.Quit();
Marshal.ReleaseComObject(wb);
Marshal.ReleaseComObject(xl);
//GC.Collect();

Вроде все правильно освобождается, а процесс висит после выхода из метода. Если убрать комментарий — пропадает.


данное сообщение получено с www.gotdotnet.ru
ссылка на оригинальное сообщение
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.