Загрузка данных из файла .CSV

23.08.21

Интеграция - Файловый обмен (TXT, XML, DBF), FTP

Алгоритм для загрузки данных в учебную конфигурацию из файла с расширением CSV.

Здравствуйте. Эта публикация является частью учебного процесса, так что не судите строго.

 

Задача - создать обработку для загрузки данных в учебную конфигурацию из файла с расширением CSV.

Учебная конфигурация - это простая база ведения домашней бухгалтерии.

Данные - это файл выгрузки из аналогичной андроид программы.

Итак приступим к решению.

Шаг 1. Прочитать файл с данными

Создаем обработку. В форме обработки создаем:

  • реквизит - строку "Имя Файла"
  • и команду "Прочитать". 

Для команды "Прочитать" сразу сделаем процедуры ПрочитатьНаКлиенте и ПрочитатьНаСервере и пока отложим их.

Нам необходимо, чтобы строка "Имя Файла" позволяла выбрать файл. Для этого создадим дополнительную процедуру 

&НаКлиенте
Процедура ИмяФайлаНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
	ДиалогВыбора = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
	ДиалогВыбора.Заголовок = "Выберите каталог";
	
	Если ДиалогВыбора.Выбрать() Тогда
		ИмяФайла = ДиалогВыбора.ПолноеИмяФайла;
	КонецЕсли;
	каталогCSV=ДиалогВыбора.Каталог;
	файлCSV=ИмяФайла;
	файлCSV_ansi = ПерекодироватьФайлUTF8_ANSI(каталогCSV,файлCSV);
	ИмяФайла=файлCSV_ansi;
	
КонецПроцедуры

Как видно, начало процедуры вполне стандартное, однако в процессе работы над основной процедурой "Прочитать" я столкнулся с небольшой проблемой - файл был в не той кодировке и не хотел восприниматься алгоритмом, поэтому я добавил сюда строки:

файлCSV=ИмяФайла;
файлCSV_ansi = ПерекодироватьФайлUTF8_ANSI(каталогCSV,файлCSV);
ИмяФайла=файлCSV_ansi;

А также пришлось добавить на форму соответствующую функцию

Функция ПерекодироватьФайлUTF8_ANSI(каталогФайла, файлUTF8)

	  исходныйФайл = файлUTF8;
	  файлЧтение  = Новый ЧтениеТекста(исходныйФайл,КодировкаТекста.UTF8);    
	  txt=файлЧтение.Прочитать();
	  файлЧтение.Закрыть();

	  ФайлANSI = СтрЗаменить(файлUTF8,".","_ansi.");
	  файлЗапись = Новый ЗаписьТекста(ФайлANSI,КодировкаТекста.ANSI);    
	  файлЗапись.Записать(txt);
	  файлЗапись.Закрыть();
	  
      Возврат ФайлANSI;
КонецФункции

Теперь вернемся к процедуре "Прочитать", а именно к процедуре "ПрочитатьНаСервере" которую мы создали выше. Код процедуры состоит из таких частей:

Первая


	ПеременИмяФайла=ИмяФайла;
	
	ЗагружаемыйФайл = Новый ТекстовыйДокумент;
	ЗагружаемыйФайл.Прочитать(ПеременИмяФайла);
	Разделитель = ",";
	
	Шапка = ЗагружаемыйФайл.ПолучитьСтроку(1);
	
	МассивКол = СтрРазделить(Шапка,",");         
			
	
	Таблица = Новый ТаблицаЗначений;
	
	
	Для Каждого ИмяСтолбца Из МассивКол Цикл
		ИмяБезПробелов = СтрЗаменить(ИмяСтолбца," ",""); 
		Таблица.Колонки.Добавить(ИмяБезПробелов);
				
	КонецЦикла;
		
	Для НомерСтроки=2 по ЗагружаемыйФайл.КоличествоСтрок() Цикл
		
		Строка = ЗагружаемыйФайл.ПолучитьСтроку(НомерСтроки);
		МассивКол = СтрРазделить(Строка,Разделитель);
		НоваяСтрочка= Таблица.Добавить();
		
		      	
		
		Для НомерСтолбца= 1 по МассивКол.Количество() Цикл
			ТекущееЗначение = МассивКол[НомерСтолбца-1];
			ИмяКолонки = Таблица.Колонки[НомерСтолбца-1].Имя;
			НоваяСтрочка[ИмяКолонки] = ТекущееЗначение;
			
		КонецЦикла;
		
	КонецЦикла;

