Универсальный парсер CSV-файлов


В интернете довольно много примеров, как парсить CSV-файл.
Но ни один из них не смог сразу прочитать правильно CSV-файл от MS Exchange!
Данный парсер не только может корректно это сделать, но и читает любые CSV-файлы от других программ.

CSV (от англ. Comma-Separated Values — значения, разделённые запятыми) — текстовый формат, предназначенный для представления табличных данных. Каждая строка файла — это одна строка таблицы. Значения отдельных колонок разделяются разделительным символом (delimiter) — запятой (,). Однако, большинство программ вольно трактует стандарт CSV и допускают использование иных символов в качестве разделителя. 

 

За основу кода взята типовая функция РазложитьСтрокуВМассивПодстрок.

// Функция "расщепляет" строку на подстроки, используя заданный
//  разделитель. Разделитель может иметь любую длину.
//  Если в качестве разделителя задан пробел, рядом стоящие пробелы
//  считаются одним разделителем, а ведущие и хвостовые пробелы параметра Стр
//  игнорируются.
//  Например,
//  РазложитьСтрокуВМассивПодстрок(",ку,,,му", ",") возвратит массив значений из пяти элементов,
//  три из которых - пустые строки, а
//  РазложитьСтрокуВМассивПодстрок(" ку   му", " ") возвратит массив значений из двух элементов
//
// Параметры:
//  Стр -    строка, которую необходимо разложить на подстроки.
//      Параметр передается по значению.
//  Разделитель -  строка-разделитель, по умолчанию - запятая.
//
//
// Возвращаемое значение:
//  массив значений, элементы которого - подстроки
//
Функция РазложитьСтрокуВМассивПодстрок(Знач Стр, Разделитель = ",") Экспорт

МассивСтрок = Новый Массив();
Если Разделитель = " " Тогда
Стр = СокрЛП(Стр);
Пока Истина Цикл
Поз = Найти(Стр,Разделитель);
Если Поз=0 Тогда
МассивСтрок.Добавить(Стр);
Возврат МассивСтрок;
КонецЕсли;
МассивСтрок.Добавить(Лев(Стр,Поз-1));
Стр = СокрЛ(Сред(Стр,Поз));
КонецЦикла;
Иначе
ДлинаРазделителя = СтрДлина(Разделитель);
Пока Истина Цикл
Поз = Найти(Стр,Разделитель);
Если Поз=0 Тогда
МассивСтрок.Добавить(Стр);
Возврат МассивСтрок;
КонецЕсли;
МассивСтрок.Добавить(Лев(Стр,Поз-1));
Стр = Сред(Стр,Поз+ДлинаРазделителя);
КонецЦикла;
КонецЕсли;

КонецФункции // глРазложить

Это функция дополнена параметром СимволВыделения! Этот параметр решает проблему выделения ячеек, в которых присутствует разделитель.

В разработке использовался код: Работа в 1С с CSV файлами. 

Для ознакомления в модуле есть код: //infostart.ru/public/98398/.

Обновление от 30.10.2026

Дописан алгоритм вычленения ячеек, в которых есть и символ разделитель, и символ выделения.

Например, строка: «Ответ на письмо», мой друг» доставлен».  Вернятся как: Ответ на письмо», мой друг» доставлен.

В прошлой версии результат был: Ответ на письмо| мой друг» доставлен.

16 Comments

  1. Yashazz

    Автор, а вы в курсе, что читать csv-файлы как текст — это жесть, допустимая только при маленьком их размере или откровенно кривом формате? Это я к тому, что заголовочек у публикации больно сомнителен — «универсальный парсер», ага. Универсальные, во-первых, давно есть, а во-вторых, не через «Разложить строку» делаются)

    Reply ↓
  2. Xershi

    (1) Yashazz, покажите мне универсальный, ссылку пожалуйста!

    Давайте я вам дам файл, а вы мне его корректно вашим парсером разложите?

    Reply ↓
  3. V.Nikonov

    А как быть со строковыми колонками которые в тексте содержат разделитель? По стандарту такие значения заключают в кавычки, и тогда разделитель до закрывающей кавычки не анализируется!

    Reply ↓
  4. Xershi

    (3) V.Nikonov, после тестирования парсера на большом массиве строк, доработал код. Но пока нет времени обновить файл публикации. Так что в скором времени и этот вопрос будет решен.

    Но даже в текущей версии такую строку распарсит корректно, если рядом не будет символа выделения!

    Reply ↓
  5. Xershi

    Немного статистики. CSV-файл более 2 ГБ обработка не смогла даже прочитала, т.к. просто вылетела платформа. А вот файл менее 1 ГБ обработало, но на 97% не хватило памяти на сервере и тоже вылет (процесс 1С использовал почти 3 гига оперативной памяти).

    Файл в 680 МБ с трудом дочитало (процесс 1С использовал почти 2.5 гига оперативной памяти).

    Файлы с меньшим объемом без проблем читает.

    Все операции выполнялись на 32-битном процессе. Как поведет себя обработка в регламентном задании, пока не могу сказать, но там используется 64-битный процесс, поэтому ограничение на память там больше.

    Познавательно по этому поводу написано на этом сайте: http://www.viva64.com/ru/k/0036/

    Reply ↓
  6. BigB

    (0) функция РазложитьСтрокуВМассивПодстрокMSExchange работает неверно!

    Как видно из вложений в Excel csv открывается правильно, а в 1С неправильно.

    Из Вашей обработки я взял только одну функцию.

    Reply ↓
  7. Xershi

    (6) BigB, вы настройки для своего конфигурации сделали? На скриншотах этого я не увидел.

    Reply ↓
  8. BigB

    (7) повторю еще раз: Из Вашей обработки я взял только одну функцию.

    Запускал её с параметрами так:

    МассивКол = РазложитьСтрокуВМассивПодстрокMSExchange(Строка, «;», «»»»);
    Reply ↓
  9. Xershi

    (8) BigB, так с такими параметрами, она будет работать по другому. Как типовая. Используйте полный список параметров!

    Reply ↓
  10. BigB

    (9) приложил настройки из обработки.

    Только я не понял, чем они отличаются от моих, что я выложил ранее?

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

    Reply ↓
  11. Xershi

    (10) BigB, у вас шапка есть? Похоже строки шапки либо нет, либо разделитель у вас не тот. Взять только эту функцию будет не достаточно для корректной работы всего алгоритма! Используйте обработку полностью!

    Reply ↓
  12. BigB

    (11) Вы почему не умеете читать, то, что Вам пишут? Я же Вам только, что написал и картинки приложил. Повторю ещё раз: При использовании Вашей обработки с настройками, которые я уже выкладывал — я получил кривую шапку (только последнюю колонку) и пустую табличную часть. В личку могу выслать csv файл, чтобы Вы сами убедиться, что функция РазложитьСтрокуВМассивПодстрокMSExchange не работает.

    Reply ↓
  13. Xershi

    (12) BigB, скиньте в личку ваш файл. Важным нюансом также является, чтобы названия колонок шапки писались слитно!

    Думаю именно из-за этого у вас и не работает все. Поэтому, если вы весь алгоритм работы не разобрали, то такой результат и получили!

    Reply ↓
  14. Xershi

    Ваш файл не по стандарту сделан.

    1. а.) В шапке нет разделителя! б.) И слова содержат пробелы. Для а.) я делал обновление http://infostart.ru/public/411000/. Для б.) убрать пробелы или заточить обработку под удаление пробелов в шапке.

    2. У вас разное количество колонок. В шапке 35, а в данных 36. Решается добавлением в шапку 36 колонки.

    Reply ↓
  15. kuzyara

    Работающий код.

    Reply ↓
  16. ZLENKO

    Реализовано в версии 8.3.6.1977 функции: СтрРазделить(), СтрСоединить()

    Читаем тут: https://infostart.ru/public/366865/

    Reply ↓

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *