Имя: Пароль:
1C
 
Загрузить из Excell. Оптимизация.
0 lamme
 
19.10.07
09:56
Пользуюсь такой структурой:
обЭксел  = Новый ComОбъект("excel.application");
ОбЭксел.WorkBooks.close(); // закрываем файл- экселя
НашФайл = обЭксел.Workbooks.Open(СокрЛП(ИмяФ)); //Открываем файл
НашЛист = НашФайл.Sheets(1); //Устанавливаем нужный лист  - лист №1
LastRow = обЭксел.Cells(1,1).SpecialCells(11).Row; // количество
   Для i = 2 По LastRow Цикл // начиная со строки =2 и по ....
       Если ПустаяСтрока (НашЛист.Cells(i, 1).Value) =1 тогда
           Продолжить ;
       конецесли ;


и тд и тп
А теперь ситуевина:
есть ексель с 6 колонками и 22 тыщ строк
Есть докуемнт - в который надо загрзить все жти 6 колонок.
Каждая колонка - имеет тип -справочник. Либо создаеться новый либо вставляеться что-то найденное.
---
Вопрос.
У меня 22 тыщ строк обрабатываеться 15-18 минут.
Как можно оптимизировать ?
1 artem666
 
19.10.07
09:58
ADOB вроде поможет
2 artem666
 
19.10.07
09:58
на скока слышал
3 artem666
 
19.10.07
09:58
сам не пользовался
4 lamme
 
19.10.07
10:00
а как нибудь с примером можно ?
или ссылку ?
и вообще - оно что - всегда так долго ?
- процедура простая -загрузить все строки в док, создавая новый элемент определенного справочника или вставляя найденный.
5 Zholty
 
19.10.07
10:09
процедура то простая, только данных много
6 Zholty
 
19.10.07
10:13
а что дальше в коде?
7 lamme
 
19.10.07
10:13
(5)
это точно ...
в этом собтвенно и вопрос то был .. как ускорить все это безобразие ?
8 lamme
 
19.10.07
10:14
ну типа вот весь код
---------

обЭксел  = Новый ComОбъект("excel.application");
ОбЭксел.WorkBooks.close(); // закрываем файл- экселя
НашФайл = обЭксел.Workbooks.Open(СокрЛП(ИмяФ)); //Открываем файл
НашЛист = НашФайл.Sheets(1); //Устанавливаем нужный лист  - лист №1
LastRow = обЭксел.Cells(1,1).SpecialCells(11).Row; // количество строк с .. по последнюю
Сотрудник = Справочники.Сотрудники;
НомерПартии = Справочники.ПроизводственныеРаботы_Партии;
   Для i = 2 По LastRow Цикл // начиная со строки =2 и по ....
       Если ПустаяСтрока (НашЛист.Cells(i, 1).Value) =1 тогда
           Продолжить ;
       конецесли ;
           
           НоваяСтрока = НовыйДок.ТабличнаяЧасть1.Добавить();
           НоваяСтрока.ШК = Сокрлп(НашЛист.Cells(i, 1).Value);
           состояние(сокрлп(i)+"/"+сокрлп(LastRow)+"."+НоваяСтрока.ШК);
           Если НашЛист.Cells(i, 2).Value="A" тогда
               НоваяСтрока.ТипТовара  = Перечисления.ТипыТоваровПриПроизводственныхРаботах.A;
           ИначеЕсли НашЛист.Cells(i, 2).Value="B" тогда    
               НоваяСтрока.ТипТовара  = Перечисления.ТипыТоваровПриПроизводственныхРаботах.B;
           ИначеЕсли НашЛист.Cells(i, 2).Value="C" тогда    
               НоваяСтрока.ТипТовара  = Перечисления.ТипыТоваровПриПроизводственныхРаботах.C;
           ИначеЕсли НашЛист.Cells(i, 2).Value="D" тогда    
               НоваяСтрока.ТипТовара  = Перечисления.ТипыТоваровПриПроизводственныхРаботах.D;
           ИначеЕсли НашЛист.Cells(i, 2).Value="E" тогда        
               НоваяСтрока.ТипТовара  = Перечисления.ТипыТоваровПриПроизводственныхРаботах.E;
           конецесли;
           
           КодПартии = Сокрлп(НашЛист.Cells(i, 3).Value);
           ДатаПартии = Дата(НашЛист.Cells(i, 5).Value);
           
           
           НайденнаяСсылка3 = НомерПартии.НайтиПоКоду (КодПартии);
           Если НайденнаяСсылка3 = НомерПартии.ПустаяСсылка() Тогда // Создаем новый ЭлементСправочника
               НоваяСтрока.Партия = СоздатьНовуюПартию(КодПартии,ДатаПартии);
           Иначе
               НоваяСтрока.Партия= НайденнаяСсылка3;
           конецесли;
           НоваяСтрока.ДатаОперации = ДатаПартии;

           КодСотрудника  = Сокрлп(НашЛист.Cells(i, 4).Value);
           НайденнаяСсылка2 = Сотрудник.НайтиПоКоду (КодСотрудника);
           Если НайденнаяСсылка2 = Сотрудник.ПустаяСсылка() Тогда // Создаем новый ЭлементСправочника
           Иначе
               НоваяСтрока.Сотрудник = НайденнаяСсылка2;
           конецесли;    
           
           Если НашЛист.Cells(i, 6).Value="1" тогда        
               НоваяСтрока.ТипОперации =  перечисления.ТипДвиженияПроизводственныхРабот.Продажа;
               НоваяСтрока.Количество = 1;
               
           Иначеесли    НашЛист.Cells(i, 6).Value="0" тогда        
               НоваяСтрока.ТипОперации =  перечисления.ТипДвиженияПроизводственныхРабот.Возврат;
               НоваяСтрока.Количество = -1;
           конецесли;    
               
       конеццикла;    
   ОбЭксел.WorkBooks.close(); // закрываем файл- экселя
   ОбЭксел.Quit(); // закрываем сам эксель
   ОбЭксел = "";
   НашФайл = "";
   НашЛист = "";
   LastRow = "";
   НовыйДок.Записать(РежимЗаписиДокумента.Проведение);
