Execução infinita em estrutura de controle

Fórum sobre a linguagem CA-Clipper.

Moderador: Moderadores

Gelson
Usuário Nível 3
Usuário Nível 3
Mensagens: 170
Registrado em: 16 Abr 2005 17:04

Mensagem por Gelson »

A estrutura do campo SALDO no DBF é N,14,2

vSALDO=STRTRAN(SUBS(LINHAS,59,16),".","")
vSALDO=VAL(STRTRAN(vSALDO,",",","."))


Como faço para que valores x.xxx.xxx.xxx.xx sejam aceitos ?


No primeiro caso : ,".","") tem duas aspas no final isto quer dizer o que ?
No segundo caso tem aspas, ponto, aspas, qual a tradução disto ?
Avatar do usuário
gvc
Colaborador
Colaborador
Mensagens: 1270
Registrado em: 23 Ago 2005 10:57

Mensagem por gvc »

SUBS(LINHAS,59,16)
*Pega da variável linhas, a partir da posição 59, os próximos 16 caracteres.

STRTRAN(<variavel>, ".", "")
*Procura dentro da variável as ocorrências de "." (ponto) e troca por "" (nada) - Isso é usado para remover um tipo de caracter do conteúdo da variável. Neste caso, esta removendo os pontos.

*STRTRAN(<variavel>, ",", ",".")
* Acho que tem um erro aqui. Esta procurando "," (virgula) dentro de variável e trocando por (",".") - Acredito que seja somente "." ponto.
*Esta trocando virgula por ponto.

val(<variavel>)
*Esta retornando o valor númerico do campo caracter. Se não for numérico, retorna 0 (zero).

Resumindo:
vSALDO=STRTRAN(SUBS(LINHAS,59,16),".","")
vSALDO=VAL(STRTRAN(vSALDO,",",","."))

Esta pegando uma parte da variável/campo linhas, removendo a ponto de milhar, trocando a virgula decimal por ponto, retorna o valor numérico encontrado.
"TRS-80/Sincler/Apple/PC - Clipper Winter 85, tlink 1.0 [pc 10 MHz - 640K] {NEZ 8000 2Kb RAM}"
{POG - Programação Orientada a Gambiarra}
Avatar do usuário
gvc
Colaborador
Colaborador
Mensagens: 1270
Registrado em: 23 Ago 2005 10:57

Mensagem por gvc »

Gelson escreveu: ... observei que um valor de 1234,00 foi gravado como 1,00 e outro valor de 413,99 foi gravado certo então não dá para ter confiança exatidão da gravação.
Essa eu não entendi. Vc esta usando o mesmo fonte que me enviou?
Lembre-se que vc esta somando uma variável ao valor do campo e atribuindo a outra o resultado.
Vc esta comparando o valor do resultado com zero.
"TRS-80/Sincler/Apple/PC - Clipper Winter 85, tlink 1.0 [pc 10 MHz - 640K] {NEZ 8000 2Kb RAM}"
{POG - Programação Orientada a Gambiarra}
Gelson
Usuário Nível 3
Usuário Nível 3
Mensagens: 170
Registrado em: 16 Abr 2005 17:04

Mensagem por Gelson »

Não mudei na maneira de achar o valor de msal_atu, é que como já tentei de tudo que é jeito e os valores zerados continuam sendo gerados no txt, tenho feito teste de importação dos dados do txt para um dbf.

Já tentei usando a clausula com sdf no final, e não deu certo, achei uma rotina aqui no forum que também não deu certo, por fim achei uma outra e, funções para dowload que esta dando mais resultado.

o prblema que mesmo o fonte que esta aqui para download, quando o valor da venda bruta ultrapassa a casa dos x.xxx.xxx.xx é gravado valor errado no dbf, andei googleando mas não achei nada para compreender como funciona estes máscaras ".", etc., andei tentando sem rumo mesmo até achar uma forma de dar certo, mas não achei. Se desse certo esta transferência eu poderia em vez de comparar a variável de memória para eliminar o saldo zerados do relatório, passaria a sua o valor do campo saldo deste novo dbf que recebeu os dados da transferência do txt.

vou coloca o fonte abaixo para ficar mais claro;

Código: Selecionar todos

ET DATE BRITISH    
SET EPOCH TO 1950   

SELECT 1
USE RELSALDO    
ZAP           

SELECT 2
USE SALTUDO     
ZAP          

vArq="SALDO.TXT"  
APPEND FROM (vArq) SDF   

GO TOP    
DO WHILE !EOF()
  IF LEFT(LINHAS,15)="CONTA      NOME" 
  SKIP 2
  EXIT
 ENDIF
 SKIP
ENDDO
DO WHILE !EOF()
 vCONTA=LEFT(LINHAS,5)            
 vNOME=SUBS(LINHAS,6,33)
 vTIPO=SUBS(LINHAS,41,14)
 vSALDO=SUBS(LINHAS,59,16)
 vSALDO=STRTRAN(SUBS(LINHAS,59,16),",",".","")
 vSALDO=VAL(STRTRAN(vSALDO,",",".",""))

* vSALDO=STRTRAN(SUBS(LINHAS,59,16),".","")
* vSALDO=VAL(STRTRAN(vSALDO,",","."))
 IF vCONTA!="    "         
  SELE RELSALDO
  APPEND BLANK
  REPL CONTA WITH vCONTA,;
       NOME WITH vNOME,;
       TIPO WITH vTIPO,;
       SALDO WITH vSALDO
  SELE SALTUDO
 ELSE                    
  EXIT
 ENDIF
 SKIP
ENDDO
CLOSE ALL    
ALERT("OS REGISTROS FORAM GRAVADOS NO ARQUIVO RELSALDO.DBF")
RETU   
Avatar do usuário
gvc
Colaborador
Colaborador
Mensagens: 1270
Registrado em: 23 Ago 2005 10:57

Mensagem por gvc »

vSALDO=SUBS(LINHAS,59,16)
vSALDO=STRTRAN(SUBS(LINHAS,59,16),",",".","")
vSALDO=VAL(STRTRAN(vSALDO,",",".",""))

isto esta estranho. Tente:

csaldo := substr(linhas, 59, 16)
alert(csaldo)
csaldo := strtran(csaldo, ".", "")
alert(csaldo)
csaldo := strtran(csaldo, ",", ".")
alert(csaldo)
vsaldo := val(csaldo)
alert(str(vsaldo))

Os alert´s são para vc acompanhar os valor trabalhados. Após verificar que esta Ok, remova os alert´s.

-------

Se vc definir um tamanho para o campo numérico e atribuir um número maior que a capacidade, o Clipper vai preencher com ####. significa estouro de capacidade. Mude o tamanho do campo, conforme sua real necessidade.

-------

Nós usamos o formato 1.000,00 para indicar 1000 - O formato americano, que é utilizado no computador é 1,000.00 para indicar os mesmos 1000 - Assim, quando vamos ler um valor em caracteres no nosso formato e converter para numérico, devemos:
1) tirar os pontos;
2) mudar a virgula pelo ponto decimal;
3) transformar em numérico.

Ex. "36.423,59"
1) (tirando os pontos) "36423,59"
2) (mudando a virgula para ponto decimal) "36423.59"
3) (convertendo para numérico) 36423.59
"TRS-80/Sincler/Apple/PC - Clipper Winter 85, tlink 1.0 [pc 10 MHz - 640K] {NEZ 8000 2Kb RAM}"
{POG - Programação Orientada a Gambiarra}
Gelson
Usuário Nível 3
Usuário Nível 3
Mensagens: 170
Registrado em: 16 Abr 2005 17:04

Mensagem por Gelson »

Vou testar agora mesmo, aproveito para postar os resultados das comparações, para que você não fiquem pensando que não tenho lido ou testado os seus posts anteriores e que talvez eu não esteja sabendo me expressa claramente. um abraço e obrigado pela paciência.

Já fiz testes com todos os sinais matemáticos e mudando a forma de declarar as variáveis no fonte usando [0] e [ 0.00] pois me disseram aqui no fórum que o Clipper analisar [0] e [0.00] de formas diferentes.

Veja m os teste retornados com todos os sinais usados

< ( negativos e zerados)
<= ( negativos e zerados)
> (positivos e zerados)
>= (positivos e zerados)
<>( zerados)
# (zerados)

Código: Selecionar todos

CLEAR
mlinha = 66
*mfolha = 1
mtotsal = 0
mdata   = CTOD('  /  /  ')
mtipo   = 0
USE CLIENTES INDEX INCLIENT
SELECT 2
USE MOVIM    INDEX IMOVIM

@10,01 SAY 'INFORME DATA LIMITE'
@10,21 GET mdata
@11,01 SAY 'INFORME TIPO'
@11,21 GET mtipo PICTURE '9'
@11,23 SAY '1 -> CARRETEIRO, 2 -> CLIENTES, 3 -> FUNCIONARIO'
READ


SET PRINTER TO SALDO.TXT

SET DEVICE TO PRINT

?? CHR(27) + CHR(15)

dbgotop()


SET DEVICE TO PRINT
SELECT 1 
mSAL_ATU = 0

WHILE !EOF()

IF CONTA = '99998' .or.;
(mtipo = 1 .and. VAL(CONTA) > 19999) .or.;
(mtipo = 2 .and. (VAL(CONTA) > 30000 .or. VAL(CONTA) < 20000)) .or.;
(mtipo = 3 .and. VAL(CONTA) < 30000) .or.;
(mtipo = 4 .and. (VAL(CONTA) < 1 .OR. VAL(CONTA) > 99998)) 

dbskip()
loop
end

 SELECT 2
 mvalor = 0 
 SEEK CLIENTES->CONTA
 DO WHILE CLIENTES->CONTA = CONTA .AND. .NOT. EOF()
  IF DATA     > mdata
   SKIP
   LOOP
  ENDIF
  IF CT < 10
   mvalor = mvalor - VALOR
  ELSE
   mvalor = mvalor + VALOR
  ENDIF
  SKIP
 ENDDO
 SELECT 1
 mSAL_ATU = SAL_INI + mvalor
 IF mSAL_ATU > 0                                                          
  SKIP
  LOOP
  ENDIF
 IF mlinha > 50
  @1,10 SAY '** RELATORIO  **  TESTE'
  @1,65 SAY 'FOLHA'
  @1,69 SAY mfolha PICTURE '999'
  @2,20 SAY 'RELACAO DE SALDOS DEVEDORES ATE'
  SET CENTURY ON
  @2,54 SAY mdata
  SET CENTURY OFF
  DO CASE
   CASE mtipo = 1
    @2,75 SAY 'CARRETEIROS'
   CASE mtipo = 2
    @2,75 SAY 'CLIENTES'
   OTHERWISE  
    @2,75 SAY 'FUNCIONARIOS'
  ENDCASE 
  @4,0  SAY 'CONTA'
  @4,11 SAY 'NOME'
  @4,40 SAY 'TIPO'
  @4,70 SAY 'SALDO'
  mfolha = mfolha + 1
  mlinha = 5
  ENDIF
 @mlinha,0   SAY CONTA
 @mlinha,6  SAY NOME
 @mlinha,40  SAY TIPO
 @mlinha,58  SAY -mSAL_ATU PICTURE '9,999,999,999.99D'
 mlinha = mlinha + 1
 mtotsal = mtotsal + mSAL_ATU
 SKIP
ENDDO
@mlinha,35 SAY 'T O T A L    = >'
@mlinha,58 SAY -mtotsal PICTURE '9,999,999,999.99D'
 

?? CHR(27) + CHR(15)

SET DEVICE TO SCREEN
SET PRINTER TO


CLEAR
RETURN
[/code]
Gelson
Usuário Nível 3
Usuário Nível 3
Mensagens: 170
Registrado em: 16 Abr 2005 17:04

Mensagem por Gelson »

Testei e observei as caixa de alertas conforme você postou e está ficando assim:

Valor de 28,96 no txt , fica:

1º) 28,96
2º) 2896
3º)2896

assim sendo grava no dbf como sendo 2896.00

Não uso [,] nos valores então na opção pega as virgulas e remove, não vai remover nada mesmo.

Editei o txt e mudei o valor acima para : 778.687.028.96 e foi gravado o dbf com: 778.69

Editei novamente retirando todos os ponto e deixando 778687028.96 e deu certo, foi gravado corretamente no relsaldo.dbf . Então o problema está nos pontos ?

Talvez vc me pergunte como esta ao get de entrada deste valores no banco de dados, esta assim: GET mvalor PICTURE '9,999,999,999.99'
Avatar do usuário
gvc
Colaborador
Colaborador
Mensagens: 1270
Registrado em: 23 Ago 2005 10:57

Mensagem por gvc »

Vamos por partes.

778.687.028.96 - Que número é esse?
Ou vc coloca 778.687.028,96 ou vc coloca 778,687,028.96
Vc não pode usar o mesmo separador de milhar e decimal.

Poste o código de conversão. Se o primeiro valor é 28,96 então no final das conversões deve ficar 28.96 - Verifique seu código fontes.

vSALDO=STRTRAN(SUBS(LINHAS,59,16),",",".","")
vSALDO=VAL(STRTRAN(vSALDO,",",".",""))

O STRTRAN tem a seguinte sintaxe:

STRTRAN(<cString>, <cSearch>, [<cReplace>], [<nStart>], [<nCount>]) --> cNewString

Arguments

<cString> is the character string or memo field to search.

<cSearch> is the sequence of characters to locate.

<cReplace> is the sequence of characters with which to replace

<cSearch>. If this argument is not specified, the specified instances of the search argument are replaced with a null string ("").

<nStart> is the first occurrence that will be replaced. If this argument is omitted, the default is one.

<nCount> is the number of occurrences to replace. If this argument is not specified, the default is all.

Verifique com vc esta usando-os.
"TRS-80/Sincler/Apple/PC - Clipper Winter 85, tlink 1.0 [pc 10 MHz - 640K] {NEZ 8000 2Kb RAM}"
{POG - Programação Orientada a Gambiarra}
Avatar do usuário
gvc
Colaborador
Colaborador
Mensagens: 1270
Registrado em: 23 Ago 2005 10:57

Mensagem por gvc »

{Veja os #Gil}

CLEAR
mlinha = 66
*mfolha = 1
mtotsal = 0
mdata = CTOD(' / / ')
mtipo = 0
USE CLIENTES INDEX INCLIENT
SELECT 2
USE MOVIM INDEX IMOVIM

@10,01 SAY 'INFORME DATA LIMITE'
@10,21 GET mdata
@11,01 SAY 'INFORME TIPO'
@11,21 GET mtipo PICTURE '9'
@11,23 SAY '1 -> CARRETEIRO, 2 -> CLIENTES, 3 -> FUNCIONARIO'
READ

SET PRINTER TO SALDO.TXT

SET DEVICE TO PRINT

?? CHR(27) + CHR(15)

dbgotop()

SET DEVICE TO PRINT
SELECT 1
mSAL_ATU = 0

WHILE !EOF()

IF CONTA = '99998' .or.;
(mtipo = 1 .and. VAL(CONTA) > 19999) .or.;
(mtipo = 2 .and. (VAL(CONTA) > 30000 .or. VAL(CONTA) < 20000)) .or.;
(mtipo = 3 .and. VAL(CONTA) < 30000) .or.;
(mtipo = 4 .and. (VAL(CONTA) < 1 .OR. VAL(CONTA) > 99998))

dbskip()
loop
end

SELECT 2
mvalor = 0
SEEK CLIENTES->CONTA
DO WHILE CLIENTES->CONTA = CONTA .AND. .NOT. EOF()
IF DATA > mdata
SKIP
LOOP
ENDIF
// O quê é o campo CT? #Gil
IF CT < 10
mvalor = mvalor - VALOR
ELSE
mvalor = mvalor + VALOR
ENDIF
SKIP
ENDDO

SELECT 1
mSAL_ATU = SAL_INI + mvalor
IF mSAL_ATU > 0 // Se o msal_atu é maior que zero, pula para o próximo registro de cliente #Gil
SKIP
LOOP
ENDIF
// Aqui só entra se msal_atu é menor ou igual a ZERO. #Gil
IF mlinha > 50
@1,10 SAY '** RELATORIO ** TESTE'
@1,65 SAY 'FOLHA'
@1,69 SAY mfolha PICTURE '999'
@2,20 SAY 'RELACAO DE SALDOS DEVEDORES ATE'
SET CENTURY ON
@2,54 SAY mdata
SET CENTURY OFF
DO CASE
CASE mtipo = 1
@2,75 SAY 'CARRETEIROS'
CASE mtipo = 2
@2,75 SAY 'CLIENTES'
OTHERWISE
@2,75 SAY 'FUNCIONARIOS'
ENDCASE
@4,0 SAY 'CONTA'
@4,11 SAY 'NOME'
@4,40 SAY 'TIPO'
@4,70 SAY 'SALDO'
mfolha = mfolha + 1
mlinha = 5
ENDIF

@mlinha,0 SAY CONTA
@mlinha,6 SAY NOME
@mlinha,40 SAY TIPO
// O que são estes sinais (-mSAL_ATU) e ('9,999,999,999.99D')? #Gil
@mlinha,58 SAY -mSAL_ATU PICTURE '9,999,999,999.99D'
mlinha = mlinha + 1
mtotsal = mtotsal + mSAL_ATU
SKIP
ENDDO
@mlinha,35 SAY 'T O T A L = >'
// O que são estes sinais (-mtotsal) e ('9,999,999,999.99D')? #Gil
@mlinha,58 SAY -mtotsal PICTURE '9,999,999,999.99D'

?? CHR(27) + CHR(15)

SET DEVICE TO SCREEN
SET PRINTER TO

CLEAR
RETURN
"TRS-80/Sincler/Apple/PC - Clipper Winter 85, tlink 1.0 [pc 10 MHz - 640K] {NEZ 8000 2Kb RAM}"
{POG - Programação Orientada a Gambiarra}
Gelson
Usuário Nível 3
Usuário Nível 3
Mensagens: 170
Registrado em: 16 Abr 2005 17:04

Mensagem por Gelson »

1- Tenho um dbf chamado histórico, e outro chamado movim, no histórico ficam os códigos das transações, ou seja, dos lançamentos, de acordo com CT o lançamento pode ser um credito ou um debito. O dbf movim é onde são gravados estes lançamentos.

Movim [conta, ct, doc, data, valor]

Historico [campo chamado CT ( com os códigos), campo chamado histórico ( com a descrição de cada código)]

2- Já usei os sinais matemáticos e os zeros não ficam de fora, o correto seria menor e igual a zero ficarem de fora

3- o sinal [-] seria para ser impresso menos na frente do valor
4- '9,999,999,999.99D' mascara do get onde D indica que é um débito
5- mesma coisa no mtotal e na mascara do get
Gelson
Usuário Nível 3
Usuário Nível 3
Mensagens: 170
Registrado em: 16 Abr 2005 17:04

Mensagem por Gelson »

[o restante do código esta igual ao anterior]

csaldo := substr(linhas, 59, 16)
alert(csaldo)
csaldo := strtran(csaldo,".","")
alert(csaldo)
csaldo := strtran(csaldo,",",".")
alert(csaldo)
vsaldo := val(csaldo)
alert(str(vsaldo))


10,000,027.96 // resultado do alert

10,000,02796 // resultado do alert

10.000.02796 // resultado do alert

10.000000000 // resultado do alert


depois de testar de tudo que é jeito só consegui resolver o problema pedindo para remover apenas as virgulas, então ficou assim:

csaldo := substr(linhas, 59, 16)
alert(csaldo)
csaldo := strtran(csaldo,",","")
alert(csaldo)
vsaldo := val(csaldo)
alert(str(vsaldo))


Agora preciso descobrir como fazer no meu prg para eleminar os saltos de paginas e os cabeçalhos a partir da segunda pagina, pois da maneira como esta o dbf só grava a primeira pagina. Pelo visto tem de ficar um unico cabeçalho no inicio e depois somente os dados.
Avatar do usuário
gvc
Colaborador
Colaborador
Mensagens: 1270
Registrado em: 23 Ago 2005 10:57

Mensagem por gvc »

Gelson escreveu: 3- o sinal [-] seria para ser impresso menos na frente do valor
4- '9,999,999,999.99D' mascara do get onde D indica que é um débito
Vc não precisa colocar o (-) menos na frente do campo. Ele já sai sozinho. Vc esta invertendo o sinal da variável.

Se vc colocar "@CX 9,999,999,999.99" vai sair CR e DB após números positivos e negativos respectivamente. (Crédito e Débito).

Como vc esta usando a notação 9,999.99 é só usar a função para retirar a virgula. Não tem necessidade de retirar o ponto decimal.

mSAL_ATU = SAL_INI + mvalor
IF mSAL_ATU >= 0 // Se colocar assim, não vão aparecer os registros cujo msal_atu sejam positivos ou zeros #Gil
SKIP
LOOP
ENDIF

imprima tb SAL_INI e mvalor para verificar os respectivos valores.
"TRS-80/Sincler/Apple/PC - Clipper Winter 85, tlink 1.0 [pc 10 MHz - 640K] {NEZ 8000 2Kb RAM}"
{POG - Programação Orientada a Gambiarra}
Gelson
Usuário Nível 3
Usuário Nível 3
Mensagens: 170
Registrado em: 16 Abr 2005 17:04

Mensagem por Gelson »

Olá, GVC

Mesmo fazendo as alterações e os testes e vários outros os valores zerados teimam em sair.

Tomei a liberdade de lhe mandar o ccop19 linkado e os dbf usados no relatório talvez assim fique mais fácil ver onde estou errando.

obrigado mais uma vez
Avatar do usuário
gvc
Colaborador
Colaborador
Mensagens: 1270
Registrado em: 23 Ago 2005 10:57

Mensagem por gvc »

É erro de arredondamento com as variáveis.
Coloque:

mSAL_ATU := round(SAL_INI + mvalor, 2)

Não sei o motivo de acontecer isso, mas nos meus teste isso funcionarou.
"TRS-80/Sincler/Apple/PC - Clipper Winter 85, tlink 1.0 [pc 10 MHz - 640K] {NEZ 8000 2Kb RAM}"
{POG - Programação Orientada a Gambiarra}
Gelson
Usuário Nível 3
Usuário Nível 3
Mensagens: 170
Registrado em: 16 Abr 2005 17:04

Mensagem por Gelson »

GVC,

Não sei nem como lhe agradecer, fico lhe muito grato pela paciência e interesse demonstrado em me ajudar a resolver o problema, fico grato também pelo aprendizado que você me proporcionou com suas explicações ao longo deste tópico.

Um abraço e muito obrigado mais uma vez.

:)Pos
Responder