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

18.11.11

Разработка - Универсальные функции

Две функции чтения 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);

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

См. также

Вставляем картинку из буфера обмена (платформа 1С 8.3.24)

Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Задача: вставить картинку из буфера обмена на форму средствами платформы 1С.

1 стартмани

18.03.2024    2657    0    John_d    8    

53

GUID в 1С 8.3 - как с ними быть

Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Пришлось помучиться с GUID-ами немного, решил поделиться опытом, мало ли кому пригодится.

12.02.2024    4591    atdonya    22    

45

Переоткрытие внешних обработок

Универсальные функции Платформа 1С v8.3 Бесплатно (free)

На заключительных этапах, когда идет отладка или доработка интерфейса, необходимо много раз переоткрыть внешний объект. Вот один из способов автоматизации этого.

30.11.2023    3952    ke.92@mail.ru    16    

61

Валидация JSON через XDTO (включая массивы)

WEB-интеграция Универсальные функции Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

При работе с интеграциями рано или поздно придется столкнуться с получением JSON файлов. И, конечно же, жизнь заставит проверять файлы перед тем, как записывать данные в БД.

28.08.2023    8799    YA_418728146    6    

141

Печать непроведенных документов для УТ, КА, ERP. Настройка печати по пользователям, документам и печатным формам

Пакетная печать Печатные формы Адаптация типовых решений Универсальные функции Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Абонемент ($m)

Расширение для программ 1С:Управление торговлей, 1С:Комплексная автоматизация, 1С:ERP, которое позволяет распечатывать печатные формы для непроведенных документов. Можно настроить, каким пользователям, какие конкретные формы документов разрешено печатать без проведения документа.

2 стартмани

22.08.2023    2071    21    progmaster    7    

3

Расширение: Быстрые отборы через буфер [Alt+C] Копировать список, [Alt+V] Вставить список, [Ctrl+C] Копировать из файлов

Инструментарий разработчика Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 1С:Розница 2 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Зарплата и Управление Персоналом 3.x Абонемент ($m)

Копирует в буфер значения из списков, из ячеек отчетов, таблиц, настроек списков, других отборов и вставляет в выбранную настройку отбора. Работает с Объект не найден. Работает как в одной так и между разными базами 1С. Использует комбинации [Alt+C] Копировать список, [Alt+V] Вставить список. Также для копирования данных используется стандартная [Ctrl+C] (например из открытого xls, mxl, doc и т.п. файла скопировать список наименований)

1 стартмани

13.10.2022    16139    133    sapervodichka    112    

129

Система контроля ведения учета [БСП]

Универсальные функции Механизмы типовых конфигураций БСП (Библиотека стандартных подсистем) Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

В данном материале рассмотрим типовой алгоритм подсистемы контроля учета БСП в конфигурациях на примерах.

18.07.2022    7241    quazare    8    

109
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. artbear 1448 18.11.11 11:14 Сейчас в теме
А если внутри поля есть текст с точкой-запятой в кавычках, нормально прочитает?
Например, файл
клиент;адрес
ИП Иванов А.А.;"Москва;ул.Ленина;53"
прочитается верно, как 2 поля?
4. v_id 106 18.11.11 13:43 Сейчас в теме
(1) artbear, на днях специально проверю, в моем случае такого набора данных быть не может
9. cool.vlad4 2 18.11.11 14:05 Сейчас в теме
(1) Обе ф-ции грузят как положено. Проверил,
ЗЫ Только клиент и адрес_ уйдут под название колонок
artbear; v_id; +2 Ответить
11. artbear 1448 18.11.11 14:36 Сейчас в теме
(9) Спасибо.
(10) да, это верное поведение.
Рекомендую добавить в описание небольшой коммент насчет кавычек и вложенных точек с запятой, т.к. такие тексты не такая уж редкость :(
2. cool.vlad4 2 18.11.11 11:36 Сейчас в теме
а как серый кардинал к этому относится, что вы скоммуниздили его функции? ...я помнится еще весной видел эти ф-ции...
3. v_id 106 18.11.11 13:41 Сейчас в теме
(2) cool.vlad4, чукча не читатель...
описание прочти и/или опубликуй что-ть, что пройдет модерацию, потом поговорим.
5. cool.vlad4 2 18.11.11 13:49 Сейчас в теме
(3) Реагируй адекватно. Написано же
Делюсь результатом моих поисков (абсолютный копи-паст),
вот я и спросил, а The Gray Cardinal дал добро или нет. ...на этом сайте он помоему зарегистрирован.
ЗЫ
описание прочти и/или опубликуй что-ть, что пройдет модерацию, потом поговорим.
и? где в описании есть его разрешение? ф-ции один в один скопированы, есть чем гордится...
6. v_id 106 18.11.11 13:53 Сейчас в теме
(5) cool.vlad4, Публикуется с согласия автора.

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

cool.vlad4 пишет:
Реагируй адекватно

Не считай других хуже себя, эталона нравственности.
7. cool.vlad4 2 18.11.11 13:58 Сейчас в теме
(6) Я и не считаю, я просто задал вопрос, поскольку есть такая возможность и поскольку бываю на форуме скрипт-кодинга. Ты слишком нервно все воспринимаешь
Зы и почему-то у меня в браузере не было надписи, что публикуется с согласия. Приношу свои извинения.
8. v_id 106 18.11.11 14:04 Сейчас в теме
10. v_id 106 18.11.11 14:13 Сейчас в теме
cool.vlad4 пишет:
ЗЫ Только клиент и адрес_ уйдут под название колонок

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

Спасибо, что проверил!
12. cool.vlad4 2 18.11.11 16:10 Сейчас в теме
А я себе в консоль добавил и немножко видоизменил 1-ую ф-цию:
Если МенеджерВременныхТаблиц = Неопределено Тогда
		Сообщить("Включите использование временных таблиц");
	 Возврат;
    КонецЕсли;
	
	ДиалогВыбора = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
    
	ДиалогВыбора.Фильтр     = "Файл csv данных (*.csv)|*.csv";
	ДиалогВыбора.Расширение = "csv";
	
	ДиалогВыбора.Заголовок ="Выберите файлы для загрузки";

	ДиалогВыбора.ПредварительныйПросмотр     = Ложь;
	ДиалогВыбора.ИндексФильтра               = 0;
	ДиалогВыбора.ПроверятьСуществованиеФайла = Ложь;
	ДиалогВыбора.МножественныйВыбор          = Ложь;
	Если ДиалогВыбора.Выбрать() Тогда 
		Файл = Новый Файл(ДиалогВыбора.ПолноеИмяФайла);
		ВремЗапрос = Новый Запрос;
		ВремЗапрос.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц;
		ВремЗапрос.Текст =  "ВЫБРАТЬ * ПОМЕСТИТЬ " +  ИмяВремТаблицы + "	
							|ИЗ
							|	&ТЗ как тбл";
		ВремЗапрос.УстановитьПараметр("ТЗ",ЗагрузитьИзCSVвТЗ_1(Файл.Путь, Файл.Имя));
		ВремЗапрос.Выполнить();  		
	КонецЕсли;
	
Показать

// Параметры:
// "Папка" - путь к файлу без имени файла с завершающим слешем,
// "ИмяФайла" - имя файла,
// "КолПолей" - количество колонок (число).
// Функция возвращает ТаблицуЗначений с данными файла         
Функция ЗагрузитьИзCSVвТЗ_1(Папка, ИмяФайла, КолПолей=Неопределено, ИспользоватьСхему=Ложь) Экспорт	//добавить преобразование первой строки - и её загрузку	 
	
Если  ИспользоватьСхему И ЗначениеЗаполнено(КолПолей) Тогда
    Текст = "[" + ИмяФайла + "]

    |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);

	Для iCount = 0 По objRec.Fields.Count-1 Цикл
	     ТаблЗнач.Колонки.Добавить(objRec.Fields.Item(iCount).Name,АДОвТип(objRec.Fields.Item(iCount).Type)); //по Type можно смотреть тип
    КонецЦикла;

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

    Ном = 1;
    Пока Не objRec.EOF Цикл

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

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

        КонецЕсли;

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

        Для i=0 По ТаблЗнач.Колонки.Количество()-1 Цикл

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

        КонецЦикла;

        objRec.MoveNext();

        Ном = Ном + 1;

    КонецЦикла;

    objRec.Close();

   Возврат ТаблЗнач;
   
КонецФункции
Показать

///На самом деле типов дофига и больше
Функция АДОвТип(type)  Экспорт
	Если type=3 Тогда 
		Возврат Новый ОписаниеТипов("Число",,Новый КвалификаторыЧисла(10)); 
	ИначеЕсли type=5 Тогда
	    Возврат Новый ОписаниеТипов("Число",,Новый КвалификаторыЧисла(15,2)); 
	Иначе
		Возврат Новый ОписаниеТипов("Строка",,Новый КвалификаторыСтроки(256));
	КонецЕсли;
КонецФункции
Показать
13. artbear 1448 18.11.11 16:46 Сейчас в теме
14. svetlanapk 12.01.12 21:43 Сейчас в теме
Плагиат и есть плагиат, куда смотрят модераторы!!!
15. support 4484 12.01.12 21:45 Сейчас в теме
18. v_id 106 13.01.12 16:00 Сейчас в теме
(15) support,
(all) думаю, ники svetlanapk, Administrator это клоны пользователя infoooo, который очень любит использовать чужие (и мою, в том числе) обработки в своих сборках, что было неоднократно доказано (ссылку не даю, она забанена).

