Clipper On Line • Ver Tópico - Ajuda com rotina

Ajuda com rotina

Projeto MiniGui - Biblioteca visual para Harbour/xHarbour

Moderador: Moderadores

 

Ajuda com rotina

Mensagempor Paulo_CPV » 28 Fev 2014 14:56

Boa tarde!

Estou fazendo uma rotina para calcular o modulo 10 e não estou conseguindo identificar o erro, alguém poderia me ajudar a identificar este erro? []'s Paulo - Jacareí/SP


nValor := "95832019"

FUNCTION Modulo10(nValor)

   PRIVATE nTamanho , nSoma , Resultado := ARRAY(100) , nFator , nResto , i
   PRIVATE cResult
   
   nTamanho := LEN(nValor)
   nFator   := 2

   FOR i = nTamanho TO 1
   
      Resultado[i] := VAL( SUBSTR( nValor , i , 1 ) ) * nFator
      
      IF nFator = 2
      
         nFator := 1
         
      ELSE
      
         nFator := 2
         
      ENDIF
   
   NEXT i

   nSoma := 0
   
   FOR i = 1 TO nTamanho
   
      IF Resultado[i] > 9 // Está dando erro aqui (Erro nos parâmetros)
      
         nSoma := nSoma + VAL( SUBSTR( STR( Resultado[i] ) , 1 , 1 ) ) + ;
                          VAL( SUBSTR( STR( Resultado[i] ) , 2 , 1 ) )
      
      ELSE
      
         nSoma := nSoma + Resultado[i]
      
      ENDIF
   
   NEXT i
   
   nResto := MOD( nSoma , 10 )
   
   cResult := IF( nResto = 0 , "0" , STR(INT( 10 - nResto ) ) )

RETURN(MSGBOX(nValor + "-" + ALLTRIM(cResult) , "Teste"))
Paulo_CPV
Usuário Nível 3

Usuário Nível 3
 
Mensagens: 178
Data de registro: 07 Mar 2013 10:27
Cidade/Estado: Jacarei/SP
Curtiu: 0 vez
Mens.Curtidas: 1 vez

Ajuda com rotina

Mensagempor Toledo » 28 Fev 2014 16:04

Amigo, o erro está na linha 12...

FOR i = nTamanho TO 1

Faltou o STEP -1

FOR i = nTamanho TO 1 STEP -1


Abraços,
Toledo - Clipper On Line
toledo@pctoledo.com.br
Harbour 3.2/MiniGui/HwGui
Faça uma doação para o fórum, clique neste link: http://www.pctoledo.com.br/doacao
Avatar de usuário

Toledo
Administrador

Administrador
 
Mensagens: 3038
Data de registro: 22 Jul 2003 18:39
Cidade/Estado: Araçatuba - SP
Curtiu: 263 vezes
Mens.Curtidas: 258 vezes

Ajuda com rotina

Mensagempor Paulo_CPV » 28 Fev 2014 23:47

Boa noite, Toledo!

Muito obrigado pela sua ajuda, eu tinha esquecido do "STEP", mas agora estou com outro problema é no calculo do modulo 10. ele não está fazendo a somatória correta. Exemplo: 261533-4

No segundo FOR onde é feito a somatória:

i Valor do Array
1 2
2 12 (1 + 2 = 3)
3 1
4 10 (1 + 0 = 1)
5 3
6 6
Somatória: 2 + 3 + 1 + 1 + 3 + 6 = 16 -> Aqui a somatória está dando 12.

Código:

   nSoma := 0
   
   FOR i = 1 TO nTamanho
   
      nSoma := nSoma + IF( Resultado[i] > 9 , VAL( SUBSTR( STR( Resultado[i] ) , 1 , 1 ) ) + ;
                                  VAL( SUBSTR( STR( Resultado[i] ) , 2 , 1 ) ) , Resultado[i] )
                     
   NEXT i


O que será que eu estou fazendo de errado?

[]'s
Paulo - Jacareí/SP
Paulo_CPV
Usuário Nível 3

Usuário Nível 3
 
Mensagens: 178
Data de registro: 07 Mar 2013 10:27
Cidade/Estado: Jacarei/SP
Curtiu: 0 vez
Mens.Curtidas: 1 vez

Ajuda com rotina

Mensagempor Toledo » 01 Mar 2014 07:45

Amigo, nesta parte do seu código, troque todas as ocorrências de:

STR( Resultado[i] )


Por:
STR( Resultado[i], 2, 0 )


ou por:
AllTrim(STR( Resultado[i] ))


Abraços,
Toledo - Clipper On Line
toledo@pctoledo.com.br
Harbour 3.2/MiniGui/HwGui
Faça uma doação para o fórum, clique neste link: http://www.pctoledo.com.br/doacao
Avatar de usuário

