Formatar números para contas e exibição - TrabalharFormato() e Exibir()

Compartilhe seus scripts, funções, ferramentas e programas
Post Reply
User avatar
Gio
Posts: 472
Joined: 30 Sep 2013, 10:54
Location: Brazil

Formatar números para contas e exibição - TrabalharFormato() e Exibir()

Post by Gio » 10 Jul 2018, 09:31

Bom dia.

Quando solicitamos a um usuário que escreva um número em um campo aberto, podemos nos deparar com números escritos em formatos diferentes do que esperávamos (e até mesmo diferentes do formato que o autohotkey usa para efetuar cálculos matemáticos). Isso pode ser um transtorno, principalmente porque o formato padrão de escrita de números no Brasil é diferente do formato padrão americano.

Explico: vamos supor que eu tenha o seguinte valor de uma mercadoria: dois mil cento e quarenta sete reais e cinquenta e oito centavos. Nesse caso teríamos a seguinte situação:

1. Um brasileiro provavelmente escreveria este número colocando um ponto depois da casa dos milhares e uma vírgula antes dos decimais: 2.147,58
2. Já um americano, provavelmente escreveria este número colocando uma vírgula depois da casa dos milhares e um ponto antes do decimais: 2,147.58
3. Além disso, o autohotkey está programado para trabalhar com um formato que não separa as casas dos milhares e que separam os decimais por pontos: 2147.58

Isso significa que o formato do número que o usuário vai escrever pode ser diferente do que esperávamos, mesmo que seja perfeitamente válido para ele. Se não tivermos cuidado com isso, uma rotina de um programa nosso que se disponha a interpretar estes valores pode falhar de modo catastrófico!

Mas felizmente nós programadores temos a faca e o queijo na mão para resolver o problema, e podemos fazer isso de duas formas. A primeira é restringir o formato de número que podem ser inseridos. Isso significa que se o usuário não inserir um número no formato que esperamos, nós exibimos uma caixa de mensagem de erro e solicitamos que ele adote o formato correto (devidamente explicado na caixa). Esta solução é viável, porém bastante restritiva e um tanto quanto anti-profissional (não vemos programas apresentando essas limitações por aí certo?).

Portanto, a segunda solução, que pode ser usada em conjunto com a primeira é uma função de interpretação dos valores, que seja capaz de pegar número em diferentes formatos e transformá-los para o formato desejado!

:arrow: Assim, temos a seguinte função que formata números para efetuar contas no AutoHotkey:

Code: Select all

TrabalharFormato(ByRef Valor, Casas = 2) 
{
   stringreplace Valor, Valor, %A_Space%
   stringgetpos commapos, Valor, `,
   stringgetpos dotpos, Valor, .
   if (dotpos > commapos and dotpos > 0 and commapos > 0)
   {
      stringreplace Valor, Valor, `,
   }
   if Valor is not number
   {
      stringreplace Valor, Valor, .
      stringreplace Valor, Valor, `,,.
   }
   Valor := Round(Valor, Casas)
   return Valor
}
O que essa função faz é implementar uma sequência de modificações textuais nos pontos e nas vírgulas de modo que o resultado final seja um só, mesmo que os formatos iniciais sejam diferentes. Assim, ela pode receber números em vários formatos de diferentes, mas os devolve em um formato só (que é o formato padrão do autohotkey para efetuar cálculos).

Por exemplo, todos os formatos abaixo serão transformados para o mesmo formato. Assim, é possível até mesmo realizar contas matemáticas sem se preocupar com o formato do número!

Code: Select all

MsgBox % TrabalharFormato("1.038,45")
MsgBox % TrabalharFormato("405.17")
MsgBox % TrabalharFormato("1,009.4")
MsgBox % TrabalharFormato("9.3")
MsgBox % TrabalharFormato("1,000")
MsgBox % TrabalharFormato("8,99") + TrabalharFormato("0.01")
MsgBox % TrabalharFormato("100") + TrabalharFormato("16,17")
Return

TrabalharFormato(ByRef Valor, Casas = 2) 
{
   stringreplace Valor, Valor, %A_Space%
   stringgetpos commapos, Valor, `,
   stringgetpos dotpos, Valor, .
   if (dotpos > commapos and dotpos > 0 and commapos > 0)
   {
      stringreplace Valor, Valor, `,
   }
   if Valor is not number
   {
      stringreplace Valor, Valor, .
      stringreplace Valor, Valor, `,,.
   }
   Valor := Round(Valor, Casas)
   return Valor
}
Uma vez que os número estão no formato padrão de contas, levá-los ao formato brasileiro (ou qualquer outro formato) se torna bastante simples.

:arrow: Assim, temos também a seguinte função que recebe número em formato adequado para contas (AutoHotkey) e transforma em números em formato de exibição no padrão brasileiro:

Code: Select all

Exibir(ByRef Valor)
{
   StringReplace Valor, Valor, .,`,
   RegExReplace(Valor, "\G\d+?(?=(\d{3})+(?:\D|$))", "$0.")
   Return Valor
}
Agora vejamos um exemplo de aplicação das duas funções em conjunto (para trabalhar valores, realizar contas com eles e depois exibi-los em formato brasileiro):

Code: Select all

MsgBox % Exibir(TrabalharFormato("1.038,45"))
MsgBox % Exibir(TrabalharFormato("405.17"))
MsgBox % Exibir(TrabalharFormato("1,009.4"))
MsgBox % Exibir(TrabalharFormato("9.3") + TrabalharFormato("10,4"))
MsgBox % Exibir(TrabalharFormato("1,000") + TrabalharFormato("5.7"))
MsgBox % Exibir(TrabalharFormato("8,99") + TrabalharFormato("0.01"))
MsgBox % Exibir(TrabalharFormato(TrabalharFormato("100") + TrabalharFormato("16,17"), 2)) ; Como a função trabalharformato é a que indica as casas, e a soma mexe nisso, devemos chamá-la após as contas também se quisermos as casas corretamente..
Return

TrabalharFormato(ByRef Valor, Casas = 2) 
{
   stringreplace Valor, Valor, %A_Space%
   stringgetpos commapos, Valor, `,
   stringgetpos dotpos, Valor, .
   if (dotpos > commapos and dotpos > 0 and commapos > 0)
   {
      stringreplace Valor, Valor, `,
   }
   if Valor is not number
   {
      stringreplace Valor, Valor, .
      stringreplace Valor, Valor, `,,.
   }
   Valor := Round(Valor, Casas)
   return Valor
}

Exibir(ByRef Valor)
{
   StringReplace Valor, Valor, .,`,
   RegExReplace(Valor, "\G\d+?(?=(\d{3})+(?:\D|$))", "$0.")
   Return Valor
}
OBSERVAÇÕES:
Ainda que a função TrabalharFomarto() seja bastante abrangente, ela não é perfeita!. Em um campo aberto o usuário pode escrever o que quiser, e até mesmo errar.
Dessa forma, vale a pena também testar o resultado da função antes de usá-lo de alguma forma se a rotina precisa ser perfeita. Uma maneira de fazer isso é usando a condicional If Var is Type. Assim, podemos verificar facilmente se o conteúdo de uma variável está no formato de número para contas do autohotkey.

Exemplo de uso da condicional If Var is Type para esse caso:

Code: Select all

Num1 := "1.040,00"
Num2 := "1040.00"

If Num1 is number
{
	msgbox % "Num1 está no formato adequado para contas!"
}
Else
{
	msgbox % "Num1 NÃO está no formato adequado para contas!"
}

If Num2 is number
{
	msgbox % "Num2 está no formato adequado para contas!"
}
Else
{
	msgbox % "Num2 NÃO está no formato adequado para contas!"
}
"What is suitable automation? Whatever saves your day for the greater matters."
Barcoder - Create QR Codes and other Barcodes using only Autohotkey !!
Post Reply

Return to “Scripts e Funções”