Обработка txt файла

1. SergiusK 13.08.18 07:56 Сейчас в теме
Всем привет! Есть 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
+
По теме из базы знаний
Ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. Cooler 22 13.08.18 08:00 Сейчас в теме
(1)
Можно как-то ускорить обработку файла???
Об этом надо начинать спрашивать не форум, в глаза не видевший вашего кода, а замер производительности.
+
6. herfis 498 13.08.18 09:19 Сейчас в теме
(1) 8500 строк - это немного. Проще сначала прочитать файл в память в таблицу значений, выгрузить колонку артикулов в массив и сделать один запрос на отсутствующие артикулы. Ускорение будет на порядки. Для очень больших файлов (сотни тысяч и больше) схема такая же, только порционная.
Infector; +1
15. user1031946 15.08.18 15:29 Сейчас в теме
Присоединяюсь к (6) и работать с ТЗ.
+
3. pun4er 13.08.18 08:49 Сейчас в теме
Вы 1 артикул сравниваете одним запросом? 8500 запросов получается? Если так, то не удивительно. А вообще, крайне желательно показать код, который это всё делает, экстрасенсорными способностями угадывания кода по описанию тут вряд ли кто обладает.
+
4. DarkUser 13.08.18 08:50 Сейчас в теме
Если у вас выполняется запрос для каждого артикула, то желательно сделать наоборот. Сначала получить выборку по артикулам в базе, а потом сверять артикул с данными выборки.
YanTsys; +1
5. kogl208 13.08.18 09:17 Сейчас в теме
А как происходит обработка самого файла? Как построен запрос?
Желательно вначале получить список артикулов из файла, а затем в запросе: создать таблицу и туда загрузить артикулы из файла (АртикулыФайла); получить список артикулов из базы (АртикулыБазы); АртикулыФайла Левое соединение АртикулыБазы. Далее на Ваше усмотрение. Отбор можно в запросе (Есть NULL) или после выполнения обработать. Все зависит от предпочтений.
+
7. Jestery 13.08.18 14:29 Сейчас в теме
Уважаемый топикстартер, вы подозреваетесь в страшном преступлении - выполнении запроса в цикле :) Код в студию :)
+
8. kild 89 13.08.18 17:32 Сейчас в теме
Можно как-то ускорить обработку файла???

Может и можно, а может и нет.
Собственно, что ускорить-то нужно, где код?
+
9. SergiusK 14.08.18 08:02 Сейчас в теме
&НаСервере
Процедура СформироватьНаСервере()
	
	// проверим наличие файла выбранном каталоге
	КаталогГдеИскать = ВыборКаталогаЗагрузки;
	МассивНайденныхФайлов = НайтиФайлы(КаталогГдеИскать, "*.txt");
	
	Если МассивНайденныхФайлов.Количество() < 0 Тогда //каталог пустой
		Сообщить("Каталог пустой.");
		Возврат;
	ИначеЕсли МассивНайденныхФайлов.Количество() > 1 Тогда //в каталоге файлов больше одного
		Сообщить("В выбранном каталоге слишком много файлов.");
		Возврат;
	Иначе 
		Сообщить("Файл найден, загружаем.");
	КонецЕсли;
	
	Разделитель = ";";
	
	//прочитаем файл TXT
	ФайлТХТ = Новый ТекстовыйДокумент;
	
	ФайлТХТ_ПолноеИмя = МассивНайденныхФайлов[0].ПолноеИмя;//полное имя файла
	
	ФайлТХТ.Прочитать(ФайлТХТ_ПолноеИмя);
	
	ФайлТХТ_КоличествоСтрок = ФайлТХТ.КоличествоСтрок();
	
	Для СчетчикСтрок = 1 По ФайлТХТ_КоличествоСтрок Цикл //переберем все строки TXT
		
		ФайлТХТ_ТекущаяСтрока = ФайлТХТ.ПолучитьСтроку(СчетчикСтрок);
		ФайлТХТ_ТекущаяСтрокаРазделенная = СтрРазделить(ФайлТХТ_ТекущаяСтрока, Разделитель, Истина);
		
		//на форме создана ТаблицаЗначений "ФайлТХТ_ТЗ"
		//заполним ФайлТХТ_ТЗ
		СтрТЗФайлТХТ_ТЗ = ФайлТХТ_ТЗ.Добавить();
		СтрТЗФайлТХТ_ТЗ.Артикул       = ФайлТХТ_ТекущаяСтрокаРазделенная[0];
		СтрТЗФайлТХТ_ТЗ.Номенклатура  = ФайлТХТ_ТекущаяСтрокаРазделенная[1];
		СтрТЗФайлТХТ_ТЗ.ШК            = ФайлТХТ_ТекущаяСтрокаРазделенная[2];
		СтрТЗФайлТХТ_ТЗ.ЦенаРозничная = ФайлТХТ_ТекущаяСтрокаРазделенная[3];
		СтрТЗФайлТХТ_ТЗ.ЕдИзм         = ФайлТХТ_ТекущаяСтрокаРазделенная[4];
		СтрТЗФайлТХТ_ТЗ.СтавкаНДС     = ФайлТХТ_ТекущаяСтрокаРазделенная[5];
		СтрТЗФайлТХТ_ТЗ.ВесШт         = ФайлТХТ_ТекущаяСтрокаРазделенная[6];
		
	КонецЦикла;
	
	//запрос по артикулу
	Запрос = Новый Запрос;
	Запрос.Текст = 
		"ВЫБРАТЬ
		|	спрНоменклатура.Ссылка КАК Номенклатура,
		|	спрНоменклатура.Артикул КАК Артикул,
		|	ЦеныНоменклатурыСрезПоследних.Цена КАК Цена,
		|	Штрихкоды.Штрихкод КАК Штрихкод
		|ИЗ
		|	Справочник.Номенклатура КАК спрНоменклатура
		|		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&ТекущаяДата, ) КАК ЦеныНоменклатурыСрезПоследних
		|		ПО спрНоменклатура.Ссылка = ЦеныНоменклатурыСрезПоследних.Номенклатура.Ссылка
		|		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Штрихкоды КАК Штрихкоды
		|		ПО спрНоменклатура.Ссылка = Штрихкоды.Владелец.Ссылка
		|ГДЕ
		|	спрНоменклатура.Артикул = &Артикул
		|	И ЦеныНоменклатурыСрезПоследних.ВидЦены = &ВидЦены";
	
	//Запрос.УстановитьПараметр("Артикул", файлАртикул);
	Запрос.УстановитьПараметр("ВидЦены", Справочники.ВидыЦен.НайтиПоНаименованию("Розничная"));
	Запрос.УстановитьПараметр("ТекущаяДата", КонецДня(ДатаРозничнойЦены));
	
	Для каждого СтрФайлТХТ_ТЗ Из ФайлТХТ_ТЗ Цикл //переберем все строки ТЗ
		
		Запрос.УстановитьПараметр("Артикул", СтрФайлТХТ_ТЗ.Артикул);
		РезультатЗапросаПоАртикулу = Запрос.Выполнить();
		
		ТЗ_Артикул = РезультатЗапросаПоАртикулу.Выбрать();
		
		Пока ТЗ_Артикул.Следующий() Цикл
			
			//обработка как мне надо
			//НО ОЧЕНЬ ДОЛГО!!!!			
			
		КонецЦикла;
		
	КонецЦикла;
	
КонецПроцедуры

&НаКлиенте
Процедура Сформировать(Команда)
	СформироватьНаСервере();
КонецПроцедуры

&НаКлиенте
Процедура ВыборКаталога(Команда)
	Режим = РежимДиалогаВыбораФайла.ВыборКаталога;
	ДиалогВыбораФайла = Новый ДиалогВыбораФайла(Режим);
	ДиалогВыбораФайла.Каталог = "";
	ДиалогВыбораФайла.МножественныйВыбор = Ложь;
	ДиалогВыбораФайла.Заголовок = "Выберите каталог";
	
	Если ДиалогВыбораФайла.Выбрать() Тогда
		ВыборКаталогаЗагрузки = ДиалогВыбораФайла.Каталог;	
	КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура ПриОткрытии(Отказ)
	ДатаРозничнойЦены = КонецДня(ТекущаяДата());