Toledo
Administrador

Administrador
 
Mensagens: 3038
Data de registro: 22 Jul 2003 18:39
Cidade/Estado: Araçatuba - SP
Curtiu: 263 vezes
Mens.Curtidas: 258 vezes

Ajuda com rotina

Mensagempor JoséQuintas » 01 Mar 2014 20:40

Nota: só não entendi porque foi postado em minigui.

Sugestões, vou mostrar por etapa, assim pode aproveitar a parte que quiser/puder

1) Declarar as variáveis como locais e não private

2) Usando iif()
IF nFator = 2 
   nFator := 1
ELSE
   nFator := 2
ENDIF


pode trocar por:
nFator := iif( nFator == 2, 1, 2 )


3)
a) trecho corrigido
  IF Resultado[i] > 9 
   nSoma := nSoma + VAL( SUBSTR( STR( Resultado[i],2 ) , 1 , 1 ) ) + ;
           VAL( SUBSTR( STR( Resultado[i],2) ) , 2 , 1 ) )
  ELSE
   nSoma := nSoma + Resultado[i]
  ENDIF


b) Eliminar IF/ELSE já que zero não faz diferença na soma
   nSoma := nSoma + VAL( SUBSTR( STR( Resultado[i],2 ) , 1 , 1 ) ) + ; 
           VAL( SUBSTR( STR( Resultado[i],2) ) , 2 , 1 ) )


c) O segundo FOR/NEXT utiliza os resultados do primeiro FOR/NEXT que foram salvos em array
Então, elimine a necessidade de array, colocando o que tem dentro do segundo FOR/NEXT dentro do primeiro

4) Vi que as variáveis já indicam o tipo de conteúdo, mas imagino que usou nValor ao invés de cValor pra depois alterar

5) Na parte final, Str( Int( 10 - nResto ) ), melhor trocar direto para Str( 10 - nResto, 1 )
Isso também já elimina a necessidade do AllTrim() no final
Ou melhor ainda, faça por número e converta só no final

6) Apesar da compilação aceitar, talvez por compatibilidade clipper, fica parecendo uma função escrever assim RETURN(1), acrescente um espaço após return. (Também previne caso o compilador passe a rejeitar isso em versões futuras)

A sua rotina com as alterações que mencionei:

nValor := "95832019"

FUNCTION Modulo10(nValor)
LOCAL nTamanho , nSoma , cResultado, nFator , nResto , i
LOCAL cResult

nTamanho := LEN(nValor)
nFator := 2
nSoma  := 0

FOR i = nTamanho TO nTamanho
  cResultado := VAL( SUBSTR( nValor , i , 1 ) ) * nFator
  nSoma := nSoma + VAL( SUBSTR( STR( cResultado, 2 ) , 1 , 1 ) ) + ;
           VAL( SUBSTR( STR( cResultado, 2 ) , 2 , 1 ) )
  nFator := iif( nFator = 2, 1, 2 )
NEXT i

nResto := MOD( nSoma , 10 )
nResto := iif( nResto == 0, 0, 10 - nResto )
cResult := STR( nResto, 1 )
RETURN (MSGBOX(nValor + "-" + cResult , "Teste"))
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18152
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1215 vezes

Ajuda com rotina

Mensagempor JoséQuintas » 01 Mar 2014 20:51

Complemento:
Essas coisas, às vezes deixamos pra depois e esquecemos.
Fui olhar a minha, e encontrei isto:
nSoma := nSoma - ( Int( nSoma / 10 ) * 10 )


onde poderia ser uma destas:
//nSoma := Mod( nSoma, 10 )
nSoma := nSoma % 10
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18152
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1215 vezes

Ajuda com rotina

Mensagempor Paulo_CPV » 06 Mar 2014 16:26

Boa tarde!

Obrigado pelas dicas dos caros amigos.

[]'s
Paulo - Jacareí/SP
Paulo_CPV
Usuário Nível 3

Usuário Nível 3
 
Mensagens: 178
Data de registro: 07 Mar 2013 10:27
Cidade/Estado: Jacarei/SP
Curtiu: 0 vez
Mens.Curtidas: 1 vez




Retornar para MiniGui

Quem está online

Usuários vendo este fórum: Nenhum usuário registrado online e 8 visitantes


Ola Amigo, espero que meu site e forum tem lhe beneficiado, com exemplos e dicas de programacao.
Entao divulgue o link da Doacao abaixo para seus amigos e redes sociais ou faça uma doacao para o site forum...
MUITO OBRIGADO PELA SUA DOACAO!
Faça uma doação para o forum
cron
v
Olá visitante, seja bem-vindo ao Fórum Clipper On Line!
Efetue o seu login ou faça o seu Registro