|
Оптимизация кода | ☑ | ||
---|---|---|---|---|
0
Rumpil
20.02.12
✎
09:50
|
Доброе утро, господа. У меня существует файл с ценами в формате
Excel, 156 тысяч строк, в этом файле так получилось что есть какое то количество записей-дубликатов. Соответственно при загрузке в 1С и создании документа "Установка цен номенклатуры контрагентов" я должен не только искать такой товар в базе 1с, но и после нахождения его прежде чем добавить его в табличную часть моего документа я должен проверять не был ли он уже посажен ранее в эту табличную часть. Код под эту задачу написал, но он дико весит - за 15 часов он обработал только около 20 тысяч строк. МОжет подскажете как можно оптимизировать код ? Попытка гл_appExcel = Новый COMObject("Excel.Application"); Исключение Сообщить(ОписаниеОшибки()); Возврат; КонецПопытки; exWorkBook = гл_appExcel.Workbooks.Open(Файлы); RangeAll = exWorkBook.ActiveSheet.UsedRange; если СтрокиС = 0 тогда СтрокиС=1; КонецЕсли; ДокОбъект = Документы.УстановкаЦенНоменклатурыКонтрагентов.СоздатьДокумент(); ДокОбъект.Дата = ТекущаяДата(); ДокОбъект.Контрагент = Справочники.Контрагенты.Вендор; ТипЦен = ДокОбъект.ТипыЦен.Добавить(); ТипЦен.ТипЦен = ВыбраннаяЦена; ДокОбъект.Ответственный = УправлениеПользователями.ПолучитьЗначениеПоУмолчанию(ПараметрыСеанса.ТекущийПользователь, "ОсновнойОтветственный"); Для НомерСтроки = СтрокиС По СтрокиПо Цикл ОбработкаПрерыванияПользователя(); ПрописьюШтрихкод = Формат(RangeAll.Cells(НомерСтроки, 1 ).Value, "ЧГ=0"); ПрописьюМодель = RangeAll.Cells(НомерСтроки, 2 ).Value; ПрописьюНаименование = RangeAll.Cells(НомерСтроки, 4 ).Value; ПрописьюСебестоимость = RangeAll.Cells(НомерСтроки, 8 ).Value; //Товар = Справочники.Номенклатура.ПустаяСсылка(); //Товар = Справочники.Номенклатура.НайтиПоНаименованию(ПрописьюНаименование,Истина); Товар = ""; Артикул = Сред(ПрописьюШтрихкод,1,16); Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Номенклатура.Ссылка |ИЗ | Справочник.Номенклатура КАК Номенклатура |ГДЕ | Номенклатура.Наименование = &ТекНом | И Номенклатура.Модели.Наименование = &ТекМод | И Номенклатура.Артикул = &ТекАрт"; Запрос.УстановитьПараметр("ТекАрт", Артикул); Запрос.УстановитьПараметр("ТекНом", ПрописьюНаименование); Запрос.УстановитьПараметр("ТекМод", ПрописьюМодель); Результат = Запрос.Выполнить(); Выборка = Результат.Выбрать(); Пока Выборка.Следующий() Цикл Товар = Выборка.Ссылка; КонецЦикла; если НЕ ЗначениеЗаполнено(Товар) Тогда Сообщить("Товар "+ ПрописьюНаименование +" не найден в базе и не загружена себестоимость.",СтатусСообщения.Информация); КонецЕсли; если ЗначениеЗаполнено(Товар) Тогда ИскомыйТовар = Новый Структура; ИскомыйТовар.Вставить("Номенклатура", Товар); РезультатПоиска = ДокОбъект.Товары.НайтиСтроки(ИскомыйТовар); Если РезультатПоиска.Количество() = 0 Тогда Если ПрописьюСебестоимость = Неопределено Тогда Сообщить("Цена на товар "+ ПрописьюНаименование +" не заполнена в файле Excel",СтатусСообщения.Информация); Иначе НоваяСтрока = ДокОбъект.Товары.Добавить(); НоваяСтрока.Номенклатура = Товар; НоваяСтрока.ЕдиницаИзмерения = Справочники.ЕдиницыИзмерения.НайтиПоНаименованию("?d"); НоваяСтрока.Валюта = ВыбраннаяЦена.ВалютаЦены; НоваяСтрока.ТипЦен = ВыбраннаяЦена; НоваяСтрока.Цена = ПрописьюСебестоимость; ДокОбъект.Записать(РежимЗаписиДокумента.Проведение); КонецЕсли; КонецЕсли; КонецЕсли; КонецЦикла; exWorkBook.Close( Ложь ); гл_appExcel.Workbooks.Close( ); |
|||
1
Dirk Diggler
20.02.12
✎
09:56
|
загрузить все в ТЗ, запросом выбрать и свернуть её из временной таблицы.
|
|||
2
Rumpil
20.02.12
✎
09:57
|
(1) о, идея, спасиб, сейчас попробую
|
|||
3
Steel_Wheel
20.02.12
✎
09:57
|
Это ДокОбъект.Записать(РежимЗаписиДокумента.Проведение);
вытащи из цикла, записывай только на каждую 1000-ую строку |
|||
4
Steel_Wheel
20.02.12
✎
09:57
|
ты изнасиловал свою БД )
|
|||
5
artems
20.02.12
✎
10:07
|
+(4) в особо извращенной форме ))
|
|||
6
decdmb
20.02.12
✎
10:18
|
+ загружать не через COM, а через ADO.
|
|||
7
Rumpil
20.02.12
✎
10:30
|
Переписал код, не сказать что все полетелело, но пошустрее вроде заработал:
Попытка гл_appExcel = Новый COMObject("Excel.Application"); Исключение Сообщить(ОписаниеОшибки()); Возврат; КонецПопытки; exWorkBook = гл_appExcel.Workbooks.Open(Файлы); RangeAll = exWorkBook.ActiveSheet.UsedRange; если СтрокиС = 0 тогда СтрокиС=1; КонецЕсли; ДокОбъект = Документы.УстановкаЦенНоменклатурыКонтрагентов.СоздатьДокумент(); ДокОбъект.Дата = ТекущаяДата(); //ДокОбъект.Организация = УправлениеПользователями.ПолучитьЗначениеПоУмолчанию(ПараметрыСеанса.ТекущийПользователь, "ОсновнаяОрганизация"); ДокОбъект.Контрагент = Справочники.Контрагенты.Вендор; ТипЦен = ДокОбъект.ТипыЦен.Добавить(); ТипЦен.ТипЦен = ВыбраннаяЦена; ДокОбъект.Ответственный = УправлениеПользователями.ПолучитьЗначениеПоУмолчанию(ПараметрыСеанса.ТекущийПользователь, "ОсновнойОтветственный"); ОбработкаПрерыванияПользователя(); Таблица = Новый ТаблицаЗначений; Таблица.Колонки.Добавить("ПрописьюШтрихкод",Новый ОписаниеТипов("Строка")); Таблица.Колонки.Добавить("ПрописьюМодель",Новый ОписаниеТипов("Строка")); Таблица.Колонки.Добавить("ПрописьюНаименование",Новый ОписаниеТипов("Строка")); Таблица.Колонки.Добавить("ПрописьюСебестоимость",Новый ОписаниеТипов("Число")); Для НомерСтроки = СтрокиС По СтрокиПо Цикл НоваяСтр = Таблица.Добавить(); НоваяСтр.ПрописьюШтрихкод = Формат(RangeAll.Cells(НомерСтроки, 1 ).Value, "ЧГ=0"); НоваяСтр.ПрописьюМодель = RangeAll.Cells(НомерСтроки, 2 ).Value; НоваяСтр.ПрописьюНаименование = RangeAll.Cells(НомерСтроки, 4 ).Value; НоваяСтр.ПрописьюСебестоимость = RangeAll.Cells(НомерСтроки, 8 ).Value; КонецЦикла; Для каждого Стр из Таблица Цикл Товар = ""; Артикул = Сред(Стр.ПрописьюШтрихкод,1,16); Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Номенклатура.Ссылка |ИЗ | Справочник.Номенклатура КАК Номенклатура |ГДЕ | Номенклатура.Наименование = &ТекНом | И Номенклатура.Модели.Наименование = &ТекМод | И Номенклатура.Артикул = &ТекАрт"; Запрос.УстановитьПараметр("ТекАрт", Артикул); Запрос.УстановитьПараметр("ТекНом", Стр.ПрописьюНаименование); Запрос.УстановитьПараметр("ТекМод", Стр.ПрописьюМодель); Результат = Запрос.Выполнить(); Выборка = Результат.Выбрать(); Пока Выборка.Следующий() Цикл Товар = Выборка.Ссылка; КонецЦикла; если НЕ ЗначениеЗаполнено(Товар) Тогда Сообщить("Товар "+ Стр.ПрописьюНаименование +" не найден в базе и не загружена себестоимость.",СтатусСообщения.Информация); КонецЕсли; если ЗначениеЗаполнено(Товар) Тогда ИскомыйТовар = Новый Структура; ИскомыйТовар.Вставить("Номенклатура", Товар); РезультатПоиска = ДокОбъект.Товары.НайтиСтроки(ИскомыйТовар); Если РезультатПоиска.Количество() = 0 Тогда Если Стр.ПрописьюСебестоимость = 0 Тогда Сообщить("Цена на товар "+ Стр.ПрописьюНаименование +" не заполнена в файле Excel",СтатусСообщения.Информация); Иначе НоваяСтрока = ДокОбъект.Товары.Добавить(); НоваяСтрока.Номенклатура = Товар; НоваяСтрока.ЕдиницаИзмерения = Справочники.ЕдиницыИзмерения.НайтиПоНаименованию("?d"); НоваяСтрока.Валюта = ВыбраннаяЦена.ВалютаЦены; НоваяСтрока.ТипЦен = ВыбраннаяЦена; НоваяСтрока.Цена = Стр.ПрописьюСебестоимость; Сообщить("Добавлена цена на товар "+ Стр.ПрописьюНаименование +", цена - " + Стр.ПрописьюСебестоимость,СтатусСообщения.Информация); КонецЕсли; КонецЕсли; КонецЕсли; КонецЦикла; ДокОбъект.Записать(РежимЗаписиДокумента.Проведение); exWorkBook.Close( Ложь ); гл_appExcel.Workbooks.Close( ); |
|||
8
DrShad
20.02.12
✎
10:35
|
Сообщить() убери оно тоже сильно тормозит
|
|||
9
DrShad
20.02.12
✎
10:36
|
(6) +100500
|
|||
10
Rumpil
20.02.12
✎
10:37
|
(8) ок
|
|||
11
Maxus43
20.02.12
✎
10:40
|
запросом к ёкселю шустрей ж будет
|
|||
12
DrShad
20.02.12
✎
10:40
|
(10) лучше создавай Текст в качестве лога и потом выводи его в конце в Поле на форме и записывай соответственно
|
|||
13
Rumpil
20.02.12
✎
11:08
|
сделал через йоксель, вроде скорость полета хорошая
|
|||
14
Лефмихалыч
20.02.12
✎
11:25
|
спасибо, поржал
1. Запрос из цикла вынеси, замени на временную таблицу и соединение с номенклатурой 2. Либо в запрос воткни Первые 1, либо в цикл обхода выборки воткни Прервать 3. Вот это "РезультатПоиска = ДокОбъект.Товары.НайтиСтроки(ИскомыйТовар);" выкоси наиух, замени на запрос. Нормализуй источник, чтобы дублей не было, тогда не потребуется эта проверка 4. Справочники.ЕдиницыИзмерения.НайтиПоНаименованию("?d"); вынеси из цикла вообще, зачем это каждый раз заново находить? 5. К экселю запросом через АДО обращайся А в целом - да отсохнут руки, написавшие это |
|||
15
DexterMorgan
20.02.12
✎
11:29
|
(14) <А в целом - да отсохнут руки, написавшие это>
А в целом - да отсохнут руки, написавшие это |
|||
16
ЧеловекДуши
20.02.12
✎
11:31
|
Грузи через АДО, быстрее
|
|||
17
ЧеловекДуши
20.02.12
✎
11:33
|
+(14) +100500 :)
|
|||
18
Rumpil
20.02.12
✎
11:46
|
(14) а через АДо как сделать ?
|
|||
19
decdmb
20.02.12
✎
12:04
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |