Clipper On Line • Ver Tópico - Função extenso passo a passo

Função extenso passo a passo

Aqui você poderá oferecer suas Contribuições, Dicas e Tutoriais (Texto ou Vídeo) que sejam de interesse de todos.

Moderador: Moderadores

 

Função extenso passo a passo

Mensagempor JoséQuintas » 17 Abr 2021 20:49

Só quando fui converter pra MySQL é que "enxerguei" como ficou fácil.
Sempre pensei de fora pra dentro, mas de dentro pra fora fica muuuito mais fácil.

Acompanhem....

Regra básica de programação:
Dividir o problemão em probleminhas....

O menor problema é..... um único número.
Sem usar array, ou economia de fonte...

FUNCTION ExtensoUnidade( nValor )

LOCAL cTxt := ""

DO CASE
CASE nValor == 1; cTxt := "HUM"
CASE nValor == 2; cTxt := "DOIS"
CASE nValor == 3; cTxt := "TRES"
CASE nValor == 4; cTxt := "QUATRO"
CASE nValor == 5; cTxt := "CINCO"
CASE nValor == 6; cTxt := "SEIS"
CASE nValor == 7; cTxt := "SETE"
CASE nValor == 8; cTxt := "OITO"
CASE nValor == 9; cTxt := "NOVE"
CASE nValor == 10; cTxt := "DEZ"
CASE nValor == 11; cTxt := "ONZE"
CASE nValor == 12; cTxt := "DOZE"
CASE nValor == 13; cTxt := "TREZE"
CASE nValor == 14; cTxt := "QUATORZE"
CASE nValor == 15; cTxt := "QUINZE"
CASE nValor == 16; cTxt := "DEZESSEIS"
CASE nValor == 17; cTxt := "DEZESSETE"
CASE nValor == 18; cTxt := "DEZOITO"
CASE nValor == 19; cTxt := "DEZENOVE"
ENDCASE

RETURN cTxt


Olhem com atenção:
NADA complicado, tudo simples, resolvido de 1 a 19.
Qualquer programador consegue fazer isso, em qualquer linguagem de programação, porque só tem comando básico.
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: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Função extenso passo a passo

Mensagempor JoséQuintas » 17 Abr 2021 21:02

Agora vamos para 2 dígitos.
Até 19 resolvido.
Agora vém 20 a 99
Precisaremos separar o primeiro e o segundo dígito pra isso.
Podemos usar substr(Str()) ou função de divisão com Int() e/ou resto de divisão.
Fazer usando tudo básico, sem economizar fonte.

FUNCTION ExtensoDezena( nValor )

   LOCAL cTxt := ""

   IF nValor == 0
      RETURN cTxt
   ENDIF
   IF nValor < 20
      RETURN ExtensoUnidade( nValor )
   ENDIF


Até 19 resolvido, agora acima disso vamos dividir os dois dígitos

   nDezena := Int( nValor / 10 )
   nUnidade := nValor - ( nDezena * 10 )
   DO CASE
   CASE nDezena == 2; cTxt := "VINTE"
   CASE nDezena == 3; cTxt := "TRINTA"
   CASE nDezena == 4; cTxt := "QUARENTA"
   CASE nDezena == 5; cTxt := "CINQUENTA"
   CASE nDezena == 6; cTxt := "SESSENTA"
   CASE nDezena == 7; cTxt := "SETENTA"
   CASE nDezena == 8; cTxt :=  "OITENTA"
   CASE nDezena == 9; cTxt :=  "NOVENTA"
   ENDCASE


Pronto, resolvido o primeiro dígito.
Agora o segundo dígito.

IF nUnidade != 0
   cTxt += " E " + ExtensoUnidade( nUnidade )
ENDIF

RETURN cTxt


Pronto.
Tudo simples.
Agora temos de 1 a 99.

Eu nunca tinha visto por este lado, de fazer de dentro pra fora, muito mais fácil deste jeito.
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: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Função extenso passo a passo

Mensagempor JoséQuintas » 17 Abr 2021 21:12

Agora de 1 a 999.
Bem parecido com o anterior, só que vamos dividir por 100 ao invés de por 10.

FUNCTION ExtensoCentena( nValor )

   LOCAL cTxt := "", nCentena, nDezena

   IF nValor == 0
      RETURN cTxt
   ENDIF
   IF nValor < 100
      RETURN ExtensoDezena( nValor )
   ENDIF


Até 99 já temos.

IF nValor == 100
   RETURN "CEM"
ENDIF


CEM é exceção, resolvido, agora separar os dígitos.

nCentena := Int( nValor / 100 )
nDezena := nValor - ( nCentena * 100 )


Mesma coisa do anterior, temos o primeiro dígito e o resto

