Всем привет! Есть 1С:Предприятие 8.3 (8.3.11.2867). Пытаюсь загрузить txt файл (примерно 8500 строк), структура файла такая:
Артикул;Номенклатура;ШК;Цена;ЕдиницаИзмерения;СтавкаНДС
Нужно сравнить Артикул с тем что уже есть в БД, соответственно если нет такого артикула, значит завести новую номенклатуру и т.д.
Сначала разбиваю строку по разделителю, потом сравниваю запросом и в итоге, чтоб обработать все 8500 строк занимает примерно 1,5 часа.
Можно как-то ускорить обработку файла???
P.S.: Характеристики компа: проц.CPU E5-2670 2.6GHz, ОЗУ 32Гб, ОС Windows Server 2008 R2 Standart, х64
Артикул;Номенклатура;ШК;Цена;ЕдиницаИзмерения;СтавкаНДС
Нужно сравнить Артикул с тем что уже есть в БД, соответственно если нет такого артикула, значит завести новую номенклатуру и т.д.
Сначала разбиваю строку по разделителю, потом сравниваю запросом и в итоге, чтоб обработать все 8500 строк занимает примерно 1,5 часа.
Можно как-то ускорить обработку файла???
P.S.: Характеристики компа: проц.CPU E5-2670 2.6GHz, ОЗУ 32Гб, ОС Windows Server 2008 R2 Standart, х64
По теме из базы знаний
- Простое сравнение ролей 1С 8 (сравнение обработок, правил обмена XML, файлов txt, файлов mxl)
- Анализ данных txt файла
- Сохранение (чтение) настроек внешней обработки в файл (управляемые формы)
- Загрузка автозаказов из txt-файлов сети супермаркетов "Абсолют"
- Загрузка родительской платы из TXT файла и создание документа "Поступление родительской платы на лицевой счет"
Ответы
Подписаться на ответы
Инфостарт бот
Сортировка:
Древо развёрнутое
Свернуть все
(1) 8500 строк - это немного. Проще сначала прочитать файл в память в таблицу значений, выгрузить колонку артикулов в массив и сделать один запрос на отсутствующие артикулы. Ускорение будет на порядки. Для очень больших файлов (сотни тысяч и больше) схема такая же, только порционная.
Вы 1 артикул сравниваете одним запросом? 8500 запросов получается? Если так, то не удивительно. А вообще, крайне желательно показать код, который это всё делает, экстрасенсорными способностями угадывания кода по описанию тут вряд ли кто обладает.
Если у вас выполняется запрос для каждого артикула, то желательно сделать наоборот. Сначала получить выборку по артикулам в базе, а потом сверять артикул с данными выборки.
А как происходит обработка самого файла? Как построен запрос?
Желательно вначале получить список артикулов из файла, а затем в запросе: создать таблицу и туда загрузить артикулы из файла (АртикулыФайла); получить список артикулов из базы (АртикулыБазы); АртикулыФайла Левое соединение АртикулыБазы. Далее на Ваше усмотрение. Отбор можно в запросе (Есть NULL) или после выполнения обработать. Все зависит от предпочтений.
Желательно вначале получить список артикулов из файла, а затем в запросе: создать таблицу и туда загрузить артикулы из файла (АртикулыФайла); получить список артикулов из базы (АртикулыБазы); АртикулыФайла Левое соединение АртикулыБазы. Далее на Ваше усмотрение. Отбор можно в запросе (Есть NULL) или после выполнения обработать. Все зависит от предпочтений.
Уважаемый топикстартер, вы подозреваетесь в страшном преступлении - выполнении запроса в цикле :) Код в студию :)
Можно как-то ускорить обработку файла???
Может и можно, а может и нет.
Собственно, что ускорить-то нужно, где код?
&НаСервере
Процедура СформироватьНаСервере()
// проверим наличие файла выбранном каталоге
КаталогГдеИскать = ВыборКаталогаЗагрузки;
МассивНайденныхФайлов = НайтиФайлы(КаталогГдеИскать, "*.txt");
Если МассивНайденныхФайлов.Количество() < 0 Тогда //каталог пустой
Сообщить("Каталог пустой.");
Возврат;
ИначеЕсли МассивНайденныхФайлов.Количество() > 1 Тогда //в каталоге файлов больше одного
Сообщить("В выбранном каталоге слишком много файлов.");
Возврат;
Иначе
Сообщить("Файл найден, загружаем.");
КонецЕсли;
Разделитель = ";";
//прочитаем файл TXT
ФайлТХТ = Новый ТекстовыйДокумент;
ФайлТХТ_ПолноеИмя = МассивНайденныхФайлов[0].ПолноеИмя;//полное имя файла
ФайлТХТ.Прочитать(ФайлТХТ_ПолноеИмя);
ФайлТХТ_КоличествоСтрок = ФайлТХТ.КоличествоСтрок();
Для СчетчикСтрок = 1 По ФайлТХТ_КоличествоСтрок Цикл //переберем все строки TXT
ФайлТХТ_ТекущаяСтрока = ФайлТХТ.ПолучитьСтроку(СчетчикСтрок);
ФайлТХТ_ТекущаяСтрокаРазделенная = СтрРазделить(ФайлТХТ_ТекущаяСтрока, Разделитель, Истина);
//на форме создана ТаблицаЗначений "ФайлТХТ_ТЗ"
//заполним ФайлТХТ_ТЗ
СтрТЗФайлТХТ_ТЗ = ФайлТХТ_ТЗ.Добавить();
СтрТЗФайлТХТ_ТЗ.Артикул = ФайлТХТ_ТекущаяСтрокаРазделенная[0];
СтрТЗФайлТХТ_ТЗ.Номенклатура = ФайлТХТ_ТекущаяСтрокаРазделенная[1];
СтрТЗФайлТХТ_ТЗ.ШК = ФайлТХТ_ТекущаяСтрокаРазделенная[2];
СтрТЗФайлТХТ_ТЗ.ЦенаРозничная = ФайлТХТ_ТекущаяСтрокаРазделенная[3];
СтрТЗФайлТХТ_ТЗ.ЕдИзм = ФайлТХТ_ТекущаяСтрокаРазделенная[4];
СтрТЗФайлТХТ_ТЗ.СтавкаНДС = ФайлТХТ_ТекущаяСтрокаРазделенная[5];
СтрТЗФайлТХТ_ТЗ.ВесШт = ФайлТХТ_ТекущаяСтрокаРазделенная[6];
КонецЦикла;
//запрос по артикулу
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| спрНоменклатура.Ссылка КАК Номенклатура,
| спрНоменклатура.Артикул КАК Артикул,
| ЦеныНоменклатурыСрезПоследних.Цена КАК Цена,
| Штрихкоды.Штрихкод КАК Штрихкод
|ИЗ
| Справочник.Номенклатура КАК спрНоменклатура
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&ТекущаяДата, ) КАК ЦеныНоменклатурыСрезПоследних
| ПО спрНоменклатура.Ссылка = ЦеныНоменклатурыСрезПоследних.Номенклатура.Ссылка
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Штрихкоды КАК Штрихкоды
| ПО спрНоменклатура.Ссылка = Штрихкоды.Владелец.Ссылка
|ГДЕ
| спрНоменклатура.Артикул = &Артикул
| И ЦеныНоменклатурыСрезПоследних.ВидЦены = &ВидЦены";
//Запрос.УстановитьПараметр("Артикул", файлАртикул);
Запрос.УстановитьПараметр("ВидЦены", Справочники.ВидыЦен.НайтиПоНаименованию("Розничная"));
Запрос.УстановитьПараметр("ТекущаяДата", КонецДня(ДатаРозничнойЦены));
Для каждого СтрФайлТХТ_ТЗ Из ФайлТХТ_ТЗ Цикл //переберем все строки ТЗ
Запрос.УстановитьПараметр("Артикул", СтрФайлТХТ_ТЗ.Артикул);
РезультатЗапросаПоАртикулу = Запрос.Выполнить();
ТЗ_Артикул = РезультатЗапросаПоАртикулу.Выбрать();
Пока ТЗ_Артикул.Следующий() Цикл
//обработка как мне надо
//НО ОЧЕНЬ ДОЛГО!!!!
КонецЦикла;
КонецЦикла;
КонецПроцедуры
&НаКлиенте
Процедура Сформировать(Команда)
СформироватьНаСервере();
КонецПроцедуры
&НаКлиенте
Процедура ВыборКаталога(Команда)
Режим = РежимДиалогаВыбораФайла.ВыборКаталога;
ДиалогВыбораФайла = Новый ДиалогВыбораФайла(Режим);
ДиалогВыбораФайла.Каталог = "";
ДиалогВыбораФайла.МножественныйВыбор = Ложь;
ДиалогВыбораФайла.Заголовок = "Выберите каталог";
Если ДиалогВыбораФайла.Выбрать() Тогда
ВыборКаталогаЗагрузки = ДиалогВыбораФайла.Каталог;
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ПриОткрытии(Отказ)
ДатаРозничнойЦены = КонецДня(ТекущаяДата());
КонецПроцедуры
ПоказатьПроцедура ПодобратьСсылкиНоменклатурыПоАртикулам(Таблица, ИмяКолонкиАртикула, ИмяКолонкиСсылки) Экспорт
Артикулы = Таблица.ВыгрузитьКолонку(ИмяКолонкиАртикула);
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| НоменклатураСпр.Артикул КАК Артикул,
| НоменклатураСпр.Ссылка КАК Номенклатура,
| ЕСТЬNULL(НоменклатураСпр.ПометкаУдаления, ЛОЖЬ) КАК ПометкаУдаления
|ИЗ
| Справочник.Номенклатура КАК НоменклатураСпр
|ГДЕ
| НоменклатураСпр.Артикул В(&Артикулы)
|
|УПОРЯДОЧИТЬ ПО
| Артикул,
| ПометкаУдаления"
;
Запрос.УстановитьПараметр("Артикулы", Артикулы);
ТаблицаНоменклатуры = Запрос.Выполнить().Выгрузить();
Для Каждого Стр Из Таблица Цикл
Если ЗначениеЗаполнено(Стр[ИмяКолонкиСсылки]) ИЛИ Не ЗначениеЗаполнено(Стр[ИмяКолонкиАртикула]) Тогда
Продолжить;
КонецЕсли;
ПараметрыОтбораТаблицыНоменклатур = Новый Структура("Артикул", Стр[ИмяКолонкиАртикула]);
ОтборТаблицыНоменклатур = ТаблицаНоменклатуры.НайтиСтроки(ПараметрыОтбораТаблицыНоменклатур);
Если ОтборТаблицыНоменклатур.Количество() > 0 Тогда
Номенклатура = ОтборТаблицыНоменклатур[0].Номенклатура;
Иначе
Номенклатура = ПредопределенноеЗначение("Справочник.Номенклатура.ПустаяСсылка");
КонецЕсли;
Если Не ЗначениеЗаполнено(Номенклатура) Тогда
Номенклатура = ПредопределенноеЗначение("Справочник.Номенклатура.ПустаяСсылка");
КонецЕсли;
ПараметрыОтбораИсходнойТаблицы = Новый Структура(ИмяКолонкиАртикула, Стр[ИмяКолонкиАртикула]);
ОтборИсходнойТаблицы = Таблица.НайтиСтроки(ПараметрыОтбораИсходнойТаблицы);
Для Каждого СтрОтбора Из ОтборИсходнойТаблицы Цикл
СтрОтбора[ИмяКолонкиСсылки] = Номенклатура;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Показать
Еще один вариант предложу - выбрать сначала все артикулы из базы в список значений (или массив), а потом при обработке файла искать артикул в этом массиве, и если артикул не найден - заводить. Из предложенных способов есть более быстрые, но не каждый программист в силах реализовать, а тут все просто.
Внимание! Тема сдана в архив
Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот