Чтение больших текстовых файлов (CSV)

Две функции чтения CSV файла и возврата Таблицы Значений с данными файла с использованием COM объекта ADODB.Recordset и внешней компоненты GameWithFire.

Не люблю изобретать велосипед, поэтому первое что делаю при необходимости его изобрести пользуюсь поиском.

Делюсь результатом моих поисков (абсолютный копи-паст), который, думаю, поможет и другим, на форуме есть пара не закрытых веток на эту тему. А для моего случая (загрузка большого количества csv файлов в ТЗ) — лучше и не надо.

Файлы с кавычкими и вложенными запятым обрабатываются верно. Например файл с содержанием:
клиент;адрес
ИП Иванов А.А.;»Москва;ул.Ленина;53″

вернет ТЗ в 2 колонки

клиент адрес
ИП Иванов А.А. Москва;ул.Ленина;53

 

Спасибо автору данного решения The gray Cardinal.

Публикуется с согласия автора.

Первоисточник и сами функции


Функция ПрочитатьCSV(Папка, ИмяФайла, КолПолей)

    // Параметры:

    // «Папка» — путь к файлу без имени файла с завершающим слешем,

    // «ИмяФайла» — имя файла,

    // «КолПолей» — количество колонок (число).

    // Функция возвращает ТаблицуЗначений с данными файла.

    Текст = «[» + ИмяФайла + «]

    |ColNameHeader=False

    |Format=Delimited(;)

    |TextDelimiter=none

    |CharacterSet=ANSI

    |»;

    Для ы = 1 По КолПолей Цикл

        Текст = Текст + «Col» + ы + «=Field» + ы + » Text» + Символы.ПС;

    КонецЦикла;

    ТекстДок = Новый ТекстовыйДокумент;

    ТекстДок.УстановитьТекст(Текст);

    ТекстДок.Записать(Папка + «Schema.ini»);

    objRec = Новый COMОбъект(«ADODB.Recordset»);

    strQuery = «SELECT * FROM [» + ИмяФайла + «]»;

    strConn = «Provider=Microsoft.Jet.OLEDB.4.0;Data Source=» + Папка + «;Extended Properties=»»text;»»»;

    adOpenStatic = 3;

    adLockOptimistic = 3;

    adCmdText = 1;

    ТаблЗнач = Новый ТаблицаЗначений;

    Для ы = 1 По КолПолей Цикл

        ТаблЗнач.Колонки.Добавить();

    КонецЦикла;

    objRec.Open(strQuery, strConn, adOpenStatic, adLockOptimistic, adCmdText);

    КолСтрок = objRec.RecordCount;

    Ном = 1;

    Пока Не objRec.EOF Цикл

        Если Ном % 500 = 0 Тогда

            Состояние(ИмяФайла + » » + Ном + » из » + КолСтрок);

        КонецЕсли;

        НовСтр = ТаблЗнач.Добавить();

        Для i=0 По objRec.Fields.Count—1 Цикл

            НовСтр[i] = Строка(objRec.Fields(i).Value);

        КонецЦикла;

        objRec.MoveNext();

        Ном = Ном + 1;

    КонецЦикла;

    objRec.Close();

    Возврат ТаблЗнач;

КонецФункции


Функция ПрочитатьCSV_2(Папка, ИмяФайла, КолПолей)

    // Параметры:

    // «Папка» — путь к файлу без имени файла с завершающим слешем,

    // «ИмяФайла» — имя файла,

    // «КолПолей» — количество колонок (число).

    // Функция возвращает ТаблицуЗначений с данными файла.

    Текст = «[» + ИмяФайла + «]

    |ColNameHeader=False

    |Format=Delimited(;)

    |TextDelimiter=none

    |CharacterSet=ANSI

    |»;

    Для ы = 1 По КолПолей Цикл

        Текст = Текст + «Col» + ы + «=Field» + ы + » Text» + Символы.ПС;

    КонецЦикла;

    ТекстДок = Новый ТекстовыйДокумент;

    ТекстДок.УстановитьТекст(Текст);

    ТекстДок.Записать(Папка + «Schema.ini»);

    objRec = Новый COMОбъект(«ADODB.Recordset»);

    strQuery = «SELECT * FROM [» + ИмяФайла + «]»;

    strConn = «Provider=Microsoft.Jet.OLEDB.4.0;Data Source=» + Папка + «;Extended Properties=»»text;»»»;

    adOpenStatic = 3;

    adLockOptimistic = 3;

    adCmdText = 1;

    objRec.Open(strQuery, strConn, adOpenStatic, adLockOptimistic, adCmdText);

    ПодключитьВнешнююКомпоненту(«GameWithFire.ADOUtils»);

    ADOUtils = Новый(«AddIn.ADOUtils»);

    Возврат ADOUtils.ADORecordsetToValueTable(objRec);

КонецФункции

33 Comments

  1. artbear

    А если внутри поля есть текст с точкой-запятой в кавычках, нормально прочитает?

    Например, файл

    клиент;адрес

    ИП Иванов А.А.;»Москва;ул.Ленина;53″

    прочитается верно, как 2 поля?

    Reply ↓
  2. cool.vlad4

    а как серый кардинал к этому относится, что вы скоммуниздили его функции? …я помнится еще весной видел эти ф-ции…

    Reply ↓
  3. v_id

    (2) cool.vlad4, чукча не читатель…

    описание прочти и/или опубликуй что-ть, что пройдет модерацию, потом поговорим.

    Reply ↓
  4. v_id

    (1) artbear, на днях специально проверю, в моем случае такого набора данных быть не может

    Reply ↓
  5. cool.vlad4

    (3) Реагируй адекватно. Написано же

    Делюсь результатом моих поисков (абсолютный копи-паст),

    вот я и спросил, а The Gray Cardinal дал добро или нет. …на этом сайте он помоему зарегистрирован.

    ЗЫ

    описание прочти и/или опубликуй что-ть, что пройдет модерацию, потом поговорим.

    и? где в описании есть его разрешение? ф-ции один в один скопированы, есть чем гордится…

    Reply ↓
  6. v_id

    (5) cool.vlad4, Публикуется с согласия автора.

    Перед тем как пост будет опубликован он проходит модерацию, где админ задает такой же вопрос и получает ответ.

    cool.vlad4 пишет:

    Реагируй адекватно

    Не считай других хуже себя, эталона нравственности.

    Reply ↓
  7. cool.vlad4

    (6) Я и не считаю, я просто задал вопрос, поскольку есть такая возможность и поскольку бываю на форуме скрипт-кодинга. Ты слишком нервно все воспринимаешь

    Зы и почему-то у меня в браузере не было надписи, что публикуется с согласия. Приношу свои извинения.

    Reply ↓
  8. v_id

    (7) cool.vlad4, ок!

    Reply ↓
  9. cool.vlad4

    (1) Обе ф-ции грузят как положено. Проверил,

    ЗЫ Только клиент и адрес_ уйдут под название колонок

    Reply ↓
  10. v_id
    cool.vlad4 пишет:

    ЗЫ Только клиент и адрес_ уйдут под название колонок

    ИМХО, так и задумано, для универсальности.

    Спасибо, что проверил!

    Reply ↓
  11. artbear

    (9) Спасибо.

    (10) да, это верное поведение.

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

    Reply ↓
  12. cool.vlad4
    Reply ↓
  13. artbear

    (12) что за консоль?

    Reply ↓
  14. svetlanapk

    Плагиат и есть плагиат, куда смотрят модераторы!!!

    Reply ↓
  15. support

    (14) svetlanapk, где плагиат?

    Reply ↓
  16. Administrator

    См. выше support

    Reply ↓
  17. support

    (16) Administrator, так вроде получено разрешение. Хотелось бы конечно, чтобы сам http://infostart.ru/profile/1115/ подтвердил.

    Reply ↓
  18. v_id

    (15) support,

    (all) думаю, ники svetlanapk, Administrator это клоны пользователя infoooo, который очень любит использовать чужие (и мою, в том числе) обработки в своих сборках, что было неоднократно доказано (ссылку не даю, она забанена).

    Думаю администрации нужно повнимательнее отнестись к клонам и накруткам на этом сайте.

    Reply ↓
  19. v_id

    (16) Administrator, а ты чтобы не палисться перелогиниться не забывай.

    Reply ↓
  20. serggo

    Народ, а у меня несмотря на файл schema.ini всё равно читает, как будто разделитель — запятые (((( Помогите!!! Что делать?

    [Cписок2.txt]

    ColNameHeader=True

    Format=Delimited(;)

    TextDelimiter=none

    CharacterSet=ANSI

    Col1=Field1 Text

    Col2=Field2 Text

    Col3=Field3 Text

    Col4=Field4 Text

    Col5=Field5 Text

    Col6=Field6 Text

    PS: если кто скажет переименуй в csv — неповерю, проверял. Также смотрел остальные параметры schema.ini — не помогло (((

    Reply ↓
  21. zfilin

    (20) В коде есть небольшая неточность. Из-за того, что по-умолчанию метод «Записать» объекта «ТекстовыйДокумент» сохраняет в кодировке UTF8 (см. синтакс-помощник), в файле Schema.ini в начале появляются лишние символы, которые обычно не видны в просмотрщике. И кажется, что с файлом все в порядке.

    На самом деле строчка

    ТекстДок.Записать(Папка + «Schema.ini»);

    должна выглядеть так:

    ТекстДок.Записать(Папка + «Schema.ini», КодировкаТекста.ANSI);

    Так все работает.

    Reply ↓
  22. yuraos

    Для работы с ADO использую эту подсистему

    Прочитал про GameWithFire.dll и обрадовался, щас ускорю выгрузку ADORecordset в ТЗ.

    Но обнаружилось, что на сервере (где мне это особенно интересно сделать)

    подключить ВК невозможно (ограничение платформы как под 8.1, так и под 8.2, у меня — 8.1).

    Не знаете, как можно обойти это ограничение ???

    Reply ↓
  23. SANILLA

    оооо спасибо, искал, кажется то что надо

    Reply ↓
  24. Myskyl

    (21) zfilin, Благодарю за подсказку

    ТекстДок.Записать(Папка + «Schema.ini», КодировкаТекста.ANSI);

    так действительно лучше выглядит.

    Reply ↓
  25. Xershi

    Что-то у меня не читает файл. Коллекция с пустыми ячейками.

    Но у меня разделитель «,».

    //|Format=Delimited(;)
    |Format=Delimited(,)

    Не помогло.

    Reply ↓
  26. Xershi

    Похоже проблема в том что файл содержит для каждой колонки обертку «». Так еще в самих ячейках есть разделитель. Придется писать свой парсер.

    Reply ↓
  27. yur4ik9408

    а как на счет больших файлов, у которых больше 255 колонок?

    кто-то сталкивался с данной проблемой?

    Reply ↓
  28. Xershi

    (27) yur4ik9408, у моего парсера количество колонок роли не играет, вопрос только в стандарте и размере самого файла.

    Reply ↓
  29. yur4ik9408

    (28) Xershi, А где можно посмотреть на ваш парсер?

    Reply ↓
  30. Xershi

    (29) yur4ik9408, в моих публикациях. http://infostart.ru/public/410803/

    Reply ↓
  31. kuzyara

    Для небольших файлов можно использовать такой код.

    Reply ↓
  32. shamahn

    3 часа потратил на отладку — еле нашел ошибку.

    Строчка

    ТекстДок.Записать(Папка + «Schema.ini»); 

    в моем случае записывала в UTF-8 с BOM и драйвер ни в какую не хотел есть файл Schema.ini

    Все решается просто заменой строки на

    ТекстДок.Записать(Папка + «Schema.ini», КодировкаТекста.ANSI);

    Не надо меня благодарить

    Reply ↓
  33. wolder

    (32) ещё в (21) комменте 5 лет назад было написано 🙂

    Reply ↓

Leave a Comment

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