|
Медленный экспорт в Excel | ☑ | ||
---|---|---|---|---|
0
apd123
18.11.14
✎
15:50
|
Есть регистр сведений с примерно 35К записей, его нужно экспортировать в эксель.
Делаю так: Процедура ПриОткрытииНаСервере() имяФайла = "C:\excel-export-test.xlsx"; Попытка Попытка ExcelПриложение = Новый COMОбъект("Excel.Application"); Исключение Сообщить("Ошибка при запуске Microsoft Excel." + Символы.ПС + ОписаниеОшибки(), СтатусСообщения.Внимание); Возврат; КонецПопытки; Книга = ExcelПриложение.WorkBooks.Add(); Лист = Книга.WorkSheets(1); Лист.Cells(1, 1).Value = "Заголовок 1"; // ... Лист.Cells(1, 49).Value = "Заголовок 49"; Выборка = РегистрыСведений.Данные.Выбрать(); Счетчик = 2; Пока Выборка.Следующий() Цикл ТекущаяСтрока = Выборка.ПолучитьМенеджерЗаписи(); Лист.Cells(Счетчик, 1).Value = ТекущаяСтрока.Поле1; Лист.Cells(Счетчик, 2).Value = ТекущаяСтрока.Поле2; Лист.Cells(Счетчик, 3).Value = ТекущаяСтрока.Поле3; Лист.Cells(Счетчик, 4).Value = ТекущаяСтрока.Поле4; Лист.Cells(Счетчик, 5).Value = ТекущаяСтрока.Поле5; Лист.Cells(Счетчик, 13).Value = ТекущаяСтрока.Поле13; Лист.Cells(Счетчик, 14).Value = ТекущаяСтрока.Поле14; Лист.Cells(Счетчик, 20).Value = ТекущаяСтрока.Поле20; Лист.Cells(Счетчик, 29).Value = ТекущаяСтрока.Поле29; Счетчик = Счетчик + 1; КонецЦикла; Книга.SaveAs(имяФайла); ExcelПриложение.Quit(); Сообщить("Файл выгружен успешно: " + имяФайла ); Исключение Сообщить("Ошибка записи данных файла :" + имяФайла); Сообщить(ОписаниеОшибки()); Попытка ExcelПриложение.Quit(); Исключение КонецПопытки; КонецПопытки; КонецПроцедуры Обработка выполняется полтора часа. Вот так выглядит замер производительности http://i.imgur.com/6wrs2yh.png Видно что почти все время уходит на запись значений в ячейки. При этом тип содержимого (там есть и числа и даты и строки) на скорость почти никак не влияет. На мой взгляд полтора часа это как-то дофига, учитывая что никаких расчетов не происходит, просто запись в файл, при том что итоговый экселевский файл весит примерно 2 мегабайта. Или это нормально? Если нет, то куда копать? |
|||
1
Wobland
18.11.14
✎
15:52
|
а вывести список не пробовал?
|
|||
2
sapphire
18.11.14
✎
15:52
|
(0) А табличный документ тоже сохраняет долго?
|
|||
3
Wobland
18.11.14
✎
15:53
|
> ТекущаяСтрока = Выборка.ПолучитьМенеджерЗаписи();
бохмой |
|||
4
sapphire
18.11.14
✎
15:54
|
(3) Да уж...
|
|||
5
sapphire
18.11.14
✎
15:55
|
банан долбобей нервно курит :)
|
|||
6
Wobland
18.11.14
✎
15:55
|
да какой дивный регистр. так и вспоминаются ресурсы у одного РН (остатки обуви): Размер40, Размер42...
|
|||
7
Wobland
18.11.14
✎
15:56
|
и полтора часа висит при открытии? а мне нравится
|
|||
8
13_Mult
18.11.14
✎
15:57
|
А кода "Счетчик" заканчивает считать?
|
|||
9
sapphire
18.11.14
✎
15:58
|
(7) Да это видать компания Штирлиц...
зато название РС какое "Данные" :))) |
|||
10
Wobland
18.11.14
✎
15:58
|
(8) на 94й минуте матча
|
|||
11
Wobland
18.11.14
✎
15:59
|
+(9) поле. русское поооле...
|
|||
12
sapphire
18.11.14
✎
16:00
|
Да и исчо это фсио на сервере....
|
|||
13
13_Mult
18.11.14
✎
16:01
|
Началась, дискотека
|
|||
14
Wobland
18.11.14
✎
16:02
|
ну ладно, поправим автора ;)
Видно что почти все время уходит на чтение значений |
|||
15
H A D G E H O G s
18.11.14
✎
16:04
|
(14) Замер смотрел?
|
|||
16
sapphire
18.11.14
✎
16:05
|
(0) Автор, а чё запросом-то через табличный документ низьзя никак?
|
|||
17
Wobland
18.11.14
✎
16:05
|
(15) даже не поленился
http://i.imgur.com/6wrs2yh.png |
|||
18
sapphire
18.11.14
✎
16:05
|
(15) посмотрел и замер :)
|
|||
19
H A D G E H O G s
18.11.14
✎
16:05
|
Все время уходит на вывод в ячейку Excel.
Не используйте Excel через COM |
|||
20
sapphire
18.11.14
✎
16:06
|
(19) Откуда ты знаешь? Может на чтение записи :)
|
|||
21
Kalambur
18.11.14
✎
16:08
|
(17) ну ты зверюга ))))
|
|||
22
MM
18.11.14
✎
16:08
|
Делаю ставку, что тормозит обращение к OLE-объектам Excel. Но и чтение из БД сделано отвратительно.
Почему бы не сделать отчёт,а потом его сохранить в Excel? Тем более что формат 2007 уже встроен в платформу и нет проблемы с 65500 строк на листе. |
|||
23
apd123
18.11.14
✎
16:10
|
(3) И что? Надо было запросом? А смысл? Тормозит не в этом месте.
(8) Заканчивает когда заканчиваются записи. Не понял вопрос. Да и проблема явно не в этом. (16) Попробую. (19) А как его использовать? Для особо умных трололо: 1) Названия полей я естественно поменял, на самом деле они называются по-другому. 2) РС таки называется "Данные". Не поверите, но бывают ситуации в которых это действительно самое подходящее и удобное название. |
|||
24
Кирпич
18.11.14
✎
16:13
|
Вариантов много разных. Например, можно всё загнать в текст, скопировать текст в буфер обмена и вставить в Excel из буфера.
|
|||
25
Kalambur
18.11.14
✎
16:13
|
((19)(22)(23) ПолучитьМенеджерЗаписи
"Предназначен для интерактивной работы с записью регистра сведений." |
|||
26
Kalambur
18.11.14
✎
16:14
|
(23) пиши нормальный код и все будет быстро
|
|||
27
sapphire
18.11.14
✎
16:14
|
(23) см (17)
тебе показали, где тормозит. |
|||
28
КонецЦикла
18.11.14
✎
16:16
|
Запороцем само быстро вроде, ADOX.Catalog
|
|||
29
H A D G E H O G s
18.11.14
✎
16:18
|
(23) Используй правильно:
МассивДанных=Новый COMSafeArray("VT_VARIANT",КоличествоСтрок-1,КоличествоСтолбцов-1); Для СчетчикСтрок=0 По КоличествоСтрок-1 Цикл МассивДанных.SetValue(СчетчикСтрок,0,ТекущаяСтрока.Идентификатор); МассивДанных.SetValue(СчетчикСтрок,1,ТекущаяСтрока.Цена); //и.т.д, все колонки КонецЦикла; ВерхняяЛеваяЯчейка= WorkBook.WorkSheets[1].Cells[НачальнаяСтрока, НачальнаяКолонка]; НижняяПраваяЯчейка= WorkBook.WorkSheets[1].Cells[НачальнаяСтрока+КоличествоСтрок-1, НачальнаяКолонка+КоличествоСтолбцов-1]; Область= WorkBook.WorkSheets[1].Range[ВерхняяЛеваяЯчейка, НижняяПраваяЯчейка]; Область.Value= МассивДанных; |
|||
30
MM
18.11.14
✎
16:18
|
(25) Доступность: Сервер, толстый клиент, внешнее соединение.
Тонкого клиента в списке нет, странная интерактивность. В (17) показали , что затык на Лист.Cells(х, у).Value, это минимум 3 обращения к внепроцессному COM-серверу, с маршалингом и всеми прелестями OLE. |
|||
31
H A D G E H O G s
18.11.14
✎
16:19
|
Ну и данные, естественно - запросом, чтобы знать число строк.
|
|||
32
Kalambur
18.11.14
✎
16:22
|
(30) ну я с СП спорить точно не буду
|
|||
33
apd123
18.11.14
✎
18:00
|
(29) (31) Огромное спасибо! С использованием COMSafeArray время экспорта удалось уменьшить до 32 секунд :) http://i.imgur.com/y4Mv6FA.png
Вот какой код получился в итоге: Процедура ПриОткрытииНаСервере() имяФайла = "C:\excel-export-test.xlsx"; Попытка Попытка ExcelПриложение = Новый COMОбъект("Excel.Application"); Исключение Сообщить("Ошибка при запуске Microsoft Excel." + Символы.ПС + ОписаниеОшибки(), СтатусСообщения.Внимание); Возврат; КонецПопытки; Книга = ExcelПриложение.WorkBooks.Add(); Лист = Книга.WorkSheets(1); Лист.Cells(1, 1).Value = "Заголовок 1"; // ... Лист.Cells(1, 49).Value = "Заголовок 49"; Запрос = Новый Запрос("ВЫБРАТЬ | .... | ИЗ РегистрСведений.Данные"); Выборка = Запрос.Выполнить().Выбрать(); КоличествоСтрок = Выборка.Количество(); КоличествоСтолбцов = 50; МассивДанных = Новый COMSafeArray("VT_VARIANT",КоличествоСтолбцов-1, КоличествоСтрок); Счетчик = 0; Пока Выборка.Следующий() Цикл МассивДанных.SetValue(0, Счетчик, Выборка.Поле1); МассивДанных.SetValue(1, Счетчик, Выборка.Поле2); МассивДанных.SetValue(2, Счетчик, Выборка.Поле3); МассивДанных.SetValue(3, Счетчик, Выборка.Поле4); МассивДанных.SetValue(4, Счетчик, Выборка.Поле5); МассивДанных.SetValue(12, Счетчик, Выборка.Поле6); МассивДанных.SetValue(13, Счетчик, Выборка.Поле7); МассивДанных.SetValue(19, Счетчик, Выборка.Поле8); МассивДанных.SetValue(28, Счетчик, Выборка.Поле9); Счетчик = Счетчик + 1; КонецЦикла; Область = Лист.Range(Лист.Cells(2, 1), Лист.Cells(КоличествоСтрок+1, КоличествоСтолбцов-1)); Область.Value = МассивДанных; ExcelПриложение.DisplayAlerts = False; Книга.SaveAs(имяФайла); ExcelПриложение.Quit(); Сообщить("Файл выгружен успешно: " + имяФайла); Исключение Сообщить("Ошибка записи данных файла :" + имяФайла); Сообщить(ОписаниеОшибки()); Попытка ExcelПриложение.Quit(); Исключение КонецПопытки; КонецПопытки; КонецПроцедуры |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |