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