Думаю администрации нужно повнимательнее отнестись к клонам и накруткам на этом сайте.
16. Administrator 12.01.12 22:03 Сейчас в теме
17. support 4484 12.01.12 22:24 Сейчас в теме
(16) Administrator, так вроде получено разрешение. Хотелось бы конечно, чтобы сам http://infostart.ru/profile/1115/ подтвердил.
19. v_id 106 13.01.12 19:52 Сейчас в теме
(16) Administrator, а ты чтобы не палисться перелогиниться не забывай.
20. serggo 16.04.12 17:18 Сейчас в теме
Народ, а у меня несмотря на файл 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 -- не помогло (((
21. zfilin 2337 18.07.12 22:27 Сейчас в теме
(20) В коде есть небольшая неточность. Из-за того, что по-умолчанию метод "Записать" объекта "ТекстовыйДокумент" сохраняет в кодировке UTF8 (см. синтакс-помощник), в файле Schema.ini в начале появляются лишние символы, которые обычно не видны в просмотрщике. И кажется, что с файлом все в порядке.

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

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

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

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

Так все работает.
Yimaida; wolder; denxp2009; ZOMI; Myskyl; +5 Ответить
24. Myskyl 04.10.13 20:32 Сейчас в теме
(21) zfilin, Благодарю за подсказку
ТекстДок.Записать(Папка + "Schema.ini", КодировкаТекста.ANSI);
так действительно лучше выглядит.
22. yuraos 991 11.02.13 09:51 Сейчас в теме
Для работы с ADO использую эту подсистему
Прочитал про GameWithFire.dll и обрадовался, щас ускорю выгрузку ADORecordset в ТЗ.
Но обнаружилось, что на сервере (где мне это особенно интересно сделать)
подключить ВК невозможно (ограничение платформы как под 8.1, так и под 8.2, у меня - 8.1).

Не знаете, как можно обойти это ограничение ???
23. SANILLA 29.09.13 22:24 Сейчас в теме
оооо спасибо, искал, кажется то что надо
25. Xershi 1474 20.10.15 16:35 Сейчас в теме
Что-то у меня не читает файл. Коллекция с пустыми ячейками.
Но у меня разделитель ",".
//|Format=Delimited(;)
	|Format=Delimited(,)

Не помогло.
26. Xershi 1474 21.10.15 12:52 Сейчас в теме
Похоже проблема в том что файл содержит для каждой колонки обертку "". Так еще в самих ячейках есть разделитель. Придется писать свой парсер.
27. yur4ik9408 34 30.06.16 11:34 Сейчас в теме
а как на счет больших файлов, у которых больше 255 колонок?
кто-то сталкивался с данной проблемой?
28. Xershi 1474 30.06.16 13:04 Сейчас в теме
(27) yur4ik9408, у моего парсера количество колонок роли не играет, вопрос только в стандарте и размере самого файла.
29. yur4ik9408 34 30.06.16 18:38 Сейчас в теме
(28) Xershi, А где можно посмотреть на ваш парсер?
30. Xershi 1474 30.06.16 19:34 Сейчас в теме
31. kuzyara 1900 22.08.16 15:48 Сейчас в теме
Для небольших файлов можно использовать такой код.
32. shamahn 1 31.03.17 00:50 Сейчас в теме
3 часа потратил на отладку - еле нашел ошибку.
Строчка
ТекстДок.Записать(Папка + "Schema.ini"); 

в моем случае записывала в UTF-8 с BOM и драйвер ни в какую не хотел есть файл Schema.ini
Все решается просто заменой строки на
ТекстДок.Записать(Папка + "Schema.ini", КодировкаТекста.ANSI);


Не надо меня благодарить
33. wolder 129 02.10.19 10:44 Сейчас в теме
(32) ещё в (21) комменте 5 лет назад было написано :)
34. gradi 5 30.12.19 21:30 Сейчас в теме
Спасибо, Очень помогли.
35. Shurkec 22.01.20 11:57 Сейчас в теме
Попробовал эту функцию на очень простом csv-файле:
Колонка 1;Колонка 2;Колонка 3
1111;222;333
reter;gfhf;vbcv
Всё читается как одна колонка. Т.е. разделитель точка с запятой игнорируется. Как можно решить эту проблему?
36. just86 07.06.20 17:40 Сейчас в теме
А какие кодировки доступны в блоке
|CharacterSet=ANSI
?

Если указать utf8, utf-8 - ошибка. Если ansi, oem - ошибки нет
Оставьте свое сообщение