КонецПроцедуры
Показать
+
10. Denis_CFO 48 14.08.18 09:34 Сейчас в теме
(9) сделайте, как в (6) посоветовали. Потому что у вас получается количество запросов к базе = количество артикулов.
+
11. Xershi 1484 14.08.18 09:42 Сейчас в теме
(9) пихай ТЗ в запрос и потом полученные данные обрабатывай, получится в 8500 раз быстрее))
+
13. nddru 31 15.08.18 05:25 Сейчас в теме
(11) А еще лучше, сделать ТЗ, скормить ее запросу во внутреннюю таблицу и слева прилепить номенклатуру по артикулу и перебрать выборку, где номенклатура null там создаем элемент.
AnnaPetishkina; +1
12. Infector 201 14.08.18 10:54 Сейчас в теме
Процедура ПодобратьСсылкиНоменклатурыПоАртикулам(Таблица, ИмяКолонкиАртикула, ИмяКолонкиСсылки) Экспорт
		
	Артикулы = Таблица.ВыгрузитьКолонку(ИмяКолонкиАртикула);
	
	Запрос = Новый Запрос;
	
	Запрос.Текст = 
	
	"ВЫБРАТЬ РАЗЛИЧНЫЕ
	|	НоменклатураСпр.Артикул КАК Артикул,
	|	НоменклатураСпр.Ссылка КАК Номенклатура,
	|	ЕСТЬNULL(НоменклатураСпр.ПометкаУдаления, ЛОЖЬ) КАК ПометкаУдаления
	|ИЗ
	|	Справочник.Номенклатура КАК НоменклатураСпр
	|ГДЕ
	|	НоменклатураСпр.Артикул В(&Артикулы)
	|
	|УПОРЯДОЧИТЬ ПО
	|	Артикул,
	|	ПометкаУдаления"
	;
	
	Запрос.УстановитьПараметр("Артикулы", Артикулы);
	
	ТаблицаНоменклатуры = Запрос.Выполнить().Выгрузить();
	
	Для Каждого Стр Из Таблица Цикл
		Если ЗначениеЗаполнено(Стр[ИмяКолонкиСсылки]) ИЛИ Не ЗначениеЗаполнено(Стр[ИмяКолонкиАртикула]) Тогда
			Продолжить;	
		КонецЕсли;
		
		ПараметрыОтбораТаблицыНоменклатур = Новый Структура("Артикул", Стр[ИмяКолонкиАртикула]);
		
		ОтборТаблицыНоменклатур = ТаблицаНоменклатуры.НайтиСтроки(ПараметрыОтбораТаблицыНоменклатур);
		
		Если ОтборТаблицыНоменклатур.Количество() > 0 Тогда
			Номенклатура = ОтборТаблицыНоменклатур[0].Номенклатура;
		Иначе
			Номенклатура = ПредопределенноеЗначение("Справочник.Номенклатура.ПустаяСсылка");
		КонецЕсли;
		
		Если Не ЗначениеЗаполнено(Номенклатура) Тогда
			Номенклатура = ПредопределенноеЗначение("Справочник.Номенклатура.ПустаяСсылка");	
		КонецЕсли;	
		
		ПараметрыОтбораИсходнойТаблицы = Новый Структура(ИмяКолонкиАртикула, Стр[ИмяКолонкиАртикула]);
		
		ОтборИсходнойТаблицы = Таблица.НайтиСтроки(ПараметрыОтбораИсходнойТаблицы);
		
		Для Каждого СтрОтбора Из ОтборИсходнойТаблицы Цикл		
			СтрОтбора[ИмяКолонкиСсылки] = Номенклатура;		
		КонецЦикла;	
		
	КонецЦикла;
	
КонецПроцедуры

Показать
+
14. SoLRoN 15.08.18 11:44 Сейчас в теме
Еще один вариант предложу - выбрать сначала все артикулы из базы в список значений (или массив), а потом при обработке файла искать артикул в этом массиве, и если артикул не найден - заводить. Из предложенных способов есть более быстрые, но не каждый программист в силах реализовать, а тут все просто.
+
16. KlesAlex 3 22.08.18 12:54 Сейчас в теме
Сначала читаете файл
Затем запросом получаете отсутствующие строки и создаете их.
+
Внимание! Тема сдана в архив

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот