Чтение csv файлов

05.07.24

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

Здесь я расскажу про алгоритм чтения csv в 1С, а также про быстрое чтение csv с помощью регулярных выражений.

Казалось бы, чего тут рассказывать, но когда я столкнулся с задачей загрузки csv в 1С, то обнаружил, что нигде - ни в функциях глобального контекста, ни в интернете нет подходящего метода чтения, который учитывал бы все нюансы. 

Обычно предлагается что-то вроде СтрРазделить(СтрокаCsv, ",") - тогда мы не учитываем запятые, которые являются частью значения.

Например: имеем структуру Имя,Возраст,Адрес - 3 колонки

и кортеж "Иван",25,"Город Санкт-Петербург, улица Маршала Блюхера 5 литера ""А"""

Разделив эту строку просто по запятой, получим: 

"Иван" | 25 | Город Санкт-Петербург | улица Маршала Блюхера 5 литера ""А"" - 4 значения и лишние кавычки.

Решение проблемы:

1. Последовательное чтение

Можно посимвольно читать и анализировать строку согласно правилам csv:

 
 Функция посимвольного чтения csv строки
Любая корректная csv строка будет преобразовываться в соответствующий массив значений, но на больших файлах посимвольный разбор строк будет работать довольно медленно.

Поэтому есть второй, в 3 раза более быстрый вариант.

2. Регулярные выражения

Можно выполнять ту же процедуру, используя регулярные выражения - но тогда вам потребуется версия платформы 8.23, либо виндовый сервер, позволяющий использовать COM-объект vb.

 
 Функция чтения csv строки с помощью регулярных выражений

