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: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

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, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, 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: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

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, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, 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