|
Чем загрузить "сложный" CSV ? | ☑ | ||
---|---|---|---|---|
0
Smallrat
31.05.13
✎
13:47
|
Есть вот такой CSV, в котором встречаются такие штуки: разделитель в поле и перевод строки (LF) в поле. Excel умудряется такой файл корректно прочитать.
Чем его можно загрузить в таблицу значений ? Файл довольно большой - 140000 строк. пробовал через ADODB: http://infostart.ru/public/98398/ несмотря на то что заявлено что "Файлы с кавычкими и вложенными запятым обрабатываются верно" - у меня поле с разделителем раскидывает в два поля, ну и перевод строки считает за новую строку. Мучался, мучался - так и не получилось изменить поведение. Мутить чтение через excel? долго наверное будет, да и муторно. Может есть у кого работающий код? |
|||
1
NWsFF
31.05.13
✎
13:50
|
Код не сохранился, делал это на регулярных выражениях, вся соль в самом регулярном выражении, правда у меня перевода строки не было в полях, так что копай в строну регулярок.
|
|||
2
zladenuw
31.05.13
✎
13:52
|
(0) а если конвертнуть его в ексель. а дальше читать через адо ?
|
|||
3
Serginio1
31.05.13
✎
13:56
|
См v8: v8:ИзСтрокиСРазделителями
Есть переписанный вариант v8: 8.2: загрузка из файла CSV (или XLS) где более 65.000 строк |
|||
4
Serginio1
31.05.13
✎
13:58
|
||||
5
Smallrat
31.05.13
✎
14:00
|
(1) регулярки... не доводилось щупать, но попробую если не найду способа попроще
(2) думаю долго будет, сперва он будет в эксель грузится, потом его оттуда читать построчно. хотя он сразу читает всё верно. (3) щас зачту |
|||
6
Smallrat
31.05.13
✎
14:20
|
(4) не отлавливает чтото разделитель и LF в поле (
попробую этот код из книги Книга знаний: Преобразование csv в таблицу значений если не взлетит - приедтся наверное браться за регулярки |
|||
7
Serginio1
31.05.13
✎
14:31
|
А как пишешь?
ExtractFields(S,aList,Delimiter,QuoteChar) ? Ты должен подать на вход строку S, массив aList. Функция заполнит массив |
|||
8
Smallrat
31.05.13
✎
14:41
|
(7) мда, невнимательно скопипастил.
Теперь разделитель правильно находит и колнки делит правильно. А вот с переводом строки выдает ошибку "Нет закрывающей скобки" ( |
|||
9
Smallrat
31.05.13
✎
14:42
|
щас или вечером попробую допилить
|
|||
10
Serginio1
31.05.13
✎
15:54
|
(8) Ты должен подать на вход строку без перевода строки.
Обычно это делается через чтение файла. Функция ИзСтрокиСРазделителями(S,Delimiter=",",QuoteChar="""") Экспорт перем aList; ExtractFields(S,aList,Delimiter,QuoteChar); Возврат aList КонецФункции Текст=Новый ЧтениеТекста(Файл,"windows-1251"); Стр = Текст.ПрочитатьСтроку(); Пока Стр <> Неопределено Цикл МассивЗначений=ИзСтрокиСРазделителями(Стр,РазделительПолей,ОграничительСтрок); КонецЦикла |
|||
11
Serginio1
31.05.13
✎
15:55
|
Стр = Текст.ПрочитатьСтроку();
Пока Стр <> Неопределено Цикл МассивЗначений=ИзСтрокиСРазделителями(Стр,РазделительПолей,ОграничительСтрок); Стр = Текст.ПрочитатьСтроку(); КонецЦикла |
|||
12
Smallrat
31.05.13
✎
16:53
|
что-то у меня не распознает конец строки ((
Стр = ЧтениеТекста.ПрочитатьСтроку(Символы.ВК+Символы.ПС); считывает весь оставшийся текст. ,а Стр = ЧтениеТекста.ПрочитатьСтроку(); разбивает строку с LF (он же Символы.ПС) на несколько |
|||
13
Serginio1
31.05.13
✎
16:55
|
То есть у тебя LF это разделитель колонок?
|
|||
14
Smallrat
31.05.13
✎
16:58
|
(13) не - разделитель колонок точка с запятой - ";"
сама колонка порой представляет многострочный текст - внутри строки разделяются LF, в то время как строки таблицы отделяются CR+LF вот и я не могу заставить ЧтениеТекста разделять строки друг от друга по CR+LF |
|||
15
Serginio1
31.05.13
✎
17:00
|
Можно попробовать двумя способами справится
Либо СтрЗаменить(ИсходныйТекст,Символ.ПС,"") или Для Счетчик = 1 По СтрЧислоСтрок(ИсходныйТекст) Цикл ТекСтрока = СтрПолучитьСтроку(ИсходныйТекст, Счетчик); ... КонецЦикла; Сейчас алгоритм посмотрю |
|||
16
Serginio1
31.05.13
✎
17:03
|
Что выдает СтрДлина(S) для строки содержащей LF?
|
|||
17
Smallrat
31.05.13
✎
17:05
|
(15) щас попробую
(16) у меня не получается ее получить - либо он ее обрезает по LF, либо в строке весь текст файла. |
|||
18
Serginio1
31.05.13
✎
17:13
|
А у тебя точно разделитель CR+LF?
Я обчно в таких ситуация в Попытке исключение ловлю исключение и склеиваю строки |
|||
19
Smallrat
31.05.13
✎
17:13
|
не успел на работе, буду дома пробовать
|
|||
20
Smallrat
31.05.13
✎
17:15
|
вот примерно так выглядит
http://savepic.net/3770423.png |
|||
21
Serginio1
31.05.13
✎
17:58
|
Можно попробовать
Новый ЧтениеТекста(<ИмяФайла>, <Кодировка>, <РазделительСтрок>, <КонвертируемыйРазделительСтрок>, <МонопольныйРежим>) <КонвертируемыйРазделительСтрок> (необязательный) Тип: Строка. Определяет разделение строк в файле для конвертации в стандартный перевод строк ПС. Значение по умолчанию: ВК + ПС. Разделитель задается в КонвертируемыйРазделительСтрок А разделитель строк ПС. Можно Ради интереса попробовать Новый ЧтениеТекста(ИмяФайла, Кодировка,Символы.ВК, Символы.ВК+Символы.ПС, <МонопольныйРежим>) Просто получается внутри переводом строки уже является ПС. Вообще замутили они с этими переносами. Без пол литра не обойтись. |
|||
22
Smallrat
31.05.13
✎
18:26
|
>>Без пол литра не обойтись.
это еще упрощенный пример. сам файл настолько долбанутый, что у меня чуть руки не опустились. ладно бы один раз надо было грузануть - я бы его поконвертировал в чтото удобное, а надо постоянную загрузку написать. вот шапка так вылядит ;Прайс-лист;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;"ООО ""Компания компания""";;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;В валютах цен.;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Цены указаны на 22.05.2013;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Ценовая группа/ Номенклатура/ Характеристика номенклатуры;Номенклатура.Код;Номенклатура.Артикул;Номенклатура.Наименование;Номенклатура.Полное наименование;Номенклатура.Группа;Номенклатура.Бренд;Номенклатура.Группа.Код;Номенклатура.Группа.Группа;Номенклатура.Группа.Группа.Код;Номенклатура.Группа.Группа.Группа;Номенклатура.Группа.Группа.Группа.Код;Номенклатура.Группа.Группа.Группа.Группа;Номенклатура.Группа.Группа.Группа.Группа.Код;Номенклатура.Группа.Группа.Группа.Группа.Группа;Номенклатура.Группа.Группа.Группа.Группа.Группа.Код;Номенклатура.Группа.Группа.Группа.Группа.Группа.Группа;Номенклатура.Группа.Группа.Группа.Группа.Группа.Группа.Код;Номенклатура.Группа.Группа.Группа.Группа.Группа.Группа.Группа;Номенклатура.Группа.Группа.Группа.Группа.Группа.Группа.Группа.Код;Номенклатура.Единица хранения остатков;Номенклатура.Единица хранения остатков.Объем;Номенклатура.Количество в упаковке;Номенклатура.Количество на паллете;Номенклатура.Единица хранения остатков.Длина;Номенклатура.Единица хранения остатков.Высота;Номенклатура.Единица хранения остатков.Ширина;Розничная; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;Цена;Ед. причем в "описании" структуры количество колонок из-за какой-то ошибки меньше чем в структуре, в конце должно быть Розничная Цена;Ед. я аж прифигел когда такой "csv" увидел |
|||
23
Kreont
31.05.13
✎
18:26
|
CSV - файл не правильный, сделай без переносов и все пойдет.
wiki:CSV CSV (от англ. Comma-Separated Values — значения, разделённые запятыми) — текстовый формат, предназначенный для представления табличных данных. Каждая строка файла — это одна строка таблицы. |
|||
24
Smallrat
31.05.13
✎
18:32
|
(23) в самой вики кстати в первом же примере csv с переносами и запятыми в полях.
|
|||
25
Kreont
31.05.13
✎
18:37
|
(24) ну я например пишу импорт, только из правильных CSV, а если какойто прогер, тот что например мне хочеть втулить "свой" вариант реализации CSV идет или лесом, или сам меняет свою программу. Без вариантов. А ложиться под чужие кривые форматы просто глупо.
|
|||
26
Kreont
31.05.13
✎
18:39
|
(24) вики правят добровольцы, как видишь неудачно, тут уж ничего не поделаешь
Ищи оригинал RFC, для стандарта CSV, его и покажи автору твоего CSV, пусть правит. |
|||
27
Kreont
31.05.13
✎
18:42
|
http://www.rfc-editor.org/rfc/rfc4180.txt
и самое главное: 1. Each record is located on a separate line, delimited by a line break (CRLF) |
|||
28
Smallrat
31.05.13
✎
18:43
|
(25) задача пока поставлена грузить из чего есть - и прогера там нет, это похоже на какую-ту стандартную конвертацию отчета "прайс-лист" из УТ, ее манагеры делают и ничео другого, окромя mxl прислать не могут.
|
|||
29
Smallrat
31.05.13
✎
18:46
|
6. Fields containing line breaks (CRLF), double quotes, and commas
should be enclosed in double-quotes. For example: "aaa","b CRLF bb","ccc" CRLF zzz,yyy,xxx у меня правда не CRLF а просто LF |
|||
30
Kreont
31.05.13
✎
18:51
|
(29) прикольно, я так далеко не читал ))), ну дай им рфс без 6-го пункта :)
Значит не повезло тебе с файлом, уменя такие ниразу не попадались, придется писать. |
|||
31
Jaap Vduul
31.05.13
✎
19:07
|
>> пробовал через ADODB
Покажь свой schema.ini |
|||
32
Smallrat
31.05.13
✎
19:21
|
Примерно так:
[222.csv] ColNameHeader=False Format=Delimited(;) TextDelimiter=none CharacterSet=ANSI Col1=Field1 Text Col2=Field2 Text |
|||
33
Ковычки
31.05.13
✎
19:25
|
заменить перевод строки на пробел
|
|||
34
Smallrat
31.05.13
✎
19:37
|
(33) как бы этот перевод строки отличить от возврата каретки. чтото у меня пока не получается.
|
|||
35
Ковычки
31.05.13
✎
19:43
|
(34) СтрЗаменить(СтрЗаменить(Стр,Символы.ПС," "),Символы.ВК,Символы.ВК+Символы.ПС);
|
|||
36
Ковычки
31.05.13
✎
19:43
|
хотя х.з. как это в объекте текст
|
|||
37
Smallrat
31.05.13
✎
19:46
|
(35) ну в принципе можно - эт получается что сначала надо весь 50мегабайтный файл считать, заменить символы, записать, а потом снова распарсить уже как нормальный csv. янадо по времени замерить
|
|||
38
Smallrat
31.05.13
✎
19:46
|
(36) в чтении текста пока не получается (
|
|||
39
Ковычки
31.05.13
✎
19:47
|
Стр="аываыва"+Символы.ВК+Символы.ПС+"sdfsdsdfsd"+Символы.ПС+"ваываываыв";
Сообщить(СтрЗаменить(СтрЗаменить(Стр,Символы.ПС," "),Символы.ВК,Символы.ВК+Символы.ПС)); |
|||
40
Smallrat
31.05.13
✎
20:16
|
Внезапно получилось так:
ЧтениеТекста = Новый ЧтениеТекста(ПутьКФайлу, КодировкаТекста.ANSI,Символы.ВК, Символы.ПС - тут может быть любой символ кроме Символы.ВК); правда каждая строка, получаемая из файла теперь впереди с переводом каретки (или строки, я пока не понял), но СокрЛ() это правит то есть http://savepic.net/3743815.png первая строка считывается как: клиент;адрес
а вторая как "ИП Ив
|
|||
41
Smallrat
31.05.13
✎
20:18
|
млииин - все же в (21) написано, вот я балда
|
|||
42
Smallrat
31.05.13
✎
20:19
|
а нет - как раз так у меня не получилось
Новый ЧтениеТекста(ИмяФайла, Кодировка,Символы.ВК, Символы.ВК+Символы.ПС, <МонопольныйРежим>) вместо Символы.ВК+Символы.ПС надо любое другое указать но без Символы.ВК |
|||
43
Serginio1
31.05.13
✎
20:25
|
(40) Чесно говоя я такие файлы на C# обработываю http://www.rsdn.ru/forum/dotnet/3303143.1
|
|||
44
Serginio1
31.05.13
✎
20:29
|
А если ничего не указываь?
|
|||
45
Ковычки
31.05.13
✎
20:30
|
балда ты, давай файл
|
|||
46
Serginio1
31.05.13
✎
20:33
|
То есть что получается при
Новый ЧтениеТекста(ИмяФайла, Кодировка,Символы.ВК) Там по умлчанию Символы.ВК+Символы.ПС При указании Символы.ПС она отработывает только Символы.ПС. То есть если символ идет сначала строки то у тебя Символы.ПС+Символы.ВК |
|||
47
Smallrat
31.05.13
✎
20:35
|
||||
48
Serginio1
31.05.13
✎
20:35
|
нет спереди у тебя стоит как раз Символы.ПС
|
|||
49
Serginio1
31.05.13
✎
20:38
|
А что делается если указать Символы.ВК+Символы.ПС
|
|||
50
Smallrat
31.05.13
✎
20:40
|
(48) ага. правда я вот понимаю что разделить получилось только потому что у меня перенос идет только одним символом LF, в то время как по RFC двумя и все задается только кавычками -типа так
"aaa","b CRLF
(49) весь файл в одну строку сваливается клиент;адрес
|
|||
51
Ковычки
31.05.13
✎
20:48
|
Текст=Новый ТекстовыйДокумент;
Текст.Прочитать("C:\Users\ginzburg\Downloads\333.csv"); Сообщить(СтрЗаменить(СтрЗаменить(Текст.ПолучитьТекст(),Символы.ПС," "),Символы.ВК,Символы.ВК+Символы.ПС)); |
|||
52
Smallrat
31.05.13
✎
21:00
|
(51) вот так получилось клиент;адрес "ИП Ив анов А.А.";"Москва;ул.Ленина;53"
|
|||
53
Serginio1
31.05.13
✎
21:06
|
Ну до к этому и здесь пришли http://www.1c-pro.ru/topic50801.html
|
|||
54
Ковычки
31.05.13
✎
21:13
|
ФСО=Новый COMОбъект("Scripting.FileSystemObject");
Текст=ФСО.OpenTextFile("C:\Users\ginzburg\Downloads\333.csv"); Стр=""; Пока Не Текст.AtEndOfStream Цикл Симв=Текст.Read(1); Если Не Симв=Символы.ПС Тогда Стр=Стр+Симв; ИначеЕсли Симв=Символы.ВК Тогда Стр=Стр+Символы.ВК+Символы.ПС; КонецЕсли; КонецЦикла; |
|||
55
Jaap Vduul
31.05.13
✎
23:29
|
(32)
Убери или закомментируй строку "TextDelimiter=none" и всё. |
|||
56
Serginio1
31.05.13
✎
23:50
|
55+ http://it-proposition.blogspot.ru/2011/08/schemaini-microsoftaceoledb120.html
TextDelimiter - определяет символ, которым отделяется текст. По умолчанию " |
|||
57
Serginio1
01.06.13
✎
12:37
|
56 + но при этом часто бывает, что файла не всегда корректные и приходится их дорабатывать своими парсерами
|
|||
58
Smallrat
03.06.13
✎
22:52
|
(54) посимвольное чтение ? это ж я поседею в процессе.
(55) бинго! ну еклмн, как все просто.... (57) вроде бы 40 мегабайт csv загрузились корректно, на первый взгляд, щас напишу обработку таблицы и там видно будет. Всем большое спасибо! не оставили в беде ))) |
|||
59
Eugeneer
03.06.13
✎
22:56
|
(58) вот готовое - гарантируем работу
http://subsystems.ru/catalog/27/158/ Читайет эксель и CSV напрямую - своя суперкомпонента. Скорость считывания 100 000 за 1 минуту. |
|||
60
zak555
03.06.13
✎
22:59
|
(59) что за суперко
|
|||
61
zak555
03.06.13
✎
23:00
|
и что за 500 придурков, которые вечно что-то грузят из эксель ?
|
|||
62
Eugeneer
03.06.13
✎
23:03
|
(61) ;))
|
|||
63
Serginio1
04.06.13
✎
11:05
|
(59) 100 000 на Это менее 1 секунды http://www.rsdn.ru/forum/dotnet/3303143.1
Минута это очень много. |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |