Fazer um recibo ou cheque de pagamento com o valor por extenso, emitir uma nota fiscal de venda apresentando o total do documento por extenso, são alguns exemplos de situações que sugerem a necessidade de uma aplicação comercial para definir um valor monetário em reais por extenso.
Este artigo tem como objetivo demonstrar os passos necessários para construir uma aplicação Delphi para definir um valor por extenso.
Primeiramente deve-se criar uma aplicação no ambiente de desenvolvimento Delphi 7 através da opção do menu "File|New|Application..." e implementar os seguintes passos:
1º Passo:
Desenvolver o formulário principal como sugere a Figura 1. Atenção: observe que as caixas de textos explicativos utilizadas na figura apresentam a ordem sequencial e o nome do componente, a página da sua localização e as propriedades que devem ser alteradas com os respectivos valores.

2º Passo:
Implementar em uma unidade de códigos (unit) construída através da opção do menu "File|New|Unit" o subprograma "valorPorExtenso", como apresentado na Listagem 1. Salvar o arquivo fonte da unit implementada com o nome "Um".
unit Um;
interface
function valorPorExtenso(vlr: real): string;
implementation
uses SysUtils;
function valorPorExtenso(vlr: real): string;
const
unidade: array[1..19] of string = ('um', 'dois', 'três', 'quatro', 'cinco',
'seis', 'sete', 'oito', 'nove', 'dez', 'onze',
'doze', 'treze', 'quatorze', 'quinze', 'dezesseis',
'dezessete', 'dezoito', 'dezenove');
centena: array[1..9] of string = ('cento', 'duzentos', 'trezentos',
'quatrocentos', 'quinhentos', 'seiscentos',
'setecentos', 'oitocentos', 'novecentos');
dezena: array[2..9] of string = ('vinte', 'trinta', 'quarenta', 'cinquenta',
'sessenta', 'setenta', 'oitenta', 'noventa');
qualificaS: array[0..4] of string = ('', 'mil', 'milhão', 'bilhão', 'trilhão');
qualificaP: array[0..4] of string = ('', 'mil', 'milhões', 'bilhões', 'trilhões');
var
inteiro: Int64;
resto: real;
vlrS, s, saux, vlrP, centavos: string;
n, unid, dez, cent, tam, i: integer;
umReal, tem: boolean;
begin
if (vlr = 0)
then begin
valorPorExtenso := 'zero';
exit;
end;
inteiro := trunc(vlr); // parte inteira do valor
resto := vlr - inteiro; // parte fracionária do valor
vlrS := inttostr(inteiro);
if (length(vlrS) > 15)
then begin
valorPorExtenso := 'Erro: valor superior a 999 trilhões.';
exit;
end;
s := '';
centavos := inttostr(round(resto * 100));
// definindo o extenso da parte inteira do valor
i := 0;
umReal := false; tem := false;
while (vlrS <> '0') do
begin
tam := length(vlrS);
// retira do valor a 1a. parte, 2a. parte, por exemplo, para 123456789:
// 1a. parte = 789 (centena)
// 2a. parte = 456 (mil)
// 3a. parte = 123 (milhões)
if (tam > 3)
then begin
vlrP := copy(vlrS, tam-2, tam);
vlrS := copy(vlrS, 1, tam-3);
end
else begin // última parte do valor
vlrP := vlrS;
vlrS := '0';
end;
if (vlrP <> '000')
then begin
saux := '';
if (vlrP = '100')
then saux := 'cem'
else begin
n := strtoint(vlrP); // para n = 371, tem-se:
cent := n div 100; // cent = 3 (centena trezentos)
dez := (n mod 100) div 10; // dez = 7 (dezena setenta)
unid := (n mod 100) mod 10; // unid = 1 (unidade um)
if (cent <> 0)
then saux := centena[cent];
if ((dez <> 0) or (unid <> 0))
then begin
if ((n mod 100) <= 19)
then begin
if (length(saux) <> 0)
then saux := saux + ' e ' + unidade[n mod 100]
else saux := unidade[n mod 100];
end
else begin
if (length(saux) <> 0)
then saux := saux + ' e ' + dezena[dez]
else saux := dezena[dez];
if (unid <> 0)
then if (length(saux) <> 0)
then saux := saux + ' e ' + unidade[unid]
else saux := unidade[unid];
end;
end;
end;
if ((vlrP = '1') or (vlrP = '001'))
then begin
if (i = 0) // 1a. parte do valor (um real)
then umReal := true
else saux := saux + ' ' + qualificaS[i];
end
else if (i <> 0)
then saux := saux + ' ' + qualificaP[i];
if (length(s) <> 0)
then s := saux + ', ' + s
else s := saux;
end;
if (((i = 0) or (i = 1)) and (length(s) <> 0))
then tem := true; // tem centena ou mil no valor
i := i + 1; // próximo qualificador: 1- mil, 2- milhão, 3- bilhão, ...
end;
if (length(s) <> 0)
then begin
if (umReal)
then s := s + ' real'
else if (tem)
then s := s + ' reais'
else s := s + ' de reais';
end;
// definindo o extenso dos centavos do valor
if (centavos <> '0') // valor com centavos
then begin
if (length(s) <> 0) // se não é valor somente com centavos
then s := s + ' e ';
if (centavos = '1')
then s := s + 'um centavo'
else begin
n := strtoint(centavos);
if (n <= 19)
then s := s + unidade[n]
else begin // para n = 37, tem-se:
unid := n mod 10; // unid = 37 % 10 = 7 (unidade sete)
dez := n div 10; // dez = 37 / 10 = 3 (dezena trinta)
s := s + dezena[dez];
if (unid <> 0)
then s := s + ' e ' + unidade[unid];
end;
s := s + ' centavos';
end;
end;
valorPorExtenso := s;
end;
end.
As unidades ou bibliotecas de códigos (unit's) representam no Delphi a forma de disponibilizar um conjunto de subprogramas (functions e/ou procedures) destinados a solucionar uma série de tarefas bastante corriqueiras, como por exemplo, a função para definir o valor por extenso. Na Listagem 2 pode-se observar a estrutura básica de uma unit.
// Cabeçalho da unidade de códigos.
// Atenção: O nome interno da unit deve ser o mesmo nome dado ao arquivo fonte
unit NomeDaUnit;
interface
// Comunicação entre dois meios (dispositivos). Contêm o cabeçalho
// dos procedimentos e funções declarados na unit, declaração
// de objetos globais e o uso de outras unidades.
implementation
// Corpo dos procedimentos e funções anunciados na seção de
// interface e declarações de objetos locais.
end.
Outro aspecto destacável da programação foi a utilização da estrutura de controle de erros "try – except - end" que irá proteger o código para eventuais erros de conversão de tipo com as funções "StrToFloat" e "StrToInt".
3º Passo:
Agora novamente no formulário principal deve-se:
-
Fazer a referência a unit "Um", implementada no passo 2, através da opção do menu "File|Use Unit...". A conclusão deste passo resulta na seguinte linha de código:
uses Um;
-
Implementar o seguinte código no evento "onClick" do botão "Extenso do Valor": Memo1.Clear;
try Memo1.Lines.Add(valorPorExtenso(StrToFloat(Edit1.Text))); except end;
O algoritmo para resolver o problema do "valor por extenso" acaba de alguma forma apresentando uma solução complexa uma vez que várias situações devem ser previstas, por exemplo:
- qualificadores do valor no singular (qualificaS) e no plural (qualificaP): milhão e milhões, bilhão e bilhões;
- valores com tratamento diferenciado: um real, cinco reais, cem mil reais, cento e cinco milhões de reais;
- extenso da parte inteira do valor e da parte fracionária definidos separadamente;
- limitação do valor monetário de entrada a 999 trilhões.
Veja também: Valor por Extenso em uma Aplicação Java.
Ilustrando a execução da aplicação:



