Ir para conteúdo
  • Cadastre-se

dev botao

  • Este tópico foi criado há 1096 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.

Recommended Posts

Postado

Estou com um problema com arredondamento no valor do boleto na remessa

Estou enviando um boleto ao banco do brasil com valor 36.42, mas por algum motivo está indo na remessa com um centavo a mais.

ValorTitulo=36.42

Quando o processo chega na função MontarCodigoBarras do arquivo ACBrBancoBrasil.pas o valor do titulo é alterado para 36.4201 e ao passa na linha

IntToStrZero(Round(ACBrTitulo.ValorDocumento * 100), 10)

ele devolve o valor arredondado para 36.43

CodigoBarras = 0019881600000036430000002851442210020579117

Não sei onde ele localizou o valor 36.4201 por não tem em lugar algum esse valor com decimais 4201 mesmo assim não deveria arredonda para cima

At revision: 23636

Screenshot_1.png

Screenshot_2.png

  • Consultores
Postado

tudo indica que sua variável é float;

altere para decimal por exemplo

Consultor SAC ACBr

Victor H Gonzales - Pandaaa
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.  Discord

Projeto ACBr - A maior comunidade Open Source de Automação Comercial do Brasil

Participe de nosso canal no Discord e fique ainda mais próximo da Comunidade !!

"Aprender é a única coisa que a mente nunca se cansa, nunca tem medo e nunca se arrepende” - Leonardo da Vinci

"Ter sucesso é falhar repetidamente, mas sem perder o entusiasmo"

Postado
3 minutos atrás, Nemi vieira disse:

Estou com um problema com arredondamento no valor do boleto na remessa

Estou enviando um boleto ao banco do brasil com valor 36.42, mas por algum motivo está indo na remessa com um centavo a mais.

ValorTitulo=36.42

Quando o processo chega na função MontarCodigoBarras do arquivo ACBrBancoBrasil.pas o valor do titulo é alterado para 36.4201 e ao passa na linha

IntToStrZero(Round(ACBrTitulo.ValorDocumento * 100), 10)

ele devolve o valor arredondado para 36.43

CodigoBarras = 0019881600000036430000002851442210020579117

Não sei onde ele localizou o valor 36.4201 por não tem em lugar algum esse valor com decimais 4201 mesmo assim não deveria arredonda para cima

At revision: 23636

Screenshot_1.png

Screenshot_2.png

como sua aplicação faz essa atribuição dos valores para o componente? Teve uns casos no passado, que o programador enviava o valor como asfloat ou .value, e vinha errado.

Se vier com dois decimais, nao ocasiona isso, posta como chega seu valor, atribuicao dos valores.

Postado (editado)

agora olha como está gravado no banco de dados esse campo bol_valor, se está 36,42 ou 36,426666666666.

E voce deve arredondar na gravação, senao vai ter dor de cabeça sempre,no banco, ja deve entrar o valor com 2 decimais. dai para frente, é cair pro abraço. Dizimas, a gente deixa em valor unitario apenas.

Editado por Antonio Gomes
  • Moderadores
Postado

Eu diria pra você fazer o inverso, trocar Double e AsFloat por Currency e AsCurrency.

Não tem motivo pra um campo de valor monetário precisar de ponto flutuante.

Equipe ACBr BigWings
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr

 

 

Postado
3 horas atrás, Victor H. Gonzales - Panda disse:

tudo indica que sua variável é float;

altere para decimal por exemplo

se eu usar o  as AsCurrency do field ele devolver  o valor  36.4201

Postado (editado)
3 horas atrás, BigWings disse:

Eu diria pra você fazer o inverso, trocar Double e AsFloat por Currency e AsCurrency.

Não tem motivo pra um campo de valor monetário precisar de ponto flutuante.

se eu usar o  AsCurrency do field ele devolver  o valor  36.4201, depois que vi isso alterei no componente e deu certo, vou realizar alguns testes para confirmar

Editado por Nemi vieira
Postado (editado)

Atualizei o componente e problema voltou, depois de alguns testes localizei fonte do problema

O problema foi ocasionado por essa função

SetRoundMode(rmUp);

tive problemas com arrendamento quando a segunda casa decimal era 5 o sistema não arredondava para cima então incrementei essa função SetRoundMode(rmUp)

resolveu meu problema de arredondamento mas  como  o componente ACBBoleto faz uso da função round na função TACBrBancoBrasil.MontarCodigoBarras ele faz o arredondamento errado x.4201 para x.423 quanto que na verdade deveria fica x.42

fonte

Rotinas de arredondamento: Round, RoundTo, SimpleRoundTo, SetRoundMode e GetRoundMode (devmedia.com.br)

 

Uma das soluções para manter a compatibilidade  foi essa na função TACBrBancoBrasil.MontarCodigoBarras 

 //Salva o modo de arredondamento utilizado pelo o usuário, caso não seja o modo default do delphi
         ModeRoundUser:=GetRoundMode();
         Try
           //seta o modo default para evitar arredondamento errado tipo de "0.4201" para "0.423"
           SetRoundMode(rmNearest);

           CodigoBarras := IntToStrZero(Banco.Numero, 3) +
                           '9' +
                           FatorVencimento +
                           IntToStrZero(Round(ACBrTitulo.ValorDocumento * 100), 10) +
                           IfThen((Length(AConvenio) = 7), '000000', '') +
                           ANossoNumero +
                           IfThen((Length(AConvenio) < 7), PadLeft(OnlyNumber(Cedente.Agencia), 4, '0'), '') +
                           IfThen((Length(AConvenio) < 7), IntToStrZero(StrToIntDef(OnlyNumber(Cedente.Conta),0),8), '') +
                           ACBrTitulo.Carteira;
         Finally
           //Restabelece o arredondamento do usuário
           SetRoundMode(ModeRoundUser);
         end

 

Screenshot_8.png

 

ACBrBancoABCBrasil.pas

Editado por Nemi vieira
  • Consultores
Postado
1 hora atrás, Nemi vieira disse:

O problema foi ocasionado por essa função

SetRoundMode(rmUp);

tive problemas com arrendamento quando a segunda casa decimal era 5 o sistema não arredondava para cima então incrementei essa função SetRoundMode(rmUp)

 

1 hora atrás, Nemi vieira disse:

Uma das soluções para manter a compatibilidade  foi essa na função TACBrBancoBrasil.MontarCodigoBarras 

 //Salva o modo de arredondamento utilizado pelo o usuário, caso não seja o modo default do delphi
         ModeRoundUser:=GetRoundMode();
         Try
           //seta o modo default para evitar arredondamento errado tipo de "0.4201" para "0.423"
           SetRoundMode(rmNearest);

           CodigoBarras := IntToStrZero(Banco.Numero, 3) +
                           '9' +
                           FatorVencimento +
                           IntToStrZero(Round(ACBrTitulo.ValorDocumento * 100), 10) +
                           IfThen((Length(AConvenio) = 7), '000000', '') +
                           ANossoNumero +
                           IfThen((Length(AConvenio) < 7), PadLeft(OnlyNumber(Cedente.Agencia), 4, '0'), '') +
                           IfThen((Length(AConvenio) < 7), IntToStrZero(StrToIntDef(OnlyNumber(Cedente.Conta),0),8), '') +
                           ACBrTitulo.Carteira;
         Finally
           //Restabelece o arredondamento do usuário
           SetRoundMode(ModeRoundUser);
         end

Você está mudando o sistema de arredondamento global para resolver um problema local. Você precisa fazer o contrário.

[]'s

Consultor SAC ACBr

Elton
Profissionalize o ACBr na sua empresa, conheça o ACBr Pro.

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Um engenheiro de Controle de Qualidade(QA) entra num bar. Pede uma cerveja. Pede zero cervejas.
Pede 99999999 cervejas. Pede -1 cervejas. Pede um jacaré. Pede asdfdhklçkh.
  • Moderadores
