Чтение больших текстовых файлов (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.Count1 Цикл

            НовСтр[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 не будет опубликован. Обязательные поля помечены *