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.