DO CASE
CASE nCentena == 1; cTxt := "CENTO"
CASE nCentena == 2; cTxt := "DUZENTOS"
CASE nCentena == 3; cTxt := "TREZENTOS"
CASE nCentena == 4; cTxt := "QUATROCENTOS"
CASE nCentena == 5; cTxt := "QUINHENTOS"
CASE nCentena == 6; cTxt := "SEISCENTOS"
CASE nCentena == 7; cTxt := "SETECENTOS"
CASE nCentena == 8; cTxt := "OITOCENTOS"
CASE nCentena == 9; cTxt := "NOVECENTOS"
ENDCASE


Pronto, resolvida a primeira parte, agora a segunda, parecida com a rotina de dezena.

IF nDezena != 0
   cTxt += " E  " + ExtensoDezena( nDezena )
ENDIF

RETURN cTxt


Pronto.
Tudo simples.
Agora temos de 1 a 999.

Repetindo: de dentro pra fora, do menor para o maior, tá muito fácil.
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: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Função extenso passo a passo

Mensagempor JoséQuintas » 17 Abr 2021 21:23

Como exemplo, com o que temos até aqui, poderíamos mostrar de 0.01 centavo a 999.99
Mesmo esquema, dividindo a parte inteira e a decimal.

FUNCTION Extenso( nValor )

   LOCAL cTxt := ""

   nInteiro := Int( nValor )
   nDecimal := ( nValor - Int( nValor ) ) * 100

   IF nInteiro != 0
      cTxt += ExtensoCentena( nValor ) + " " + iif( nInteiro == 1, "REAL", "REAIS" )
   ENDIF


Resolvido reais, agora centavos, temos o ajuste do texto em portugues também pra fazer.

   IF nDecimal != 0
      IF nInteiro != 0
         cTxt += " E "
      ENDIF
     cTxt += ExtensoCentena( nDecimal ) + " " + iif( nDecimal == 1, "CENTAVO", "CENTAVOS" )
   ENDIF

   RETURN cTxt


É só pra exemplo. Com as rotinas acima temos o extenso de 0.01 a 999.99.
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: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Função extenso passo a passo

Mensagempor JoséQuintas » 17 Abr 2021 21:39

O que muda num valor acima de 999?
999 999 999
Que vamos separar de 3 em 3, fazer o extenso igual foi feito até agora, mas cada um tem um nome: bilhão, milhão, mil

Então vamos precisar um contador, pra saber qual o grupo que estamos fazendo, e qual o nome que vamos utilizar.
Se for 1 é singular, se for mais de um é plural.
Mas é a rotina que já fizemos pra traduzir o número, acrescentado do texto de unidade.

FUNCTION ExtensoNumero( nValor )

   LOCAL cTxt, cValorTexto, nGrupo

   cValorTexto  := StrZero( nValor, 15 )

   FOR nCont = 1 TO 5
      nValorAtual := Val( Substr( cValorTexto, ( nCont * 3 - 2 ), 3 ) )
      nResto        := Val( Substr( cValorTexto, ( nCont * 3 ) )
      IF nValorAtual != 0
         cTxt += ExtensoCentena( nValorAtual )
         DO CASE
        CASE nGrupo == 1; cTxt += iif( nValorAtual == 1, "QUATRILHAO, "QUATRILHOES" )
        CASE nGrupo == 2; cTxt += iif( nValorAtual ==1, "TRILHAO", "TRILHOES" )
         CASE nGrupo == 3; cTxt += iif( nValorAtual == 1, "BILHAO", "BILHOES" )
        CASE nGrupo == 4; cTxt += "MIL"
        ENDCASE
      ENDIF
      IF nResto != 0
         cTxt += " E "
      ENDIF
   NEXT
   
   RETURN cTxt


Pronto.
Juntando tudo, e alterando a rotina Extenso() pra usar ExtensoNumero() ao invés de ExtensoCentena() temos a rotina de extenso.
Nesta aqui apenas dividimos o número de 3 em 3, e aplicamos a rotina anterior de centena.

Como ajuste final, podemos alterar pra quando for ILHAO REAIS, pra mostrar ILHAO DE REAIS.

IF "ILHAO REAIS" $ cTxt
   cTxt := StrTran( cTxt, "ILHAO REAIS", "ILHAO DE REAIS" )
ENDIF


Esta aqui já varia entre linguagens de programação, porque no MySQL por exemplo não tem FOR/NEXT, ou STRZERO().
Pra substituir o StrZero() podemos usar o LPAD( numero, 15, '0' )
E pra substituir o FOR/NEXT, pode ser o DO WHILE.
Mas basicamente seria a mesma coisa.

Então, de dentro pra fora, do menor para o maior, a rotina acaba ficando super simples.
Só percebi isso algum tempo depois de converter para o MySQL.
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: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Função extenso passo a passo

Mensagempor JoséQuintas » 17 Abr 2021 21:46

E é lógico, em Harbour podemos usar array.
Pra fazer as unidades, dezenas e centenas, e até o valor monetário, poderia reduzir o DO CASE a um array.

aList := { "UM", "DOIS", "TRES", "QUATRO", "CINCO", ... }
cTxt := aList[ nValor ]


Mas é interessante a básica, porque pode ser aplicada em outras linguagens de programação que não tenham array.

Inclusive no Harbour, usei recursividade nisso de grupos, separando três numeros a cada rodada, até acabar o número.
Mas no MySQL não tem recursividade... então tive que mudar isso.
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: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Função extenso passo a passo

Mensagempor JoséQuintas » 17 Abr 2021 22:00

Pensando bem...

Está aí um bom exemplo de código fonte simples.

Usar recursividade foi interessante.... mas já não tinha isso no MySQL
Usar array no Harbour simplifica muito... mas não tinha isso no MySQL
O bom e velho DO CASE atendeu bem a Harbour e MySQL.

Não que não seja pra usar recursos que existam na linguagem de programação....

Mas é como eu disse aqui algumas vezes:
Se ficar craque no básico, pode resolver muita coisa, e pode usar até melhor recursos avançados, quando existirem.

E volto a comentar sobre o uso de -w3 -es2.
É como se a gente voltasse no tempo, e reaprendesse a programar o básico.
E ficar craque no básico, na parte que deixamos escapar antes.
A partir daí, nosso básico pode resolver qualquer parada, inclusive pra entender o mais avançado.

E o que tem a ver com esse extenso?

Usando -w3 -es2, declarando variáveis, vi que separando em rotinas menores, "por assunto", acaba precisando menos variáveis, ou até permitindo o uso de variáveis com mesmo nome.
Isso simplifica muito o trabalho.

Esta rotina de extenso divide em rotinas onde cada uma trata "de seu assunto", por isso ficou simples.
Rotinas simples, pra problemas simples, que resolveram um problemão que era complicado.
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: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Função extenso passo a passo

Mensagempor alxsts » 17 Abr 2021 22:08

Olá!

Não é uma questão técnica, só
comentário relativo ao assunto: Hum ou um?
[]´s
Alexandre Santos (AlxSts)
alxsts
Colaborador

Colaborador
 
Mensagens: 2943
Data de registro: 12 Ago 2008 15:50
Cidade/Estado: São Paulo-SP-Brasil
Curtiu: 21 vezes
Mens.Curtidas: 248 vezes

Função extenso passo a passo

Mensagempor JoséQuintas » 17 Abr 2021 22:31

Encontrei este, que alteraria esse extenso, principalmente a parte dos centavos.

https://www.normaculta.com.br/como-escrever-o-dinheiro-por-extenso/

extenso.png
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: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Função extenso passo a passo

Mensagempor JoséQuintas » 17 Abr 2021 22:33

extenso2.png


E aqui mostra sem o "E" entre os grupos, exceto se o grupo for apenas com centena.
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: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Função extenso passo a passo

Mensagempor JoséQuintas » 17 Abr 2021 22:39

extenso3.png


Só pra rir um pouquinho.....
O oito é redondo, porque é feito com círculos.
Não sei se foi um bom exemplo pra números redondos kkkkk
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: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Função extenso passo a passo

Mensagempor JoséQuintas » 17 Abr 2021 22:43

Mas agora o que interessa:

A informação dessa página que encontrei é confiável?
Alguém tem informação sobre esses detalhes?
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: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Função extenso passo a passo

Mensagempor JoséQuintas » 17 Abr 2021 22:47

Esta parte me deixou na dúvida

Professora de português, revisora e lexicógrafa nascida no Rio de Janeiro e licenciada pela Escola Superior de Educação do Porto, em Portugal (2005). Atua nas áreas da Didática e da Pedagogia.


será português de Portugal, ou português do Brasil, apesar de serem REAIS.
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: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Função extenso passo a passo

Mensagempor JoséQuintas » 17 Abr 2021 22:53

Achei esta:

http://www.linguabrasil.com.br/img/colunas/Coluna_N137_2020-06-10.pdf

extenso4.png


Isso dividiria a rotina de extenso em duas, a não ser que os bancos alteraram a exigência para preenchimento por computador.
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: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Função extenso passo a passo

Mensagempor JoséQuintas » 18 Abr 2021 02:26

Uma das partes, moleza.

   IF nDecimal != 0
      IF nInteiro != 0
         cTxt += " E "
      ENDIF
      cTxt += ze_ExtensoNumero( nDecimal )
      cTxt += " " + iif( nDecimal == 1, "CENTAVO", "CENTAVOS" )
      cTxt += iif( nInteiro == 0, " DE REAL", "" )
   ENDIF
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: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Próximo



Retornar para Contribuições, Dicas e Tutoriais

Quem está online

Usuários vendo este fórum: Google [Bot] 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