Ajuda com rotina

Projeto MiniGui - Biblioteca visual para Harbour/xHarbour

Moderador: Moderadores

Paulo_CPV
Usuário Nível 3
Usuário Nível 3
Mensagens: 178
Registrado em: 07 Mar 2013 10:27
Localização: Jacarei/SP

Ajuda com rotina

Mensagem por Paulo_CPV »

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

Código: Selecionar todos


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"))
Avatar do usuário
Toledo
Administrador
Administrador
Mensagens: 3133
Registrado em: 22 Jul 2003 18:39
Localização: Araçatuba - SP
Contato:

Ajuda com rotina

Mensagem por Toledo »

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

Código: Selecionar todos

FOR i = nTamanho TO 1
Faltou o STEP -1

Código: Selecionar todos

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
Paulo_CPV
Usuário Nível 3
Usuário Nível 3
Mensagens: 178
Registrado em: 07 Mar 2013 10:27
Localização: Jacarei/SP

Ajuda com rotina

Mensagem por Paulo_CPV »

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:

Código: Selecionar todos

	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
Avatar do usuário
Toledo
Administrador
Administrador
Mensagens: 3133
Registrado em: 22 Jul 2003 18:39
Localização: Araçatuba - SP
Contato:

Ajuda com rotina

Mensagem por Toledo »

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

Código: Selecionar todos

STR( Resultado[i] )
Por:

Código: Selecionar todos

STR( Resultado[i], 2, 0 )
ou por:

Código: Selecionar todos

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 do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20416
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP
Curtiram: 1 vez

Ajuda com rotina

Mensagem por JoséQuintas »

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()

Código: Selecionar todos

IF nFator = 2 
   nFator := 1 
ELSE 
   nFator := 2 
ENDIF 
pode trocar por:

Código: Selecionar todos

nFator := iif( nFator == 2, 1, 2 )
3)
a) trecho corrigido

Código: Selecionar todos

  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

Código: Selecionar todos

   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:

Código: Selecionar todos

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, multithread, gtwvg, fivewin 25.12, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui), (hmg3), (hmg extended), (oohg), PNotepad, ASP, (Linux/Flagship/harbour 3.2)
"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 do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20416
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP
Curtiram: 1 vez

Ajuda com rotina

Mensagem por JoséQuintas »

Complemento:
Essas coisas, às vezes deixamos pra depois e esquecemos.
Fui olhar a minha, e encontrei isto:

Código: Selecionar todos

nSoma := nSoma - ( Int( nSoma / 10 ) * 10 )
onde poderia ser uma destas:

Código: Selecionar todos

//nSoma := Mod( nSoma, 10 )
nSoma := nSoma % 10
José M. C. Quintas
Harbour 3.2, mingw, multithread, gtwvg, fivewin 25.12, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui), (hmg3), (hmg extended), (oohg), PNotepad, ASP, (Linux/Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Paulo_CPV
Usuário Nível 3
Usuário Nível 3
Mensagens: 178
Registrado em: 07 Mar 2013 10:27
Localização: Jacarei/SP

Ajuda com rotina

Mensagem por Paulo_CPV »

Boa tarde!

Obrigado pelas dicas dos caros amigos.

[]'s
Paulo - Jacareí/SP
Responder