9 Всеяд
 
19.10.07
10:19
Я думаю, что на оптимизации чтения Excel ты много времени не сэкономишь - львиная доля времени всё равно тратится на запись объектов.
10 Zholty
 
19.10.07
10:20
вместо
           Если НашЛист.Cells(i, 2).Value="A" тогда
               НоваяСтрока.ТипТовара  = Перечисления.ТипыТоваровПриПроизводственныхРаботах.A;
           ИначеЕсли НашЛист.Cells(i, 2).Value="B" тогда    
               НоваяСтрока.ТипТовара  = Перечисления.ТипыТоваровПриПроизводственныхРаботах.B;
           ИначеЕсли НашЛист.Cells(i, 2).Value="C" тогда    
               НоваяСтрока.ТипТовара  = Перечисления.ТипыТоваровПриПроизводственныхРаботах.C;
           ИначеЕсли НашЛист.Cells(i, 2).Value="D" тогда    
               НоваяСтрока.ТипТовара  = Перечисления.ТипыТоваровПриПроизводственныхРаботах.D;
           ИначеЕсли НашЛист.Cells(i, 2).Value="E" тогда        
               НоваяСтрока.ТипТовара  = Перечисления.ТипыТоваровПриПроизводственныхРаботах.E;
           конецесли;
попробуй:
 перем = НашЛист.Cells(i, 2).Value;
           Если перем ="A" тогда
               НоваяСтрока.ТипТовара  = Перечисления.ТипыТоваровПриПроизводственныхРаботах.A;
           ИначеЕсли перем ="B" тогда    
               НоваяСтрока.ТипТовара  = Перечисления.ТипыТоваровПриПроизводственныхРаботах.B;
           ИначеЕсли перем ="C" тогда    
               НоваяСтрока.ТипТовара  = Перечисления.ТипыТоваровПриПроизводственныхРаботах.C;
           ИначеЕсли перем ="D" тогда    
               НоваяСтрока.ТипТовара  = Перечисления.ТипыТоваровПриПроизводственныхРаботах.D;
           ИначеЕсли перем ="E" тогда        
               НоваяСтрока.ТипТовара  = Перечисления.ТипыТоваровПриПроизводственныхРаботах.E;
           конецесли;

по идее будет чуть-чуть быстрее
11 manyak
 
19.10.07
10:23
попробуй -может ускорить чуть-чуть:
В начале загрузки поставь:
ОбЭксел.ScreenUpdating = false
в конце загрузки:
ОбЭксел.ScreenUpdating = true
12 smaharbA
 
19.10.07
10:25
ИспользуемыйДиапазон=Лист.UsedRange;
ДанныеИзЕкселя=ИспользуемыйДиапазон.Value;
13 Bolid7116
 
19.10.07
10:26
а ёксель нельзя перегнать в DBF средствами ёкселя, а затем загружай...
14 lamme
 
19.10.07
10:27
(11)
это что ? если не секрет
15 smaharbA
 
19.10.07
10:28
(11) это он тупит
16 lamme
 
19.10.07
10:28
11
12
может в секундах и есть убыстрение
пока не заметно ... :(
13 - это что и зачем ?
17 Aloex
 
19.10.07
10:28
Для ускорения вывода информации в Excel можно отключить обновление экрана.

   xl.ScreenUpdating = 0;
   xl.EnableEvents = 0;
   xl.Visible = 0;


Затем, когда таблица будет сформирована, вновь включить обновление экрана.

   xl.ScreenUpdating = 1;
   xl.EnableEvents = 1;
   xl.Visible = 1;
18 smaharbA
 
19.10.07
10:28
(15) -> (14)
19 smaharbA
 
19.10.07
10:29
(17) чем это поможет для (0) ?
20 smaharbA
 
19.10.07
10:30
(16) смотри (12) внимательнее
21 Aloex
 
19.10.07
10:30
Если читать через ADO будет быстрее??
22 Zholty
 
19.10.07
10:30
(17) не нада в Ёксель, надо обратно
23 Всеяд
 
19.10.07
10:30
(17) Так объект получается изначально с Visible = False, если мне память не изменяет...
24 Bolid7116
 
19.10.07
10:30
(16) в смысле что и зачем. DBF это не com и не тем более Ole объект, он грузиться быстро, гораздо быстрее. А ёксель сохраняет данные в DBF
25 Aloex
 
19.10.07
10:30
(19) пусть ставит, лишним не будет.
26 Zholty
 
19.10.07
10:31
(21) а (0) через что читает?
27 smaharbA
 
19.10.07
10:31
(21) в общем случае (как все делают) - да
если делать правильно то ОЛЕ быстрее будет
28 lamme
 
19.10.07
10:31
(20)
смотрю
применяю ...
пока не допер ...
покажи пример ?
29 Aloex
 
19.10.07
10:32
(26) db=CreateObject("ADODB.Connection");
30 smaharbA
 
19.10.07
10:33
(28) потом
Для каждого из
либо по строкам полученного массива
...
ДанныеИзЕкселя - в (12) это будет уже массив, причем ексель после этого можно уже закрывать
31 Всеяд
 
19.10.07
10:35
И всё же, я бы посмотрел сначала на результаты замера производительности. Может быть, имеет смысл не на секундах доступа к Excel играть, а на оптимизации записи?
Например, вести счётчик записи объектов и записывать в транзакции каждые 50-100 элементов? Если я правильно понимаю, партий новых там много пишется.

Кроме того, если есть повторяющиеся элементы, неплохо было бы завести соответствия загруженных кодов партий и сотрудников - тогда не надо будет искать по коду.
32 Zholty
 
19.10.07
10:37
(29) извини, попутал немного, только я сомневаюсь что будет быстрее
33 zbv
 
19.10.07
10:37
(30) а можно ИспользуемыйДиапазон задать произвольно?

типа:
ИспользуемыйДиапазон=Лист.Range("B3:I50");

чуствую, что можно... :)
34 Aloex
 
19.10.07
10:39
(31)прав ,как вариант разбить на отдельные куски чтение из файлика  а потом запись в справочники,  и затем уже рассуждать что является тормозом.
35 lamme
 
19.10.07
10:40
торомзом являеться именно заполнение справочников.
Если взять все параметры - как текст - то достаточно шустро все делаеться.
36 smaharbA
 
19.10.07
10:40
(33) да, в (12) просто пример загрузки разом всех данных с листа
...
это и в семерке действует, только там нужно извратиться немного
37 Dem1urg
 
19.10.07
10:43
Посмотри в отладчике какая часть времени уходит на загрузку данных из Excel, а какая на запись новых элементов справочника.

Можешь попробовать подключение через ADODB.
38 manyak
 
19.10.07
10:43
если отказаться от эекселя, попробуй: сохраняешь в текст файл с разделителями (Таб), в 1с читаешь файл построчно в стрИсходная, потом рабиваешь ее на многострочную и считывешь нужный столбец по его номеру:

стрСтроки = СтрЗаменить(стрИсходная, Символы.Таб, Символы.ПС);
стрПервыйСтобец = СтрПолучитьСтроку(стрСтроки, 1);
39 Dem1urg
 
19.10.07
10:45
Результаты замера производительности в студию.
А заодно и количество создаваемых элементов справочников.
40 smaharbA
 
19.10.07
10:45
Фигня какаято...(с)
41 Zholty
 
19.10.07
11:09
Словил прикольное изречение:
"Изречение: Усложнять - просто, упрощать - сложно."
42 Mitriy
 
19.10.07
14:03
Послушайте Всеяда (34), он дело говорит...
43 smaharbA
 
19.10.07
14:16
Ну-ну...
44 zbv
 
19.10.07
14:34
Abrahams дело говорит, респект ему. :)

Уже переделал закачку, добавил только еще перевод в массив 1C.

Да и "Для Каждого" выбирает по столбцам, т.е. сначала данные одного столбца по всем строчкам, потом другого, так что использовал "для ... по ..."
45 Всеяд
 
19.10.07
14:43
(44) +1
Я сразу метод себе выписал на будущее... 8)
46 Гений 1С
 
гуру
09.11.07
16:54