Полноценная функция преобразования csv файла в таблицу значений выглядит примерно так:

 
Csv в таблицу значений
Функция ФайлCSVВТаблицуЗначений(АдресФайлаВХ, Разделитель = ",", ДопПараметры = Неопределено) Экспорт      
	
	ДД = ПолучитьИзВременногоХранилища(АдресФайлаВХ);
	
	Поток = ДД.ОткрытьПотокДляЧтения();
	Чтение =  Новый ЧтениеТекста(Поток);
	
	Если ЗначениеЗаполнено(ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(ДопПараметры, "Шапка", Неопределено)) Тогда
		Шапка = ДопПараметры.Шапка;
	Иначе
		Шапка = Чтение.ПрочитатьСтроку();
	КонецЕсли;
	
	МассивКолонок = РазложитьСрокуCSVВМассивподстрок(Шапка, Разделитель);
	
	ТЗ = Новый ТаблицаЗначений;   
	
	КвСтроки = Новый КвалификаторыСтроки(999);
	КвЧисла  = Новый КвалификаторыЧисла(25, 2);
	КвДаты   = Новый КвалификаторыДаты(ЧастиДаты.ДатаВремя);
	
	ТипОбщий  = Новый ОписаниеТипов("Строка, Число, Дата, Булево", КвЧисла, КвСтроки, КвДаты);
	
	Для каждого Колонка Из МассивКолонок Цикл 
		
		Если ЗначениеЗаполнено(Колонка) Тогда  
			
			КолонкаТехИмя = СтроковыеФункцииКлиентСервер.ЗаменитьОдниСимволыДругими(""", !@#$%^&*()*-+=/\", Колонка, "");
			ТЗ.Колонки.Добавить(КолонкаТехИмя, ТипОбщий, Колонка);
			
		КонецЕсли;
		
	КонецЦикла;  
	
	
	КоличествоКолонок = ТЗ.Колонки.Количество(); 
	СчетОшибок = 0;    
	РегулярноеВыражение = РегулярноеВыражениеДляCSV(Разделитель);	
	
	ЧтениеПродолжается = Истина;
	Пока ЧтениеПродолжается Цикл     
		
		Строка = Чтение.ПрочитатьСтроку();
		
		Если Строка <> Неопределено Тогда  
			
			МассивЗначений = РазложитьСтрокуCSVВМассивПодстрок_Регулярка(Строка, РегулярноеВыражение);
			
			Если МассивЗначений.Количество() <> КоличествоКолонок Тогда
				
				СчетОшибок = СчетОшибок + 1;  
				ЗаписьЖурналаРегистрации("Не удалось разобрать csv строку!", УровеньЖурналаРегистрации.Предупреждение, ,, Строка);
				Продолжить;
				
			КонецЕсли;
			
			НовСтр = ТЗ.Добавить();
			Для НомКол = 0 По КоличествоКолонок - 1 Цикл        
				НовСтр[НомКол] = МассивЗначений[НомКол];            
			КонецЦикла;
			
		Иначе
			
			ЧтениеПродолжается = Ложь;
			Поток.Закрыть();
			
		КонецЕсли;
		
	КонецЦикла; 
	
	Возврат ТЗ;	
	
КонецФункции // ()

На этом у меня, собственно, все)

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

Вступайте в нашу телеграмм-группу Инфостарт

csv csv-файл цсв преобразовать csv в ТЗ csv в таблицу значений регулярные выражения загрузка импорт быстрая загрузка csv

См. также

НДС 22% Учетные задачи ККМ Файловый обмен (TXT, XML, DBF), FTP 1С 8.3 1С:Комплексная автоматизация 1.х 1С:Управление торговлей 10 1С:Управление производственным предприятием Бухгалтерский учет Налоговый учет НДС Платные (руб)

Готовое обновление для конфигурации 1С:Управление торговлей 10.3, 1С:Комплексная автоматизация 1.1 , 1С:Управление производственным предприятием 1.3 обеспечивающее полную поддержку новой ставки НДС 22%. Для 1С:УТ 10.3 реализована поддержка печати чеков ККМ, а также Правила обмена с 1С:БП 3.0. Решение встраивает необходимые изменения в перечисления и документы, включая торговые операции и печатные формы.

12200 руб.

16.12.2025    7528    83    0    

78

SALE! 15%

Перенос данных 1C Файловый обмен (TXT, XML, DBF), FTP Системный администратор Программист 1С:Предприятие 8 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. Не требуется синхронного обновления правил после обновления другой конфигурации, участвующей в обмене. Типовой обмен через планы обмена кнопкой Синхронизация вручную или автоматически по расписанию, или вручную обработкой.

22650 руб.

12.06.2017    158282    947    317    

477

Перенос данных 1C Файловый обмен (TXT, XML, DBF), FTP Системный администратор Программист 1С:Предприятие 8 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" с помощью правил конвертации будет максимально комфортным! | Можно бесплатно проверить перенос на вашем сервере!

50050 руб.

25.02.2015    186690    349    284    

411

SALE! 10%

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

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

38000 34200 руб.

15.12.2021    32791    243    61    

183

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

Правила переноса кадровых и расчетных данных и справочной информации из "1С:УПП1.3" или "1С:КА 1.1" в "1С:ЗУП 3.1 | Разработан в формате КД 2 (правила конвертации данных) | При выгрузке есть фильтр по организациям | Обновляется при выходе новых релизов 1С | Развитие алгоритмов | Расчетные документы переносятся в документ "Перенос данных" | Создаются документы "Начальная штатная расстановка" и "Начальная задолженность по зарплате", переносятся кадровые документы

58000 руб.

29.10.2018    61542    77    129    

76

SALE! 10%

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

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

38000 34200 руб.

23.07.2020    66352    309    86    

248

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

Регулярный обмен, выгрузка, перенос из КА 1.1, УПП 1.3, УТ 10.3 для обмена с любыми конфигурациями, поддерживающими обмен в формате EnterpriseData (КД3) - БП 3.0, ERP, КА 2, УТ 11, Розница 3, УНФ 3 и другими. Правила для старых и доработанных конфигураций не требуют синхронного обновления и совместимы с новыми и будущими конфигурациями. Обмен по расписанию, через папку, FTP, почту.

16531 руб.

18.02.2016    200140    662    543    

559
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. SerVer1C 1041 05.07.24 15:11 Сейчас в теме
Вообще-то, для правильного CSV надо подбирать такой разделитель, который НЕ будет встречаться в ячейках. И тогда можно будет сразу прочитать весь файл в табличный документ без всяких парсеров.
Rais96; NorraSaltolinen; Cерый; +3 2 Ответить
2. comptr 57 05.07.24 18:56 Сейчас в теме
(1) Как раз в правильном CSV-файле разделителем будет запятая, ведь CSV - сокращение Comma-Separated Values :)
HansGlorias; DABadyanov; svbel85; +3 Ответить
3. aximo 2604 07.07.24 11:52 Сейчас в теме
В бсп есть готовая фунция разложить строку в массив подстрок, с любыми разделителями, группой разделителей!

Работает во всех типовых
4. webester 26 07.07.24 12:59 Сейчас в теме
(3)Я тебе больше скажу, такая функция реализована и средствами встроенного языка. То есть вшита в платформу. А в БСП судя по всему оставлена уже больше для совместимости. Но автор говорит, что медленно работает.
5. HansGlorias 29 07.07.24 17:26 Сейчас в теме
(3)
(4)

Просто разделить строку по разделителю не всегда сработает, в этом и проблема.
Бывают ситуации, когда одно из значений содержит в себе разделитель, такое значение обязательно обрамлено кавычками.
6. bayselonarrend 3062 07.07.24 22:39 Сейчас в теме
(5)Почему нельзя заменить парные кавычки на какой-нибудь символ/набор символов, который точно в природе не встречается, а затем разделить не по запятой, а по "," . После чего заменить свой набор символов на кавычки обратно
7. HansGlorias 29 07.07.24 23:42 Сейчас в теме
(6)
Не обязательно каждое значение обрамлено в кавычки.

Пример из текста: "Иван",25,"Город Санкт-Петербург, улица Маршала Блюхера 5 литера ""А""" - легитимная csv строчка, 25 без кавычек и по "," не разделится.
BlinOFF; bayselonarrend; +2 Ответить
8. bayselonarrend 3062 07.07.24 23:49 Сейчас в теме
(7)Да, не посмотрел. Не думал, что бывают настолько замученные форматы, чтобы одна часть колонок с кавычками, а вторая - нет
9. booksfill 08.07.24 10:16 Сейчас в теме
Если я правильно понял, то мы работаем не с CSV файлом, а файлом строго определенной структуры.
Зачем нужен посимвольный обход или регулярка (кстати, тоже совсем не бесплатная) немного неясно.

Было бы любопытно сравнить производительность вот этого с тем же, но решаемом регулярками.:
res = СтрРазделить(СтрокаВовсеДажеНеCsv, ",");
res[0] - имя
res[1] - возраст
адрес = "";
разделитель = "";
Для i = 2 По res.Количество() - 1 Цикл
  адрес = адрес + разделитель + res[i];
  разделитель  = ","; 	
КонецЦикла; 
Показать


Тут идут извращения, не относящиеся к задаче, типа удаления кавычек Лучше бы их убрать, хотя уверен, что удаление открывающей и закрывающих кавычек на производительности практически не скажется.

У меня старая платформа под рукой, поэтому возможно, что com объект для разбора регулярок проиграет.
Хотелось бы посмотреть сравнение с более быстрым вариантом - с использованием средств самой платформы.
10. kuzyara 2238 09.07.24 07:29 Сейчас в теме
Решал подобную задачу - 7 правил RFC 4180

Если есть желание сравнить с существующими способами - возьмите файл payouts_details10000строк.csv, получите время чтения, сравните с нижепреведённой таблицей:
Native - 28 578 мс
ADODB - 8 336 мс
GWF - 7 236 мс

Так же попробуйте загрузить "невалидный" csv файл:
"ZF6A-11";"";""
"Прокладка выпускного коллектора металлическая";"190016010;3056046;31-024515-00;693.820;70-25112-00;71-24068-10;71-34208-00;JE138;JF206;0693820;078 253 039;103 632;103 632 015;103632685;103 633;103 633 016;1257319;256905;29-0078;302530115433;30694/1507;343412;433253115;433253115;433253115A;433253115A;460052;51157;70-24068-00;71-24068-00;AG7524;";"AUDI-PEGASO-VOLKSWAGEN-VOLVO  #  1978->  #   DV,DW,CP,1S,1G,ACT,D24,D24T,D24TIC     1595/1781/2383 cc    DIESEL"
ACDelco;OPEL Astra J/Insignia /для 17"диска;2357.00
a
a,b;c
a;b
c
"a;b";c
"a""b";c
"""";c
";";c
;
a;"b
c";d
a;"b
c;

d;;
e";d
a;"b""
c""";d
a;"b
"с"
a;""b;";"
aaa;"";"ccc"
Показать
ведь входящие данные далеко не всегда идеалены)
HansGlorias; +1 Ответить
11. kuzyara 2238 09.07.24 08:02 Сейчас в теме
(10) Сравнил со своей нативной реализацией - у вас без многострочных полей и в 2 раза быстрее)
HansGlorias; +1 Ответить
12. frkbvfnjh 818 06.02.25 10:13 Сейчас в теме
В каком релизе уже добавят поддержку загрузки табличного документа из CSV? Что то формат все устаревает и устаревает, да ни как не устареет. Должны были еще 8.0 добавить. Там блин работы на пару часов на С++ написать код и сколько миллионов человеко часов разработчиков прикладных решений было бы сэкономлено и сколько миллионов человеко часов обычных пользователей было бы сэкономлено в виду скорости загрузки из CSV если бы код был написан на уровне платформы?
AndrewVVS; +1 Ответить
Для отправки сообщения требуется регистрация/авторизация