Имя: Пароль:
1C
1С v8
Подскажите можно ли оптимизировать данный код?
,
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.