Ir para conteúdo
  • Cadastre-se

dev botao

NFC-e problema calcular vTotTrib


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

Recommended Posts

  • Membros Pro

Olá a todos,

Estou com um problema chato em meu aplicativo na hora de calcular a tag <vTotTrib> dentro de <total>.

Vira e mexe, quando tem muitos itens na nota, essa tag acaba dando um valor 2 ou 3 centavos menor que o total dos tributos de cada item somados, o que me remete ao erro: Rejeicao: Total do Valor Aproximado dos Tributos difere do somatorio dos itens

Pois bem... No inicio eu fazia assim:

with Imposto do
                begin

  • vTotTrib := RoundTo((dtm_banco.z_formulas.Fields[0].AsFloat + dtm_banco.z_formulas.Fields[2].AsFloat + dtm_banco.z_formulas.Fields[3].AsFloat)/100,-2)* dtm_banco.z_nfcevendas_itensvl_total.AsFloat;
  • total_tributos := total_tributos + vTotTrib; //variavel do tipo Double

E esse erro acontecia direto, ao analisar o resultado dessas linhas, observei que o vTotTrib recebia corretamente arredondando para 2 casas decimais, exemplo o número 1,567 era recebido como 11,57... Mas por algum motivo a variável "total_tributos" recebia o valor 1,567, ocasionando em diferenças de mais de 0,01 com muitos itens e rejeição posterior.

Sem saber porque isso ocorria, tentei uma nova abordagem, e estou fazendo assim agora:

  • vTotTrib := (dtm_banco.z_formulas.Fields[0].AsFloat + dtm_banco.z_formulas.Fields[2].AsFloat + dtm_banco.z_formulas.Fields[3].AsFloat) / 100 * dtm_banco.z_nfcevendas_itensvl_total.AsFloat;
  • total_tributos := RoundTo(total_tributos + vTotTrib,-2);

Se observarem, tirei o RoundTo da primeira linha. Fiz isso porque observei que usando ele ou não, por algum motivo, sempre recebo o valor arredondado para 2 casas decimais, CREIO que isso seja feito internamente pelo componente.

Na linha debaixo, forcei arredondar para duas casas, já que ele não recebia o valor arredondado. Com isso fiquei na expectativa de os valores passarem a bater certo, o que realmente ocorreu em testes que realizei reproduzindo notas das quais tive tal problema.

Isso diminuiu drasticamente a ocorrência desse erro, mas não o eliminou totalmente. Ainda ocorre com notas onde possuem muitos itens, onde ele simplesmente soma menos do que deveria.

Procurei explicar detalhadamente o problema para que algum amigo possa me indicar como o mesmo faz em seu aplicativo.

Desde já agradeço a atenção

Editado por doidopb
Link para o comentário
Compartilhar em outros sites

  • Membros Pro

Analisando uma nota com o tal problema, observei onde ocorre o erro.

Exemplo, o valor resultante da linha " (dtm_banco.z_formulas.Fields[0].AsFloat + dtm_banco.z_formulas.Fields[2].AsFloat + dtm_banco.z_formulas.Fields[3].AsFloat) / 100 * dtm_banco.z_nfcevendas_itensvl_total.AsFloat; " é 0.105.

vTotTrib  arredonda sozinho (não sei como) para 0.11 (que é o correto), enquanto que o RoundTo arredonda para 0.10. Olhando em http://www.devmedia.com.br/rotinas-de-arredondamento-round-roundto-simpleroundto-setroundmode-e-getroundmode/21114, observei que o RoundTo faz o arredondamento de banqueiro e por isso tem esse comportamento estranho (hora arredonda pra cima, hora arredonda para baixo).

Não sei como o vTotTrib arredonda sozinho certo, mas ao ler o texto do link eu tentei usar o SimpleRoundTo, mas ao contrário do que estava escrito, não fez o arredondamento aritmético que aprendemos na escolha, continuando com 0.10.

Como vocês fazem em suas aplicações para arredondar isso certo? Porque o vTotTrib arredonda certo sem comandos adicionais?

Link para o comentário
Compartilhar em outros sites

  • Membros Pro

Agora aconteceu outra coisa interessante no valor resultante da linha " (dtm_banco.z_formulas.Fields[0].AsFloat + dtm_banco.z_formulas.Fields[2].AsFloat + dtm_banco.z_formulas.Fields[3].AsFloat) / 100 * dtm_banco.z_nfcevendas_itensvl_total.AsFloat; ", exemplo 0.105.

Em outro teste que fiz,   vTotTrib  NÃO MAIS arredondou sozinho para 0.11, dessa vez ficando em 0.10. Que loucura.

Link para o comentário
Compartilhar em outros sites

  • Moderadores

Aqui eu faço como o Antônio citou.

Tenho duas variáveis locais, uma para o item e outra para o total, inicializo as duas antes com 0 (zero).

A cada iteração do item, eu faço o calculo, arredondo ou trunco conforme configuração do cliente, jogo na variável local do item e acrescento também na variável do total, só então eu seto o vTotTrib do item.

Ao final seto o valor total de vTotTrib pegando da variável de totalização.

Equipe ACBr

Régys Borges da Silveira

http://www.regys.com.br

certificacao delphicertificacao delphi
Link para o comentário
Compartilhar em outros sites

  • Membros Pro

Olá a todos,

Agradeço pelas dicas. Fiz como recomendaram e a princípio a nota que estavam dando o problema calculou certo, vou atualizar nos clientes e ver o dia a dia.

Mas me surgiu outra dúvida, conforme informei no início desse tópico, a função SimpleRoundTo não funcionou corretamente em seu objetivo de fazer o arredondamento aritmético, uso o Delphi 7. No seguinte tópico (http://www.projetoacbr.com.br/forum/topic/4964-spedpiscofins-arredondamento/) o EMBarbosa afirma que essa função tem problemas.

Não posso usar o RoundTo para arredondar pois ele efetua o "arredondamento de banqueiro". Estou usando uma função que achei na internet http://gustavohinterholz.blogspot.com.br/2011/11/funcao-de-arredondamento.html

A questão é... Vocês também possuem esses problemas com arredondamento? Que funções vocês usam para esse fim?

Link para o comentário
Compartilhar em outros sites

×
×
  • 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.