Здесь мы читаем данные с файла и добавляем их в таблицу значений. Хочу сразу предупредить, что таблица значений не предусматривает одинаковое название колонок. У меня как раз были такие, поэтому я не стал долго мучатся с этим и просто переименовал их. Однако подозреваю, что если чуть подумать и поднапрячься, то можно доработать код и решить эту проблему.

Вторая часть

МассивТипаВыбора = Новый Массив;
	МассивТипаВыбора.Добавить(Тип("ТаблицаЗначений"));
	ОписаниеТипаВыбора = Новый ОписаниеТипов(МассивТипаВыбора);
	МассивРеквизитов = Новый Массив;
	МассивРеквизитов.Добавить(Новый РеквизитФормы("ТаблицаCSV",ОписаниеТипаВыбора,));
	
	Для Каждого Ст ИЗ Таблица.Колонки Цикл
		Если Ст.Имя="" Тогда Ст.Имя="Пустая";
		КонецЕсли;
		МассивРеквизитов.Добавить(Новый РеквизитФормы(Ст.Имя, Новый ОписаниеТипов("Строка") , "ТаблицаCSV"));
		
	КонецЦикла;

	
	ИзменитьРеквизиты(МассивРеквизитов);
	
	Таб = Элементы.Добавить("ТаблицаCSV", Тип("ТаблицаФормы"));
	Таб.ПутьКДанным = "ТаблицаCSV";

	Для Каждого Ст ИЗ Таблица.Колонки Цикл
		Рек = Элементы.Добавить("Колонка" + Ст.Имя, Тип("ПолеФормы"), Таб);
		Рек.Вид = ВидПоляФормы.ПолеНадписи;
		Рек.ПутьКДанным = "ТаблицаCSV" + "." + Ст.Имя;
		Рек.Заголовок = Ст.Имя;
	КонецЦикла;
	
	
	ЗначениеВРеквизитФормы(Таблица,"ТаблицаCSV");

Захотелось немного покуражиться и программно добавить таблицу значений на форму. Хотя у этого была и рациональная причина - в дальнейшем не нужно будет каждый раз переделывать код, если файл с данными будет с другим количеством и названием колонок.

Итак, мы прочитали данные, переходим к следующему шагу.

Шаг 2. Загрузить данные в непосредственно в базу

Создаем на форме реквизит "ЧленСемьи", тип "СправочникСсылка.Семья" - если не забыли, у меня учебная база ведения домашней бухгалтерии.

А также команду "ЗагрузитьВБазу" и к ней соответствующие процедуры "ЗагрузитьВБазуНаКлиенте" и "ЗагрузитьВБазуНаСервере".

Рассмотрим код процедуры "ЗагрузитьВБазуНаСервере()".

Он также состоит из нескольких частей. Первая часть кода:

Процедура ЗагрузитьВБазуНаСервере()

	ТаблицаСЫМ=РеквизитФормыВЗначение("ТаблицаCSV");
	
	МенеджерВТ=Новый МенеджерВременныхТаблиц; 
	
	Запрос = Новый Запрос;
	Запрос.МенеджерВременныхТаблиц = МенеджерВТ;
	
	Запрос.Текст = 
		"ВЫБРАТЬ
		|	ВнешняяТабл1.date КАК Дата,
		|	ВнешняяТабл1.account КАК Счет,
		|	ВнешняяТабл1.category КАК Статья,
		|	ВнешняяТабл1.amount КАК Сумма,
		|	ВнешняяТабл1.currency КАК Валюта
		|ПОМЕСТИТЬ ВнешняяТаблица
		|ИЗ
		|	&ВнешняяТабл1 КАК ВнешняяТабл1";
	
	Запрос.УстановитьПараметр("ВнешняяТабл1",ТаблицаСЫМ);
	РезультатЗапроса = Запрос.Выполнить();

Здесь мы делаем запрос на чтение прочитанных данных на форме. Так как мы уже прочитали данные, то можем присвоить колонкам названия, используемые нами в базе.

Вторая часть кода

Запрос2 = Новый Запрос;
	Запрос2.МенеджерВременныхТаблиц = МенеджерВТ;

	Запрос2.Текст = 
		"ВЫБРАТЬ
		|	ВнешняяТаблица.Дата КАК Дата,
		|	ВнешняяТаблица.Счет КАК Счет,
		|	ВнешняяТаблица.Статья КАК Статья,
		|	ВнешняяТаблица.Сумма КАК Сумма,
		|	ВнешняяТаблица.Валюта КАК Валюта
		|ИЗ
		|	ВнешняяТаблица КАК ВнешняяТаблица";
	
	Запрос2.УстановитьПараметр("ЧленСемьи", ЧленСемьи);
	
	
	РезультатЗапроса2 = Запрос2.Выполнить();
	
	ВыборкаДетальныеЗаписи = РезультатЗапроса2.Выгрузить();
		
	Для Каждого Строка Из ВыборкаДетальныеЗаписи Цикл
	СтркСум=СтрЗаменить(Строка.Сумма," ","");
	СтркСС=СтрЗаменить(СтркСум, ".",",");
	
		
		Если Число(СтркСС) > 0 Тогда
	            
		Дох=Документы.ДобавитьДоход.СоздатьДокумент();
		Дох.Дата=ДатаИзСтроки(Строка.Дата);
		Дох.Счет=ПолучитьСсылкуСтатья(Справочники.Счета, Строка.Счет) ;
		Дох.СтатьяДоходов=ПолучитьСсылкуСтатья(Справочники.СтатьиДоходов, Строка.Статья);
		Дох.ФИО=ЧленСемьи;          
		ДохТаб=Дох.ТабличнаяЧасть1.Добавить();
		ДохТаб.Сумма=Число(СтркСС);
		ДохТаб.Валюта=ПолучитьСсылкуСтатья(Справочники.Валюты, Строка.Валюта);
		Дох.Записать(РежимЗаписиДокумента.Запись);

				
	ИначеЕсли  Число(СтркСС) < 0 Тогда

		
		Расх=Документы.ДобавитьРасход.СоздатьДокумент();
		Расх.Дата=ДатаИзСтроки(Строка.Дата);
		Расх.Счет=ПолучитьСсылкуСтатья(Справочники.Счета, Строка.Счет);
		Расх.СтатьяЗатрат=ПолучитьСсылкуСтатья(Справочники.СтатьиЗатрат, Строка.Статья);
		Расх.ФИО=ЧленСемьи;
		Сум=Число(СтркСС);
		РасхТаб=Расх.ТабличнаяЧасть1.Добавить();
		РасхТаб.Сумма=(0-Сум);
		РасхТаб.Валюта=ПолучитьСсылкуСтатья(Справочники.Валюты, Строка.Валюта);
		Расх.Записать(РежимЗаписиДокумента.Запись);
                        
	
		
	КонецЕсли;
	
			
	КонецЦикла;

Здесь мы уже непосредственно загружаем прочитанные данные в базу (конечно, второй запрос можно было не делать, но мне так показалось удобнее).

Рассмотрим некоторые строки кода детальнее.

Для Каждого Строка Из ВыборкаДетальныеЗаписи Цикл
	СтркСум=СтрЗаменить(Строка.Сумма," ","");
	СтркСС=СтрЗаменить(СтркСум, ".",",");

Так как, по сути, мы читали текстовый файл, то строки с суммами пришлось обработать - убрать лишние пробелы и заменить "." на ","

Если Число(СтркСС) > 0 Тогда

Данные, которые мы загружаем, имеют простую структуру: суммы + доходы суммы - расходы. Поэтому простое условие >0 позволило нам разделить данные для прихода и расхода.

Дох=Документы.ДобавитьДоход.СоздатьДокумент();

 Программно создаем документ, куда будем заносить данные

Дох.Дата=ДатаИзСтроки(Строка.Дата);

Здесь пришлось повозиться - до меня не сразу дошло, что если программно создаешь документ, то и дату туда надо заносить в формате "год.месяц.день час:мин:сек" пришлось добавить функцию для даты

Функция ДатаИзСтроки(стрДата) экспорт // "01.12.2011" преобразует в '01.12.2011 0:00:00'
	Попытка
		возврат Дата(Сред(стрДата,7,4)+Сред(стрДата,4,2)+Лев(стрДата,2))
	Исключение
		возврат '00010101'
	КонецПопытки;
КонецФункции

 Сразу скажу - спешил, поэтому функцию нашел здесь же на форуме. Сейчас пишу и думаю, что можно было сделать то же самое, используя "СтрРазделить", но код был бы длиннее.

Дох.Счет=ПолучитьСсылкуСтатья(Справочники.Счета, Строка.Счет);

База, по сути, - пустая, и мне не хотелось вручную наполнять справочники, поэтому добавил функцию:

&НаСервере
Функция ПолучитьСсылкуСтатья(СправочникСтатья, СтатьяНаименование)
	Перем СтатьяСсылка;
	
	
	СтатьяСсылка = СправочникСтатья.НайтиПоНаименованию(СтатьяНаименование);
	Если СтатьяСсылка = СправочникСтатья.ПустаяСсылка() Тогда
		СтатьяНовая = СправочникСтатья.СоздатьЭлемент();
		СтатьяНовая.Наименование = СтатьяНаименование ;
		СтатьяНовая.Записать();
		СтатьяСсылка = СтатьяНовая.Ссылка;
	КонецЕсли;
	      
	Возврат СтатьяСсылка;
КонецФункции

Так как справочников много, сделал два параметра "СправочникСтатья" и "СтатьяНаименование". 

Вроде основное пояснил.

Всем Спасибо. 

обработка CSV

См. также

SALE! 10%

Перенос данных 1C Файловый обмен (TXT, XML, DBF), FTP Системный администратор Программист Платформа 1С v8.3 1С:Розница 2 1С:Управление нашей фирмой 1.6 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 1С:Розница 3.0 Россия Платные (руб)

Правила в универсальном формате обмена для ERP 2.5, КА 2.5, УТ 11.5, БП 3.0, Розница, УНФ, для последних версий конфигураций. Ссылки на другие конфигурации в описании публикации. Правила совместимы со всеми другими версиями конфигураций новыми и старыми, поддерживающими обмен и синхронизацию в формате EnterpriseData. Не требуется синхронного обновления правил после обновления другой конфигурации, участвующей в обмене. Типовой обмен через планы обмена кнопкой Синхронизация вручную или автоматически по расписанию, или вручную обработкой.

27660 руб.

12.06.2017    143335    821    297    

428

SALE! 10%

Перенос данных 1C Файловый обмен (TXT, XML, DBF), FTP Системный администратор Программист Платформа 1С v8.3 Оперативный учет 1С:Управление торговлей 10 Россия Управленческий учет Платные (руб)

Перенос данных из 1С:Управление торговлей 10.3 в 1С:Управление торговлей 11.5 с помощью правил обмена. Переносятся остатки, документы (обороты за период), справочная информация. Правила проверены на конфигурациях УТ 10.3 (10.3.88.x) и УТ 11.5 (11.5.20.x), также подходят для релиза 11.5 (11.5.19.x).

35000 31500 руб.

23.07.2020    53428    236    73    

192

SALE! 10%

Перенос данных 1C Файловый обмен (TXT, XML, DBF), FTP Системный администратор Программист Платформа 1С v8.3 1С:Управление производственным предприятием 1С:Бухгалтерия 3.0 Россия Бухгалтерский учет Управленческий учет Платные (руб)

Перенос данных из 1С:Управление производственным предприятием 1.3 в 1С:Бухгалтерия предприятия 3.0 с помощью правил обмена. Переносятся остатки, документы (обороты за период), справочная информация. Правила проверены на конфигурациях УПП 1.3 (1.3.237.x) и БП 3.0 (3.0.166.x). Правила подходят для версии ПРОФ и КОРП.

35000 31500 руб.

15.12.2021    24829    174    51    

132

SALE! 10%

Перенос данных 1C Файловый обмен (TXT, XML, DBF), FTP Программист Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Комплексная автоматизация 2.х 1С:Зарплата и Управление Персоналом 3.x Россия Бухгалтерский учет Управленческий учет Платные (руб)

Перенос данных из ERP в ЗУП 3 | из КА 2 в ЗУП | Готовые правила конвертации данных (КД 2) для переноса остатков, документов с движениями и справочной информации 3 | Есть перенос начальной задолженности по зарплате и начальной штатной расстановки на выбранную дату | Обороты за прошлые годы (данные для расчета среднего) переносятся свернуто в документ "Перенос данных" | Есть фильтр по организациям | Документы за текущий период переносятся сразу с движениями, поэтому не потребуется делать перерасчеты | Перенос можно проверить перед покупкой, обращайтесь!

53111 47800 руб.

03.12.2020    37249    99    66    

95

SALE! 10%

Перенос данных 1C Файловый обмен (TXT, XML, DBF), FTP Системный администратор Программист Платформа 1С v8.3 1С:Комплексная автоматизация 1.х 1С:Управление производственным предприятием 1С:Бухгалтерия 3.0 Россия Бухгалтерский учет Платные (руб)

Перенос данных из 1С:Управление производственным предприятием 1.3 в 1С:Бухгалтерия предприятия 3.0 с помощью правил обмена | Можно выполнить переход с УПП на БП 3 или запускать выгрузку данных за выбранный период времени | Переносятся документы, начальные остатки и вся справочная информация | Есть фильтр по организации и множество других параметров выгрузки | Поддерживается несколько сценариев работы: как первичный полный перенос, так и перенос только новых документов | Перенос данных возможен в "1С: Бухгалтерия 3.0" версии ПРОФ, КОРП или базовую | Переход с "1С: УПП1.3" / "1С:КА 1.1" на "1С:БП3.0" с помощью правил конвертации будет максимально комфортным! | Можно бесплатно проверить перенос на вашем сервере!

48278 43450 руб.

25.02.2015    172021    307    258    

384

SALE! 10%

Перенос данных 1C Взаиморасчеты Оптовая торговля Логистика, склад и ТМЦ Файловый обмен (TXT, XML, DBF), FTP Системный администратор Программист Платформа 1С v8.3 1С:Управление торговлей 10 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Управленческий учет Платные (руб)

Можно проверить до покупки, оставьте заявку! Воспользовались более 268 компаний! Перенос данных из УТ 10.3 в УТ 11 | из УТ 10.3 в КА 2 | из УТ 10.3 в ERP. Предлагаем качественное и проверенное временем решение для перехода с УТ 10.3. Можно перенести начальные остатки, нормативно-справочную информацию и все возможные документы. При выгрузке можно установить отбор по периоду, организациям и складам. При выходе новых релизов конфигураций 1C оперативно выпускаем обновление переноса данных.

55778 50200 руб.

24.04.2015    195880    155    244    

284

SALE! 10%

Перенос данных 1C Файловый обмен (TXT, XML, DBF), FTP Программист Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Платные (руб)

Перенос данных из ERP в БП 3 | из КА 2 в БП 3 | из УТ 11 в БП 3 | из ЕРП в БП 3 | Сэкономьте время - используйте готовое решение для перехода! | Перенос разработан в формате КД 2 (правила конвертации данных) | Переносятся все возможные виды документов, начальных остатков и нормативно-справочная информация| Можно опционально выгружать каждую пару "номенклатура+характеристика" как отдельную номенклатуру | Есть выгрузка настроек счетов учета и зарплатных данных из ERP / КА 2 | Можно проверить на вашем сервере перед покупкой

55778 50200 руб.

15.04.2019    72792    184    151    

125

SALE! 10%

Перенос данных 1C Файловый обмен (TXT, XML, DBF), FTP Системный администратор Программист Платформа 1С v8.3 1С:Комплексная автоматизация 1.х 1С:Управление торговлей 10 1С:Управление производственным предприятием 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Платные (руб)

Перенос данных из ERP в УПП 1.3 | из КА 2 в КА 1.1 | из КА 2 в УПП 1.3 | из КА 2 в УТ 10.3 | из ERP в КА 1.1 | из ERP в УТ 10.3 | из УТ 11 в УТ 10.3 | из УТ 11 в УПП 1.3 | из УТ 11 в КА 1.1 | Можно переносить только новые объекты, найденные в приемнике перезаписываться не будут | Есть фильтр по организации при выгрузке данных | Оперативно обновляем на новые релизы 1С

53111 47800 руб.

28.11.2015    83618    32    126    

66
Оставьте свое сообщение