Форум » Clipper » преобразование csv формата в текстовой с разделителями в одной колонке » Ответить

преобразование csv формата в текстовой с разделителями в одной колонке

anker: Подскажите пожалуйста какими функциями и с какой библиотеки можно воспользоваться для преобразования csv формата в текстовой с разделителями в одной колонке например получить из |1|22222|33| |1111111 |2|33333333| что-то типа |1 |22222|33 | |1111111 |2 |33333333| если можна фрагмент кода

Ответов - 14

Dima: anker пишет: например получить из |1|22222|33| |1111111 |2|33333333| anker пишет: что-то типа |1 |22222|33 | |1111111 |2 |33333333| Что то особой разницы не вижу , не считая пару тройки пробелов. В этом и есть вся фишка ? Если так тогда можно например вот этим воспользоваться STRTRAN(<строка символов>, <замещаемая подстрока>, [<замещающая подстрока>], [<начало замены>], [<число замен>]) --> новая строка символов

anker: Фрагмент реального файла в котором могут быть тысячи строк 222295|999999912|30.11.2005|113865.83|1000000018|0.0||-1|1|1| 2855192|999999869|18.03.2006|42.21|1000000009|0.0||1|1|1| желательно преобразовать в 222295_|999999912|30.11.2005|113865.83|1000000018|0.0||-1|1|1| 2855192|999999869|18.03.2006|42.21____|1000000009|0.0||1_|1|1| "_" в даном случае пробел мажду разделителями неизвестно наперед сколько символов и какие (каждый раз по разному) подстрока врядли пойдет Мысль (может совсем и не верная) 1 сканировать поочередно каждый символ строки и переносить его в другой файл поочередно 2 если символ "|" то в другой файл в определенную позицию 1-й в 20 2-й в 40 и т д далее поочередно 3 конец строки по chr(10) chr(13) или иначе но какими функциями и желательно из библиотек toolssh.lib nanfor.lib clipper.lib

ort: Я так думаю, что одним проходом по файлу здесь не обойтись


lista: anker пишет: Фрагмент реального файла в котором могут быть тысячи строк 222295|999999912|30.11.2005|113865.83|1000000018|0.0||-1|1|1| 2855192|999999869|18.03.2006|42.21|1000000009|0.0||1|1|1| желательно преобразовать в 222295_|999999912|30.11.2005|113865.83|1000000018|0.0||-1|1|1| 2855192|999999869|18.03.2006|42.21____|1000000009|0.0||1_|1|1| "_" в даном случае пробел Зачем такие преобразования? Что дальше нужно делать? Если говорить о реальном файле, то в CLIPPER TOOLS (CT3) есть пример, который реализует разбор файла на строки, которые заканчиваются chr(10) chr(13). Хотя есть и без (CT3) Далее строки раpбираешь по элементам функциями семейства TOKEN* Или сам используя AT() и SUBSTR()

ort: Можно поиграться с этим - только конкретней поставь задачку. На двух строчках не совсем ясно.

anker: задача вообще-то вытянуть из нескольких таких 222295|999999912|30.11.2005|113865.83|1000000018|0.0||-1|1|1| 2855192|999999869|18.03.2006|42.21|1000000009|0.0||1|1|1| файлов информацию в соответствующие dbf- файлы а затем написать маленькую програмулю где бы пользователь задал период и получил отчет я почемуто решил что легче не напрямую из csv в dbf а в промежуточный txt 222295_|999999912|30.11.2005|113865.83|1000000018|0.0||-1|1|1| 2855192|999999869|18.03.2006|42.21____|1000000009|0.0||1_|1|1| а затем функцией FT_FREADLN() из nanfor.lib достать в dbf но видимо знающие люди делают по- другому

Dima: Это типа выписки банка я так понял (хотя роли это не играет) ? Делал такое....при чем у каждого банка свои форматы как TXT ,CSV так и DBF А по теме можно сделать так.....на первый взгляд. Формат строк одинаков насколько я понял ? Да можно обработать строки с помощью FT_FREADLN() , только мне кажется что промежуточного файла тут не нужно , вообще ни какого. Ты ведь задал период , верно ? Где у тебя лежит дата ты знаешь , а именно лежит она между 2 и 3 разделителем. "Вынул" дату - преобразовал ее из симовльного формата в дату и сравнил с интервалом. Если не подходит ......значит FT_FSKIP(); LOOP (если в цикле) Остальные данные извлекаешь по похожей схеме. PS После считывания строки с помощью FT_FREADLN() , попутно можно проверить корректность формата. Например кол-во разделителей. В твоем примере их 10 в строке (если я не ошибся). Если не 10 , тогда строку дальше не обрабатываем и тд и тп

ort: Я себе представляю вот так: ccc := "222295|999999912|30.11.2005||1"+CRLF+; "2855192|999999869|18.03.2006||2" ccc := StrTran(ccc,"|",",") MemoWrit("file.txt",ccc) dbCreate("file.dbf",{ {"F1","N",10,0},{"F2","N",10,0},{"F3","D",8,0},{"F4","N",3,0},{"F5","N",1,0} }) USE file.dbf APPEND FROM file.txt DELIMITED Только даты нужно преобразовывать в формат yyyymmdd или поле сделать символьным.

