|
Подскажите можно ли оптимизировать данный код? | ☑ | ||
---|---|---|---|---|
0
SherifSP
04.02.14
✎
19:25
|
Код выполняет запись данных в файл Excel. Строк 30000 колонок 26 - выполняется данный ужас 15 минут
КоличествоСтрок = ТаблицаПродажи.Количество(); КоличествоКолонок = ТаблицаПродажи.Колонки.Количество(); Для НомерСтроки = 0 По КоличествоСтрок -1 Цикл Для НомерКолонки = 0 По КоличествоКолонок - 1 Цикл Значение = СокрЛП(ТаблицаПродажи[НомерСтроки][НомерКолонки]); Если ЗначениеЗаполнено(Значение) Тогда Лист2.Cells(НомерСтроки + 2, НомерКолонки + 1).Value = Значение; КонецЕсли; КонецЦикла; КонецЦикла; |
|||
1
SherifSP
04.02.14
✎
19:25
|
+(0) При считывании можно было сразу массив данных считать, с записью не работал
|
|||
2
Maxus43
04.02.14
✎
19:28
|
создай-заполни табдок, сохрани его в формате эксель
|
|||
3
SherifSP
04.02.14
✎
19:30
|
(2) У меня каждый массив данных сохранялся на отдельном листе файла
|
|||
4
SherifSP
04.02.14
✎
19:31
|
Например для массива данных по контрагентам создавалась отдельная закладка контрагенты
|
|||
5
Gammi
04.02.14
✎
19:32
|
Мы сперва сливали данные в текстовый файл.
Затем одним махом затаскивали в excel и форматировали сразу все ячейки. Было значительно быстрее |
|||
6
DS
04.02.14
✎
19:33
|
Говорят, "ADODB.Connection" быстрее "Excel.Application".
|
|||
7
SherifSP
04.02.14
✎
19:37
|
(5) Во сколько раз?
|
|||
8
SherifSP
04.02.14
✎
19:39
|
На данный момент формирование файла составляет час с копейками, когда выборка данных 10 секунд, вот подумал нужно оптимизировать
|
|||
9
SherifSP
04.02.14
✎
19:40
|
Вот нашел статью, http://1cua.ucoz.ru/index/xls/0-16 - но не знаю на сколько она быстрее будит, может кто так пробовал?
|
|||
10
Torquader
05.02.14
✎
00:11
|
(6) Вопрос не в том, кто быстрее, а в том, что ADO работает как dll внутри процесса, а общение с Excel (которая exe-файл, то есть свой процесс) идёт через границы процесса, то есть через RPC и очереди сообщений.
Проблема решается элементарно, если мы пишем шаблон в VBA для Excel, который читает данные из текстового файла и по ним заполняет страницы нового документа, а со стороны 1С останется только записать в этот файл данные и вызвать Excel с шаблоном (ну и на последних версиях Excel нужно макросы подписать). |
|||
11
H A D G E H O G s
05.02.14
✎
00:20
|
Попробовать UsedRange
|
|||
12
Torquader
05.02.14
✎
00:31
|
(11) Для записи это явно лишнее.
|
|||
13
H A D G E H O G s
05.02.14
✎
00:36
|
(12) Вот я и говорю - попробовать. Я юзал только для чтения.
|
|||
14
Sorm
05.02.14
✎
00:43
|
(0) 1. Заполняй в невидимом режиме, показывай после заполнения.
2. Заполняй через Range, а не через Cell. |
|||
15
Fram
05.02.14
✎
03:59
|
(3) Сохранение табока в xls, а потом программный копи паст по листам.
|
|||
16
Fram
05.02.14
✎
04:00
|
табока = ТабДока
|
|||
17
MiniMuk
05.02.14
✎
04:58
|
У меня вопрос, а вы ексель сразу это заставляете рисовать?
чтото типа этого есть? ФайлШаблон.Application.ScreenUpdating = 0; ФайлШаблон.Application.DisplayAlerts = False; |
|||
18
Drac0
05.02.14
✎
06:21
|
(0) ComSafeArray
|
|||
19
MiniMuk
05.02.14
✎
06:37
|
(18) Можно совсем просто в буфер обмена скинуть колонки с разделителями таб. А потом ActiveSheet.Paste
|
|||
20
Drac0
05.02.14
✎
06:45
|
(19) ComSafe вроде шустрее будет и с типами данных проблем не будет. А если кидать в подготовленный шаблон, то и с форматом данных будет все ровно.
|
|||
21
Drac0
05.02.14
✎
06:55
|
А можно вообще извратиться: прямым запросом собрать данные и в этом же прямом запросе заставить их через провайдер в Excel :-)
|
|||
22
Лодырь
05.02.14
✎
07:22
|
(14) Кстати у последней версии Экселя замечено различное поведение в видимом и невидимом режимах.
|
|||
23
1Сергей
05.02.14
✎
07:26
|
(0) и эта хрень работает? с отрицательными индексами?
|
|||
24
1Сергей
05.02.14
✎
07:26
|
(23) сторно. не проснулсо ищо
|
|||
25
vde69
модератор
05.02.14
✎
08:15
|
вопрос первый - нафига это в екселе? неужели все эти данные не могут использовать в 1с?
совет как сделать быстрее в екселе создаешь макрос по записи одной строки из 28 ТЕКСТОВЫХ параметров, далее формируешь строку вызова из 1с и готово.... кстати когда я делал подобный бред я делал из 1с вызов макроса который вторым соединением подключался к 1с и полностью формировал себя, работало быстрее... |
|||
26
Drac0
05.02.14
✎
08:32
|
(25) Потребитель отчета может не иметь доступ к 1С. Ну и еще 100500 адекватных причин выгрузки данных в ексель.
|
|||
27
sapphire
05.02.14
✎
09:50
|
(26) тогда уж лучше в csv
|
|||
28
SherifSP
05.02.14
✎
10:45
|
(26) Данные перекидываются в хls и отправляются на сервер Spot2D
|
|||
29
SherifSP
05.02.14
✎
10:49
|
Остановился на таком варианте, но и тут ошибки в строке Catalog.ActiveConnection = СтрокаПодключения; Из за чего пока не выяснил
Процедура СоздатьКнигу(Кнопка) СтрокаПодключения = "Provider=Microsoft.Jet.OLEDB.4.0; |Data Source="+ИмяФайлаЭксель+"; |Extended Properties=""Excel 8.0;HDR=No;"";"; // Catalog = Новый COMОбъект("ADOX.Catalog"); Catalog.ActiveConnection = СтрокаПодключения; Table = Новый COMОбъект("ADOX.Table"); Table.Name = "Table"; Table.Columns.Append("Column1"); Table.Columns.Append("Column2"); Catalog.Tables.Append(Table); Table = Неопределено; //Catalog = Неопределено; Connection = Новый COMОбъект("ADODB.Connection"); Connection.Open(СтрокаПодключения); Command = Новый COMОбъект("ADODB.Command"); Command.ActiveConnection = Connection; Command.CommandType = 1; Запрос = Новый Запрос(" |ВЫБРАТЬ | Номенклатура.Код, | Номенклатура.Наименование |ИЗ | Справочник.Номенклатура КАК Номенклатура"); Результат = Запрос.Выполнить(); Выборка = Результат.Выбрать(); Пока Выборка.Следующий() Цикл Command.CommandText = " |INSERT INTO [Table] VALUES ('"+Выборка.Код+"','"+Выборка.Наименование+"')"; Command.Execute(); КонецЦикла; Command = Неопределено; Connection.Close(); Connection = Неопределено; КонецПроцедуры |
|||
30
SherifSP
05.02.14
✎
10:53
|
Вот сама ошибка, может кто что знает о ней?
Ошибка при установке значения атрибута контекста (ActiveConnection) Catalog.ActiveConnection = СтрокаПодключения; по причине: Произошла исключительная ситуация (Microsoft JET Database Engine): Внешняя таблица не имеет предполагаемый формат. |
|||
31
ptiz
05.02.14
✎
12:05
|
Я так делаю, заполняю ТЗ, а потом через COMSafeArray, всё летает:
МассивКОМ = Новый COMSafeArray("VT_VARIANT", ВсегоКолонокЕкселя, КолЗаписей); Для инд = 0 По ТаблицаТоваров.Количество() - 1 Цикл СтрокаТаблицы = ТаблицаТоваров[инд]; Для счКолонок = 1 По ВсегоКолонокЕкселя Цикл МассивКОМ.SetValue(счКолонок - 1, инд, СтрокаТаблицы["КолонкаОтчета" + счКолонок]); КонецЦикла; КонецЦикла; ОкноExcel.Range(ОкноExcel.Cells(НачальныйРяд,1), ОкноExcel.Cells(Ряд,ВсегоКолонокЕкселя)).Value = МассивКОМ; |
|||
32
SherifSP
05.02.14
✎
13:28
|
(31) А что значит "НачальныйРяд" - "Ряд", в последней строке кода?
|
|||
33
Drac0
05.02.14
✎
13:37
|
(31) +1
|
|||
34
SherifSP
05.02.14
✎
18:13
|
МассивКОМ = Новый COMSafeArray("VT_VARIANT", КоличествоКолонок, КоличествоСтрок);
Для инд = 0 По КоличествоСтрок - 1 Цикл СтрокаТаблицы = ТаблицаЗаказы[инд]; Для счКолонок = 1 По КоличествоКолонок - 1 Цикл МассивКОМ.SetValue(счКолонок - 1, инд, СтрокаТаблицы[счКолонок]); КонецЦикла; КонецЦикла; ЛистXls.Range(ЛистXls.Cells(1,1), ЛистXls.Cells(КоличествоСтрок,КоличествоКолонок)).Value = МассивКОМ; Перебор строк и колонок на много быстрее с этим методом но ЛистXls.Range(ЛистXls.Cells(1,1), ЛистXls.Cells(КоличествоСтрок,КоличествоКолонок)).Value = МассивКОМ; уже минут 5 выполняется, почему так? |
|||
35
SherifSP
05.02.14
✎
18:20
|
Ну чего никто не знает что ли?
|
|||
36
SherifSP
05.02.14
✎
18:33
|
300 тысч строк 10 минут и все равно висит, может что не так делаю?
|
|||
37
Torquader
05.02.14
✎
21:36
|
(36) Попробуй макрос в Excel написать и вызвать его для записи на лист, передав ему сформированный SafeArray.
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |