Имя: Пароль:
1C
1С v8
Есть ли способ оптимизации скорости при обращении к строкам xls?
,
0 SherifSP
 
14.06.13
09:48
В xls файле порядка 5000 строк, обращаюсь к строкам в цикле таким способом:
СтруктураДанных.Операция = СокрЛП(Ex.Cells(НС,2).Value);
           СтруктураДанных.МестоЗаправки = СокрЛП(Ex.Cells(НС,4).Value);
           СтруктураДанных.ВидТоплива = СокрЛП(Ex.Cells(НС,8).Value);
           СтруктураДанных.Кол = СокрЛП(Ex.Cells(НС,9).Value);
           СтруктураДанных.Сумма = СокрЛП(Ex.Cells(НС,10).Value);
           СтруктураДанных.Лимит = СокрЛП(Ex.Cells(НС,11).Value);

Замер производительности показал что каждое обращение в итоге занимает по 11 секунд, есть ли способ по другому обращаться к ячейкам файла, чтобы оптимизировать скорость?
1 vde69
 
14.06.13
09:50
запросом
2 Нуф-Нуф
 
14.06.13
09:53
скопировать. вставить в табличный документ 1с. читать его
3 бомболюк
 
14.06.13
09:55
диапазонами читать надо, так быстрее
4 SherifSP
 
14.06.13
09:56
(3) Это как?
5 SherifSP
 
14.06.13
09:57
(1) в 8.1 можно запросом обращаться к файлу? оО
6 SherifSP
 
14.06.13
09:57
(2) Так быстрее будит?
7 бомболюк
 
14.06.13
09:58
8 бомболюк
 
14.06.13
09:59
+(7) там вообще для вывода, но для чтения в принципе аналогично.
9 SherifSP
 
14.06.13
10:01
(7) Во, 1 вариант то что мне нужно)
10 SherifSP
 
14.06.13
10:02
+(9) Спасибо, буду чаще заглядывать в книгу знаний.
11 Ranger_83
 
14.06.13
10:02
(0) тут надо шамана Маню звать,он гуру по загрузкам из екселя
12 SherifSP
 
14.06.13
10:04
(7) А как в первом варианте считать, а не загрузить в xls?
13 SherifSP
 
14.06.13
10:05
(11) Так его наверное не так просто вызвать)
14 бомболюк
 
14.06.13
10:06
Ну наверна вот так:
МассивКОМ = Ексель.Range(Ексель.Cells(1,1), Ексель.Cells(ВсегоСтрок,ВсегоКолонок)).Value;
;-)
15 бомболюк
 
14.06.13
10:07
+(14) ну а с МассивКОМ потом гляди чего делать в отладчике. Это будет COMSafeArray.
16 SherifSP
 
14.06.13
10:09
(15) Спасибо большое)
17 SherifSP
 
14.06.13
14:37
Скрипт = Новый COMОбъект("MSScriptControl.ScriptControl");
Скрипт.language = "javascript";

ВремяНачала = Формат(Скрипт.eval("new Date().getTime()"),"ЧГ=0");
Эксель = ПолучитьCOMОбъект("c:\delado.xls");
ЛистЭксель = Эксель.WorkSheets(1);
ВсегоСтрок = ЛистЭксель.Cells.SpecialCells(11).Row;
ВсегоКолонок = ЛистЭксель.Cells.SpecialCells(11).Column;

Сообщить("Колонок: "+ Строка(ВсегоКолонок) + " Строк: "+ Строка(ВсегоСтрок));

ТЗ =  Новый ТаблицаЗначений;
Для Счетчик = 1 По ВсегоКолонок Цикл
  ТЗ.Колонки.Добавить("Колонка"+Счетчик);
КонецЦикла;

Для Счетчик = 1 По ВсегоСтрок Цикл
  НоваяСтрока = ТЗ.Добавить();
КонецЦикла;

Область = ЛистЭксель.Range(ЛистЭксель.Cells(1,1), ЛистЭксель.Cells(ВсегоСтрок,ВсегоКолонок));
Данные = Область.Value.Выгрузить();

Для Счетчик = 0 По ВсегоКолонок-1 Цикл
  ТЗ.ЗагрузитьКолонку(Данные[Счетчик], Счетчик);
КонецЦикла;
ЛистЭксель = Неопределено;
Эксель = Неопределено;

ВремяОкончания = Формат(Скрипт.eval("new Date().getTime()"),"ЧГ=0");
ОчиститьСообщения();
Сообщить("Выполнение скрипта заняло: " + Строка(ВремяОкончания - ВремяНачала) + " мсек. " + Символы.ПС +
     "Обработано строк: " + Строка(ВсегоКолонок) + " колонок: " + Строка(ВсегоСтрок) + " итого ячеек; " + Строка(ВсегоКолонок * ВсегоСтрок));

Вот такой метод сократил время считывания с 70 секунд до 5 секунд
18 Serginio1
 
14.06.13
14:44
ADODB.Connection
19 Serginio1
 
14.06.13
14:45
ADODB.Recordset
20 Eugeneer
 
14.06.13
14:48
У нас побит рекорд.
Прайс в 1 миллион строк
http://subsystems.ru/bitrix/components/bitrix/forum.interface/show_file.php?fid=1831
21 acsent
 
14.06.13
14:50
селект сделать
22 stix2010
 