Dima: Можно и так конечно :) ort пишет: ccc := StrTran(ccc,"|",",") покатит если ни где нет текста в котором уже может быть запятая. у меня был такой случай ;) один клиент-банк сбрасывал инфу в CSV , разделитель точка с запятой (;) , при чем это было жестко у них зашито в проге. А я этот файлик обрабатывал для получения отчета с минимальной проверкой формата. И те строки в которых уже была ; (типа назначение платежа) в отчет не попадали...со всеми вытекающими ;)

ort: Dima пишет: покатит если ни где нет текста в котором уже может быть запятая. Конечно, если есть запятая, то нужно выкручиваться иначе. Но в прилагаемых строках ее нет.

anker: Спасибо за идеи, но мне как делетанту это сложновато не совсем понятно или совсем непонятно зачем менять символы ccc := StrTran(ccc,"|",",") // будем иметь 222295,999999912,30.11.2005,113865.83,1000000018,0.0,-1,1,1, 2855192,999999869,18.03.2006,42.21,1000000009,0.0,1,1,1, что это меняет в строке, главное позиции начала даты и сумы не изменились зачем это писать в новый файл MemoWrit("file.txt",ccc) (будем иметь два аналогичных файла) в общем непонятно зачем менять символы (символы меня устраивают не устраивает что разделитель в разных строках стоит в разных позициях) и зачем искать что-то в строках мне надо проще я должен знать что с какой позиции в строке лежит с какой позиции дата с какой сумма зайти и взять приблизительно так c_string = ft_freadln() //взял всю строку из файла n_summa = val(substr(c_string,29,9)) //беру сумму с 29- позиции 9 символов но это не работает в первой строке "113865,83" во второй "|42.21|10" Так что видимо прийдется отказаться от этой идеи csv->txt->dbf или csv->dbf а програмулю писать которая берет данные только из dbf или перенести это творчество на неопределенное время может затем вернуться и посмотреть на все это по новому спасибо всем за помощь

Dima: anker anker пишет: Так что видимо прийдется отказаться от этой идеи csv->txt->dbf или csv->dbf а програмулю писать которая берет данные только из dbf или перенести это творчество на неопределенное время может затем вернуться и посмотреть на все это по новому спасибо всем за помощь Тут работы на 30 минут ;) Вот же .......чем не подходит ? Dima пишет: Это типа выписки банка я так понял (хотя роли это не играет) ? Делал такое....при чем у каждого банка свои форматы как TXT ,CSV так и DBF А по теме можно сделать так.....на первый взгляд. Формат строк одинаков насколько я понял ? Да можно обработать строки с помощью FT_FREADLN() , только мне кажется что промежуточного файла тут не нужно , вообще ни какого. Ты ведь задал период , верно ? Где у тебя лежит дата ты знаешь , а именно лежит она между 2 и 3 разделителем. "Вынул" дату - преобразовал ее из симовльного формата в дату и сравнил с интервалом. Если не подходит ......значит FT_FSKIP(); LOOP (если в цикле) Остальные данные извлекаешь по похожей схеме. PS После считывания строки с помощью FT_FREADLN() , попутно можно проверить корректность формата. Например кол-во разделителей. В твоем примере их 10 в строке (если я не ошибся). Если не 10 , тогда строку дальше не обрабатываем и тд и тп

ort: anker пишет: Спасибо за идеи, но мне как делетанту это сложновато Правильно - дилетант anker пишет: зачем менять символы Нужно менять, чтобы привести к нужному формату для команды APPEND FROM file.txt DELIMITED anker пишет: зачем это писать в новый файл Это я для себя пишу в файл, чтобы потом прочитать из него. Тебе, конечно, не нужно. anker пишет: Так что видимо прийдется отказаться от этой идеи csv->txt->dbf Не нужно отказываться от идеи. Если попроще, то можно так: читаешь строку, потом преобразуешь в массив функцией ListAsArray( <cList>, <cDelimiter> ) --> aList Она есть в поставке Clipper в файле STRING.PRG, преобразует строку с разделителями в массив Дата всегда будет третьим элементом в этом массиве. А далее - можно добавить записи в дбф или двухмерный массив...

LYSK: я б предложил такой вариант - не связываться с файловыми функциями, а создать структуру ДБФ с одним строковым полем длины максимальной строки, подгрузить в него текстовый файл APPEND FROM xxx.txt SDF и далее обрабатывать в цикле записи этого файла, используя столь любимые мной TOKEN из Clipper Tools pole1:=token(stroka,'|',1) pole2:=token(stroka,'|',2) и т.д разделители конечно любые, какие могут встречаться ну а дальше - то ли обработка полученных полей, то ли выгрузка их в целевой дбф - по вкусу



полная версия страницы