Postado

É preciso cuidado ao usar esse modificador, ele afeta os cálculos globalmente, inclusive a impressão do boleto sai errada com o Fortes Report.

Não vejo necessidade de você alterar o fonte do ACBrBoleto, basta isolar a chamada ao SetRoundMode dentro de uma rotina do seu código, sempre voltando ao modo anterior.

Equipe ACBr BigWings
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr

 

 

Postado
16 minutos atrás, BigWings disse:

É preciso cuidado ao usar esse modificador, ele afeta os cálculos globalmente, inclusive a impressão do boleto sai errada com o Fortes Report.

Não vejo necessidade de você alterar o fonte do ACBrBoleto, basta isolar a chamada ao SetRoundMode dentro de uma rotina do seu código, sempre voltando ao modo anterior.

essa foi a outra forma de resolver o problema, foi que eu fiz, sobre  as alterações no ACBrBoleto seria para nao pegar essas  alterçoes feita pelo usuário, claro tem que ver os pros e contra

  • Consultores
Postado
Em 19/11/2021 at 15:27, Nemi vieira disse:

Atualizei o componente e problema voltou, depois de alguns testes localizei fonte do problema

O problema foi ocasionado por essa função

SetRoundMode(rmUp);

tive problemas com arrendamento quando a segunda casa decimal era 5 o sistema não arredondava para cima então incrementei essa função SetRoundMode(rmUp)

resolveu meu problema de arredondamento mas  como  o componente ACBBoleto faz uso da função round na função TACBrBancoBrasil.MontarCodigoBarras ele faz o arredondamento errado x.4201 para x.423 quanto que na verdade deveria fica x.42

fonte

Rotinas de arredondamento: Round, RoundTo, SimpleRoundTo, SetRoundMode e GetRoundMode (devmedia.com.br)

 

Uma das soluções para manter a compatibilidade  foi essa na função TACBrBancoBrasil.MontarCodigoBarras 

 //Salva o modo de arredondamento utilizado pelo o usuário, caso não seja o modo default do delphi
         ModeRoundUser:=GetRoundMode();
         Try
           //seta o modo default para evitar arredondamento errado tipo de "0.4201" para "0.423"
           SetRoundMode(rmNearest);

           CodigoBarras := IntToStrZero(Banco.Numero, 3) +
                           '9' +
                           FatorVencimento +
                           IntToStrZero(Round(ACBrTitulo.ValorDocumento * 100), 10) +
                           IfThen((Length(AConvenio) = 7), '000000', '') +
                           ANossoNumero +
                           IfThen((Length(AConvenio) < 7), PadLeft(OnlyNumber(Cedente.Agencia), 4, '0'), '') +
                           IfThen((Length(AConvenio) < 7), IntToStrZero(StrToIntDef(OnlyNumber(Cedente.Conta),0),8), '') +
                           ACBrTitulo.Carteira;
         Finally
           //Restabelece o arredondamento do usuário
           SetRoundMode(ModeRoundUser);
         end

 

Screenshot_8.png

 

ACBrBancoABCBrasil.pas 74 kB · 1 download

Boa tarde,

Consegue fazer no programa de exemplo recriar o problema onde a variável gera o problema da linha 36,43 e valor 36,42 ?

 

Consultor SAC ACBr

Victor H Gonzales - Pandaaa
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.  Discord

Projeto ACBr - A maior comunidade Open Source de Automação Comercial do Brasil

Participe de nosso canal no Discord e fique ainda mais próximo da Comunidade !!

"Aprender é a única coisa que a mente nunca se cansa, nunca tem medo e nunca se arrepende” - Leonardo da Vinci

"Ter sucesso é falhar repetidamente, mas sem perder o entusiasmo"

  • Este tópico foi criado há 1096 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar Agora
×
×
  • Criar Novo...

Informação Importante

Colocamos cookies em seu dispositivo para ajudar a tornar este site melhor. Você pode ajustar suas configurações de cookies, caso contrário, assumiremos que você está bem para continuar.