estou com o seguinte problema, estou desenvolvendo um relatório no iReport, cujo, já fiz o Select para pegar valores, somando de todos os meses, mas acontece que pode vir algum mês sem valor.
E eu tenho que fazer um total de atendimento por Meses (Jan, Fev…), também o total de atendimento por projeto.
Alguem sabe como resolver de maneira mais simples o seguinte problema?
[code]package br.teste;
import java.math.BigDecimal;
public class TesteTime {
public static void main(String[] args) {
BigDecimal v1 = new BigDecimal(10);
BigDecimal v2 = new BigDecimal(20);
BigDecimal v3 = null;
BigDecimal soma = v1.add(v2.add(v3));
System.out.println(soma);
}
}[/code]
Eu estou com uma ídeia aqui, ainda não testei. mas parece ser meio grotesca sair testando tudo antes de soma.
Mas não acho que sejá a mais viavel.
Se alguem souber como resolver esse problema desses bentidos null que possam aparecer, ficarei muito agradecido
Se null é a mesma coisa que zero para você, crie um método que receba um BigDecimal (que pode ser null) e retorne o próprio BigDecimal, se não for null, ou BigDecimal.ZERO, se for null.
Muito bem pensada. o maior problema é que vou ter que usar isso no iReport. Estou pesquisando se no iReport, tem como eu fazer essa soma sem ter que fazer alguma gambiara.
Sei que ele faz. Pois se vc somar de diferentes linha ele traz o resultado correto. Mas eu estou somando o conteúdo dos 12 meses do ano tudo em uma unica linha, até já tentei traz direto do banco a soma.
No MYSQL, ele não reconheceu as colunas com que vem com o nome AS JANEIRO,
Eu coloquei na consulta.
,
(JANEIRO + FEVEREIRO + MARCO…) MAS O MYSQL DIZIA QUE CAMPO DESCONHECIDO.
Tendo em mãos o mesmo problema, criei um método em minha classe utilitária assim:
Obs: Pode-se fazer de maneira semelhante para subtração, multiplicação, divisão… Postarei apenas a adição, mas caso precise das outras, só falar que eu posto com as outras operações.
/**
* Método que soma os BigDecimals passados como parâmetros, tratando os nulos como 0 (Zero).
* @param args
* @return
*/
public static BigDecimal somar( BigDecimal ... args ) {
BigDecimal resultado = BigDecimal.ZERO;
for (int i = 0; i < args.length; i++) {
resultado = resultado.add( args[ i ] == null ? BigDecimal.ZERO : args[ i ] );
}
return resultado;
}
Renan, acho mais seguro criar o bigDecimal passando uma string ao invés de um valor:
fiz um código que aceita Number, ou seja qualquer tipo de número, e mesmo assim mantém a precisão:
[code]public static void main(String[] args) {
BigDecimal resultado = new BigDecimal(10);
System.out.println(somar(resultado,10.8f)); //float
System.out.println(somar(resultado,5.8d)); // double
System.out.println(somar(resultado,5.8d)); // Integer
System.out.println(somar(resultado,0.35)); // float
//System.out.println(new BigDecimal(0.35));
//0.34999999999999997779553950749686919152736663818359375 (quando não se converte em string, o erro do seu código)
}
public static BigDecimal somar(BigDecimal resultado, Number valor) {
Esta falando do parâmetro passado no construtor no exemplo de utilização do método? Se sim, foi só um exemplo mesmo, pois no meu caso eu resgato esses valores diretamente do banco utilizando JPA e só trabalho com BigDecimal mesmo (nao fico convertendo de String pra BigDecimal, Int para BigDecimal e etc…).
Esta falando do parâmetro passado no construtor no exemplo de utilização do método? Se sim, foi só um exemplo mesmo, pois no meu caso eu resgato esses valores diretamente do banco utilizando JPA e só trabalho com BigDecimal mesmo (nao fico convertendo de String pra BigDecimal, Int para BigDecimal e etc…).[/quote]
O resultado foi: 1.34999999999999997779553950749686919152736663818359375
Caso vc queira arredondar o número é só utilizar o método da própria classe BigDecimal, por exemplo:
System.out.println( Utils.somar( vl1, vl2, vl3 ).setScale( 2, BigDecimal.ROUND_HALF_DOWN ) );
Retornando: “1.35”
Passei apenas um int pra exemplificar o uso da função. Mas se o problema é precisão, se construir o BigDecimal a partir de uma string ela será mantida como falado pelo Douglas. Mas não creio que esse seja o caso do tópico cujo o problema é somar 2 ou mais BigDecimals sendo que eles podem estar nulos (como eles foram construidos e seus problemas de precisão seria outro assunto) =D
De qualquer forma, abaixo 1 exemplo onde a precisão seria respeitada:
[code] public static void main( String[] args ) {
BigDecimal vl1 = new BigDecimal( “0.35” );
BigDecimal vl2 = null;
BigDecimal vl3 = new BigDecimal( 1 );
Caso vc queira arredondar o número é só utilizar o método da própria classe BigDecimal, por exemplo:
System.out.println( Utils.somar( vl1, vl2, vl3 ).setScale( 2, BigDecimal.ROUND_HALF_DOWN ) );
Retornando: “1.35”
[/quote]
Mais ainda acho mais correto fazer isso na aplicação, veja, acho que vc está usando um modelView certo?
se não estiver seu problema coemça aí. Com o modelView vc seta os valores sem se preocupar se são nulos ou não, depois de setar todos os valores faz um método que efetua a soma.