Página 1 de 2

Ler partes de cada linha de um arquivo texto

Enviado: 27 Jul 2007 14:51
por miracle
Boa tarde, Amigos!

Preciso ler partes de cada linha de um arquivo texto.

Tenho um arquivo assim:

01126/03/0706:33000000000000001801
01026/03/0707:31000000000000005901
01126/03/0707:32000000000000003501

E preciso passar os dados num DBF, lendo os seguintes dados:
26/03/07 06:33 18
26/03/07 07:31 59
26/03/07 07:32 35

Como faço isso?

Enviado: 27 Jul 2007 15:07
por Maligno
Você pode usar a função MemoRead() do Clipper. E a partir da string lida, botar isso numa malha pra separar as strings. Do jeito que está não dá pra importar direto pro DBF, claro. Precisa de uma separação "manual".

Enviado: 27 Jul 2007 15:20
por Stanis Luksys
Só de passagem....

Outra alternativa é carregar, escrever e gravar o arquivo com:

FOpen()
FWrite()
FClose()

Falou!

Enviado: 27 Jul 2007 15:22
por Maligno
Ah, sim. Esqueci de dizer. Se o arquivo for grande, a dica do Stanis é muito melhor. Sem dúvida.

Enviado: 27 Jul 2007 15:43
por miracle
E como é que eu faria essa tal "malha"?

Enviado: 27 Jul 2007 16:43
por Pablo César
A ideia de ler o arquivo em baixo nível (FOPEN,FWRITE,FCLOSE,etc..) é mais seguro que o MEMOREAD pela sua limitação de 64KB. Outra forma seria utiliza o APPEND FROM SDF a um arquivo DBF com campos TODOS tipo caracter e no tamanho de cada campo conforme está o arquivo texto. Depois é só varrer o arquivo DBF e importar transformando o que é texto para tipo DATA, tipo NUMERICO. Enfim isso você deve saber fazer, utilize um

DO WHILE !EOF()

Ler linha a linha arquivo TXT

Enviado: 27 Jul 2007 17:46
por Maligno
miracle escreveu:E como é que eu faria essa tal "malha"?
O Pablo deu uma idéia a respeito do APPEND FROM. É uma forma também. Mas se for um arquivo pequeno, menor que 64KB, você pode fazer a tal malha que eu disse da seguinte forma:

Código: Selecionar todos

#define kEOL Chr(13)+Chr(10)

cText := MemoRead(........) + kEOL
while !Empty(cText)
   nPos  := At(kEOL,cText)
   cLine := Left(cText,nPos-1)
   cText := SubStr(cText,nPos+2)
   *
   if !Empty(cLine)
      // Neste ponto você tem uma linha isolada.
      // Separe o que tiver que separar, e grave
      // no DBF destino.
   end
end
Finito! Só isso já será suficiente para isolar as linhas uma a uma pra análise, separação e gravação dos campos. Logicamente eu não testei o código. Acabei de escrever. Mas acho que vai funcionar.

Enviado: 28 Jul 2007 11:59
por Pablo César
Agora só falta dizer se o colega miracle resolveu e dizer como.

Meus comentários sobre o debate de dar a solução, você encontrará em:

https://pctoledo.org/forum/viewto ... 9461#29461

Abrí outro tópico para que não desvie ainda mais o assunto principal.

Enviado: 28 Jul 2007 12:20
por Maligno
A forma como ele resolveu nem é tão importante. Pelas dicas que recebeu, qualquer forma escolhida o levou à solução. É isso o que importa.
Ainda se fosse um problemão absurdamente complexo, a curiosidade se justificaria. Mas não é o caso. Acho que nem os novatos aproveitariam.

Enviado: 28 Jul 2007 12:28
por Pablo César
haha, depois de tanta falação ele deve estar temeroso a se manifestar... hehe é apenas uma brincadeirinha...

Interessa sim, pois tem um detalhe que irá pesar na forma de fazer isso. Não me refiro a utilizar o MEMOREAD porque por dedução pode-se afirmar que tem situações que irá servir pelo tamanho ser pequeno (menos de 64K). Mas o que me refiro por ser importante, é que naquele exemplo que o miracle deu (1ª mensagem deste tópico) mencionava:

01126/03/0706:33000000000000001801
01026/03/0707:31000000000000005901
01126/03/0707:32000000000000003501

Se perceber a string "26/03/07" que mais tarde irá se tranformar em data está com 2 dígitos referindo-se ao ano. É um cuidado que irá tomar, só isso.

Enviado: 28 Jul 2007 12:37
por Maligno
Ah, sua preocupação é com isso? Nem esquenta. Aposto que ele já está ciente desse inconveniente. Além do quê, é só uma simples conversão de string. Nada mais.
Aliás, agora me lembro que uma dica, sua por sinal, dava conta do APPEND FROM. Nunca usei, mas não quero nem pesquisar a respeito. Então, me diga: com a data desse jeito o APPEND FROM funcionaria corretamente? Imagino eu que seria necessário apenas ajustar o SET CENTURY, não?

Enviado: 28 Jul 2007 15:33
por Pablo César
Maligno escreveu:seria necessário apenas ajustar o SET CENTURY, não?
Pode ser, mas ainda seria meio incerto. Eu faria uma função para ver qual seria a melhor opção na hora de transformar essa data com 2 dígitos no ano. Se bem que eu tinha proposto em APPENDAR para um arquivo DBF e depois lê-lo transformando-o de caracter para data. de todas formas seria conveniente transformar essa data apropriadamente. Sugiro isto:

Código: Selecionar todos

VTXT:="26/03/07"
VDATE:=STR2DATE(VTXT)
REPLACE DATA WITH VDTAE

FUNCTION STR2DATE(VTXT)
SET DATE TO BRITISH
SET CENTURY ON
XDT:=CTOD(VTXT)
XYD:=(RIGHT(ALLTRIM(STR(YEAR(XDT))),2))
XYA:=(RIGHT(ALLTRIM(STR(YEAR(DATE()))),2))
IF VAL(XYD)>VAL(XYA)
    IF (VAL(XYD))-(VAL(XYA))<2
        XDT:=CTOD( SUBSTR(DTOC(XDT),1,6)+"20"+XYD )
    ELSE
        XDT:=CTOD( SUBSTR(DTOC(XDT),1,6)+"19"+XYD )
    ENDIF
ELSE
    XDT:=CTOD( SUBSTR(DTOC(XDT),1,6)+"20"+XYD )
ENDIF
RETURN XDT
Pelo jeito, não estamos fazendo utdo, sem o colega estar pedindo... hehe mas o importante esclarecer dúvidas e ajudar...

Obs.: Esquecia de mencionar, essa função que eu fiz só é válida para este centenário (acho dificil ter que responder por algum programa com mais de cem anos... hehe). Mas pode ser adaptado... creio eu...

Enviado: 28 Jul 2007 15:58
por Maligno
Não. Eu estava perguntando se o APPEND FROM poderia manipular isso diretamente como data. Se não der, terá de ser por string. Daí tem que converter, depois separar, depois gravar,... :)))
Acho que pra resolver esse caso de forma mais apropriada, e fácil, seria o MemoRead() para arquivos pequenos ou as funções de baixo nível (FOpen, FRead, etc) para arquivos grandes.
Por essas e outras eu fiz meu sub-sistema de tratamento de texto. Não esquento a cabeça com nada. :)

Enviado: 29 Jul 2007 08:14
por Pablo César
Maligno escreveu:Não. Eu estava perguntando se o APPEND FROM poderia manipular isso diretamente como data.
Ok, entendo a sua pergunta. Funcionaria se no arquivo texto a SUB-STRING (que corresponde a data) fosse no padrão aaaammdd com quatro dígitos o ano (sem importar se está ou não o CENTURY ON ou OFF). Daí ele importa direto sem problemas. Mas não sei se ele pode alterar o formato desse arquivo texto.
Se não der, terá de ser por string. Daí tem que converter, depois separar, depois gravar...
Sim claro não é uma forma tão prática, mas é segura. E se o formato do arquivo texto fosse como eu citei acima, então este seria o caminho mais rápido, prático e eficiente de puxar os dados de um arquivo texto.
Não esquento a cabeça com nada.
Claro, contando que esse arquivo SEMPRE seja menor que 64K, então dou a razão. Mas como você disse já uma vez... dada a limitação de 64k e não servindo para TODAS as ocasiões, eu o considero INEFICIENTE.

Enviado: 29 Jul 2007 11:00
por Maligno
Sim claro não é uma forma tão prática, mas é segura.
Acho que segurança em si não é uma preocupação neste caso. No lugar do colega já faria tudo por FOpen() e FRead() mesmo. Já matava a cobra com uma porretada bem dada no meio do coco dela. E fim. :)