14.06.13
14:54
ADODB  увеличивает скорости напорядок + не нужен exel
23 Eugeneer
 
14.06.13
14:54
(22) а если у меня Линукс сервер.
24 acsent
 
14.06.13
14:55
(22) нужен. Без установленного екселя нет такого источника данных
25 acsent
 
14.06.13
14:56
(23) и как тогда ты поступаешь?
26 Eugeneer
 
14.06.13
14:58
(25) прямая компонента которая читает все форматы экселя, без экселя, без адо и вообще без всего.
27 stix2010
 
14.06.13
15:43
(23) в условиях не было
28 stix2010
 
14.06.13
15:44
(25) где ты тут видишь com объект Exel? иногда лучше жевать, чем говорить:

   //Создание объекта для установки связи с источником данных
   Connection = Новый COMОбъект("ADODB.Connection");
   //сформируем строку подключения
   //Если необходимо в дальнейшем оперировать цифровыми значениями колонок,то ставим признак HDR = NO
   //если необходимо производить загрузку с учетом псевдонимов в 1й строке,то ставим HDR = YES
   СтрокаПодключения = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source = "+ПутьКФайлу;
   СтрокаПодключения = СтрокаПодключения + "; Extended Properties = "+"""Excel 8.0"+";HDR=NO;IMEX=1"";";
   //подключение к источнику данных
   Попытка
       Connection.Open(СтрокаПодключения);
   Исключение
       Сообщить(ОписаниеОшибки());
       Возврат Неопределено;
   КонецПопытки;    
   
   //создание объекта выполнения команды
   Command = Новый COMОбъект("ADODB.Command");
   //создание объекта подключения к файлу
   axCatalog = Новый COMОбъект("ADOX.Catalog");
   axCatalog.ActiveConnection = Connection;
   //получим листы документа,
   //для обработки колонок листа можно обратится к коллекции Лист.Columns,которую тоже можно обойти посредством цикла Для каждого  

   СписокЛистов = Новый СписокЗначений;
   КоличествоКолонок = 0;
   Для каждого Лист ИЗ axCatalog.Tables Цикл
       
       ТекстЗапросаКолонки = "";
       Если Лист.Columns.Count() > 5 Тогда
           Для к = 1 По Лист.Columns.Count() Цикл
                   //Если к=3 тогда
                   //    ТекстЗапросаКолонки = ТекстЗапросаКолонки +?(ТекстЗапросаКолонки="","F"+Формат(к,"ЧЦ=15; ЧГ=0")+"",",'F"+Формат(к,"ЧЦ=15; ЧГ=0"))+"'";
                   //Иначе
                       ТекстЗапросаКолонки = ТекстЗапросаКолонки + ?(ТекстЗапросаКолонки="","F"+Формат(к,"ЧЦ=15; ЧГ=0"),",F"+Формат(к,"ЧЦ=15; ЧГ=0"));
                   //КонецЕсли;
           
           КонецЦикла;
           
           СписокЛистов.Добавить(Лист.Name,ТекстЗапросаКолонки);
           КоличествоКолонок = к - 1;
           Прервать;
       КонецЕсли;
       
   КонецЦикла;
   
   
   //Создание объекта набора записей
   RecordSet = Новый COMОбъект("ADODB.RecordSet");
   //Указание активного соединения
   Command.ActiveConnection = Connection;
   //получим количество строк в документе
   Command.CommandText = "SELECT COUNT(*)FROM ["+СписокЛистов[0].Значение+"]";
   //определение типа команды
   Command.CommandType = 1;
   //Выполнение и получение набора данных
   RecordSet = Command.Execute();
   //первая запись это количество
   КоличествоСтрок = RecordSet.Fields(0).Value;
   //опредлеление текста команды
   Command.CommandText = "SELECT "+СписокЛистов[0].Представление+" FROM ["+СписокЛистов[0].Значение+"]";
   
   //для корректного конвертирования даты немного исправим запрос для поля f3
   Command.Commandtext = СтрЗаменить(Command.Commandtext, "F3", "Format(F3,'yyyymmdd')");
   Command.Commandtext = СтрЗаменить(Command.Commandtext, "F4", "Format(F4,'hh:nn')");

   //определение типа команды
   Command.CommandType = 1;
   
   //Выполнение и получение набора данных
   Попытка
       RecordSet = Command.Execute();
   Исключение
       Сообщить(ОписаниеОшибки());
   КонецПопытки;
29 Бледно Золотистый
 
14.06.13
15:46
(24) Можно скачать за бесплатно.
30 stix2010
 
14.06.13
15:48
Provider=Microsoft.Jet.OLEDB.4.0 с win xp по умолчанию
31 Лефмихалыч
 
14.06.13
15:55
(0) попробуй Range вместо cells или даже Range.Cells
смутно припоминаю, что какой-то из этих вариантов давай кипучий скачек производительности
32 Deon
 
14.06.13
15:59
(20) Если бы оно ещё с такой же скоростью в 1С создавалось...
33 Serginio1
 
14.06.13
16:46
(32) Пиши напрямую используя булки
34 Ковычки
 
14.06.13
17:04
(22) фуфло
Чтобы обнаруживать ошибки, программист должен иметь ум, которому доставляет удовольствие находить изъяны там, где, казалось, царят красота и совершенство. Фредерик Брукс-младший