Ir para conteúdo
  • Cadastre-se

dev botao

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

Recommended Posts

Postado (editado)

Bom Dia!

Há alguns dias me deparei com a seguinte situação, estou tentando imprimir uma NFC-e com o valor da quantidade 0,266. Ao Imprimir o danfe ele mostra 0,27, ou seja ele esta arredondando o valor da quantidade. Porem configurei a quantidade com 3 casas decimais (Como mostra as imagens em anexo). Debugando o código decidi substituir a função FormatQuantidade por um simples FormatFloat passando a mascara e funcionou. Até pensei que eu poderia estar errando na configuração, mas a string que ele passa pro memo antes de imprimir vem com a quantidade 0,266 que seria a correta mas quando visualiza o danfe aparece com 0,27. E quando substitui a função pelo FormatFloat o resultado da string é exatamente o mesmo, porem o danfe vem com a quantidade correta. Agradeço a atenção. 

Obs: O meu Acbr está atualizado.

 

Erro_Arredondamento.jpg

Erro_Arredondamento1.jpg

Erro_Arredondamento2.jpg

Editado por PoliDados Desenvolvimento
Adição de observação.
Postado

Eu usei o ACBrMonitorPLUS pra testar, o parâmetro para indicar a qtde de casas decimais está funcionando corretamente...

vc esta usando o componente diretamente na sua aplicação?

Além do _qCom, tente configurar também esta outra propriedade:

ACBrNFeDANFCeFortes1.CasasDecimais.Formato := tdetInteger;

Att

Ricardo

Postado

Alterei a configuração das casas decimais para Result.DANFE.CasasDecimais.Formato := tdetMascara e assim também não funcionou. Observe nas imagem que no exato momento onde ele vai adicionar no memo ele possui o valor correto. Porem quando o danfe é visualizado o valor vem arredondado.

Postado

Cara,

realmente, eu não prestei muita atenção nas telas e perguntei coisa q já estava ali...

mas notei alguns detalhes, acho que seu fonte do ACBR NÃO está atualizado...

no método "TACBrNFeDANFCeFortesFr.rlbDetItemBeforePrint" está faltando código ali na tua tela...

Na minha cópia aqui tem o tratamento para inserir o infAdProd no meio...

Ainda não dá pra ter certeza se é esse o problema...

E a sugestão que eu dei antes foi para definir a propriedade Formato para tdetInteger.

Att

Ricardo

  • Moderadores
Postado (editado)

@PoliDados Desenvolvimento

Eu vi seu dilema e resolvi testar para ver se realmente tem algum problema na função abaixo:

Citar

function TACBrNFeDANFEClass.FormatQuantidade(dValor: Double; dForcarDecimais: Boolean) : String;
begin
  if (Frac(dValor) > 0) or (dForcarDecimais) then
  begin
    case CasasDecimais.Formato of
      tdetInteger : Result := FormatFloatBr( dValor , format(sDisplayFormat,  [CasasDecimais._qCom, 0]));
      tdetMascara : Result := FormatFloatBr( dValor , CasasDecimais._Mask_qCom);
    else
      Result := FormatFloatBr( dValor , format(sDisplayFormat,  [CasasDecimais._qCom, 0]));
    end
  end
  else
    // caso contrário mostrar somente o número inteiro
    Result := FloatToStr( dValor );
end;

Veja o case na função, ele determina qual atitude a função vai tomar para formatar sua informação.

Aproveitei e inclui no TesteCase que você pode encontrar na pasta "..\Testes\Dunit\ACBrComum\ACBrComumTestCases.dpr".

Nele tem os testes que mostra que a função está certa.

Observe o Teste abaixo : 

Citar

 { FormatFloatBrTest }

  FormatFloatBrTest = class(TTestCase)
  private
  published
   procedure Normal;
   procedure ComDecimaisZerados;
   procedure ComFormatacao;
   procedure ComSerparadorDeMilhar;
   procedure ComMascaraDisplayFormat;
  end;

Essa linha em destaque você não vai encontrar mas vou anexar a unit aqui com o teste que usei os valores que você reporta.

Citar

procedure FormatFloatBrTest.ComMascaraDisplayFormat;
function Mascara(ADec : Integer) : string;
begin
  result :=  format(sDisplayFormat,[ADec,0]);
end;
begin
  CheckEquals('0,27', FormatFloatBr(0.266, Mascara(2)));
  CheckNotEquals('0,26', FormatFloatBr(0.266, Mascara(2)));
  CheckEquals('0,266', FormatFloatBr(0.266, Mascara(3)));
  CheckEquals('0,2660', FormatFloatBr(0.266, Mascara(4)));
  CheckEquals('0,26601', FormatFloatBr(0.26601, Mascara(5)));
end;

Observe ali que se informar 0,266 com duas casas decimais o valor é arredondado para 0,27 conforme você descreve.

Agora se informar o valor com 3 cadas decimais o valor formata corretamente como demostra o teste.

Aproveitei e inclui mais um teste para a função TruncTo e o teste apresentou um bug nela.

Vou anexar aqui também a correção para que possa ser avaliada e se possível incluída no repositório.

Meu conselho, verifica onde você configura as casas decimais no seu código e boa sorte.

 

ACBrUtil.pas

A unit acbrutiltest.pas do teste deve ser salva na pasta "..\Testes\FPCUnit\ACBrComum".

acbrutiltest.pas

Editado por Waldir Paim
Postado

Bom Dia, conforme descrevi acima acredito que o erro não seja configuração pois a string que ele passa para o memo montar a linha do produto esta com o valor de quantidade 0.266 e no pdf gerado o valor é arredondado para 0,27. Pode ser conferido nas imagens em anexo que exatamente onde ele passa a string para o memo o valor esta formatado corretamente. Isso depois da função FormatQuantidade, ou seja o valor retornado pela função esta correto. Porem em um teste eu resolvi mudar a função por um simples FormatFloat, o valor retornado na string era exatamente o mesmo porem no pdf aparecia o valor arredondado.

Postado

Bom dia,

qual a versão do seu Delphi?

Esse caso tá me lembrando do tempo que trabalhava com QuickReport... dependendo do que tu fazia nos "beforeprint", no preview aparecia uma coisa, e no papel saia outra... :-)

Vou dar mais uma sugestão/palpite: tente atualizar (update) a pasta do FORTESREPORT-CE

Att

Ricardo

  • Moderadores
Postado

@PoliDados Desenvolvimento

Você realmente está engano, não trata-se de passar o valor certo e sim de como está parametrizado sua função de arredondamento.

Foque nesse trecho : 

Citar

  case CasasDecimais.Formato of
      tdetInteger : Result := FormatFloatBr( dValor , format(sDisplayFormat,  [CasasDecimais._qCom, 0]));
      tdetMascara : Result := FormatFloatBr( dValor , CasasDecimais._Mask_qCom);
    else
      Result := FormatFloatBr( dValor , format(sDisplayFormat,  [CasasDecimais._qCom, 0]));

Veja que dentro do case {CasasDecimais.Formato} que ele decide qual valor vai retorna na saída dela.

Esse paramentro por padrão define com duas casas decimais e pode estar ai o seu problema, se você não passar 3 casas ele sempre vai te retornar o valor diferente do esperado.

Fiz umas melhorias no teste e vou criar outro tópico para incluir eles nos fontes.

 

  • Moderadores
Postado

Perfeito, isso mostra que a função realmente está correta.

Eliminando essa possibilidade fica até mais fácil de você encontrar a solução.

Boa sorte!, com seus testes.

Postado

@Waldir Paim

Ai que tá, ele tem o valor arredondado até mesmo no momento que ele passa a string para o memo. Onde ja é o fim do debug, e quando o Danfe é visualizado o valor esta arredondado. Até onde eu sabia não poderíamos arredondar um valor já dentro de uma string. Observe os primeiros prints que eu adicionei. Olha o resultado da String que ele esta passando para o componente do memo. Ali ja é o final ele só ta passando o valor pro memo. Porem quando visualiza o valor vem arredondado isso que é estranho. Como falei acima. Substitui por um FormatFloat e funcionou. Sendo que tem o mesmo resultado na string. Observe as Primeiras imagens que eu anexei quando abri o tópico que você irá entender. Observe que estou debugando e ao passar o mouse em cima da string esta com o valor correto. 

OBS: Estou usando o delphi 2010.

Postado

Opa..

mais uma ideia para tentar verificar seu problema: 

tente isolar o trecho de código da impressão, pra tentar identificar se não é alguma configuração que pode estar definida apenas no seu projeto.

crie um novo projeto, coloque apenas estes 4 componentes: 1 TButton, 1 OpenDialog, 1 ACBRNFe e 1 ACBrNFeDANFCeFortes.

e execute apenas este trecho de código no onclick do botão...

(OBS: o OpenDialog é pra selecionar o XML)

 if OpenDialog1.Execute then
  begin
    ACBrNFe1.NotasFiscais.Clear;
    ACBrNFe1.NotasFiscais.LoadFromFile(OpenDialog1.FileName);

    ACBrNFeDANFCeFortes1.ACBrNFe := ACBrNFe1;

    //ACBrNFeDANFCeFortes1.CasasDecimais.Formato := tdetMascara;
    //ACBrNFeDANFCeFortes1.CasasDecimais._Mask_qCom := '###,###,###,##0.000';
    ACBrNFeDANFCeFortes1.CasasDecimais.Formato := tdetInteger;
    ACBrNFeDANFCeFortes1.CasasDecimais._qCom := 4;

    ACBrNFeDANFCeFortes1.MostrarPreview := true;
    ACBrNFeDANFCeFortes1.ImprimirDANFE();
  end;

Att

Ricardo

Postado

Boa tarde @RicardoVoigt e @Waldir Paim , Fiz o pequeno projeto como o Ricardo mencionou e funcionou. Analisei que a diferença esta na função de imprimir. No meu projeto estou usando a função 

FACBrNFe.NotasFiscais.Items.ImprimirPDF;

ai testei usando o metodo do projeto do ricardo 

FACBrNFe.NotasFiscais.LoadFromFile(sXmlCaminhoFormatado);
            TACBrNFeDANFCeFortes(FACBrNFe.DANFE).MostrarPreview := True;
            TACBrNFeDANFCeFortes(FACBrNFe.DANFE).ImprimirDANFEPDF;

Da segunda forma funcionou, parece que o problema esta na função imprimir PDF. Vou fazer mais testes, quando concluídos retorno o status. Muito Obrigado pela atenção.

  • Este tópico foi criado há 3030 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.