[[RESOLVIDO]] Validar double vindo de um excel

15 respostas
R

Fala galera, blz??

sou novo aqui no forum(cadastrado), mas ele já me ajudou bastante…

estou com um pequeno problema:

tenho dados vindos de uma planilha excel (API - JExcel 2.6), alguns desse campos são moedas, porém não podem ser validados direto no excel, pois a planilha não é padrão, qualquer usuário pode criar uma planilha e usar… todo o funcionamento está pronto, o problema é a validação dos doubles.

o usuário tem que poder digitar:
R - $ - . - , - r

e quando pego os dados tenho que validar e converter, pois vem como string, e pra converter tenho que tirar todos os caracteres que não forem numeros e o ponto flutuante, lembrando que o “R” ou o “$” não dependem um do outro(um pode existir sem o outro), além disso eles tbm podem vir no final do numero (é bizarro eu sei… =P )

ex:

R 522,00
$ 5000.00
R$4.870.00
R$3.230,00
7452.00 R$

etc…

vlw pela ajuda…

15 Respostas

renamed

Cara, no seu caso o melhor a usar é expressão regular… o problema é escrevê-la :lol:

drigo.angelo

Para remover o R$: (valor é a string que você pegou do excel)

valor.replaceAll("[R\\$]", "");
drigo.angelo

O usuario vai poder digitar vírgulas no meio do número:?:

Ou você pode ter certeza que se tiver uma vírgula no número ela vai ser separação de parte decimal (e o mesmo valendo para o ponto)?

R

[quote=drigo.angelo]Para remover o R$: (valor é a string que você pegou do excel)

valor.replaceAll("[R\\$]", "");

pode me explicar melhor a parte do "[R\\$]"??

R

drigo.angelo:
O usuario vai poder digitar vírgulas no meio do número:?:

Ou você pode ter certeza que se tiver uma vírgula no número ela vai ser separação de parte decimal (e o mesmo valendo para o ponto)?

esse é o problema…

eu não tenho como ter certeza do que o usuário vai digitar, e nem posso limitar o que ele vai digitar, então pode ter “ponto” e “virgula” no meio do numero…(mto ridiculo, mas não sou eu quem mando… =S )

vlw pela força…

drigo.angelo

Isso é uma Regex

Tudo que está entre “[” e “]” será comparado com cada caractere da string, tipo

String s = "abcde"; s.replaceAll("[abc]", "x"); System.out.println(s); //Retorna xxxde
Entendeu?

O R é só o R mesmo, e o $ é um caractere reservado das regex, por isso deve colocar \ antes :!:

drigo.angelo

Você pode ao menos ter certeza que vão ter exatamente 2 casas decimais?

R

drigo.angelo:
Isso é uma Regex

String s = "abcde"; s.replaceAll("[abc]", "x"); System.out.println(s); //Retorna xxxde

saquei…

mas continua não funcionando… segue meu código…

public ArrayList validate(String data) {
		ArrayList retorno =  new ArrayList();
		
		data.replaceAll("[rR\\$]", ""); 
		
                 // era assim que estava antes
                /*data = data.replace( "r", "" );
		data = data.replace( "r", "" );
		data = data.replace( "R", "" );
		data = data.replace( "$", "" );
		data = data.replace( ".", "" );
		data = data.replace( "%", "" );
		data.trim();
		data = data.replace( ",", "." );*/		
		try {
				Double doubleData = Double.parseDouble(data);
				retorno.add(0, doubleData);
				retorno.add(1, "");

		} catch (NumberFormatException nfe){
			retorno.add(0, null);
			retorno.add(1, data + " não é um número decimal válido.");
		}	
		return retorno;		
	}

ele sempre retorna a mensagem de erro…

R

não, não posso… o usuário pode digitar até um int, tipo: 1000, mas no fim da conversão ele tem que ter no máximo duas casas decimais, mas se o usuário digitar um inteiro, na hora da conversão já vai uma casa decimal…

drigo.angelo

É porque eu não tratei pontos/vírgulas naquela expressão… vou tentar bolar uma aqui que trate os casos mais comuns de números, tipo
1,234,567.89
1.234.567,89
1234567.89
1234567,89
123456789

renamed

Veja:

public class Classe {

	public static void main(String[] args) {
		
		String n1 = "2.300,00";
		String n2 = "2,300.00";
		try {
			NumberFormat.getInstance().parse(n1);
			NumberFormat.getInstance().parse(n2);			
		} catch (ParseException e) {
			e.printStackTrace();
		}
	}
}

Para usar, vc precisa tirar o R$, R ou $.
Ele ignora “.” e “,”. Portanto, “2556.3652.326,12,55.76” não será considerado errado.
Ao menos, vc já tem uma forma de validar, agora precisa achar uma forma de descobrir o que é a parte inteira e a parte de centavos do número (o que não deve ser tão difícil assim)

ok? =]

renamed

OBS: Se vc em C#, vc resolveria seu problema simplesmente com uma linha:

return double.Parse("R$ 23.652.366,21", CultureInfo.InvariantCulture.NumberFormat);
drigo.angelo

Até agora consegui

(\d{1,3}[\.,]){0,1}(\d{3}[.,]){0,}\d{3}([.,]\d{2}){0,1}

Tem que dar alguns ajustes ainda, mas ta quase la :smiley:

drigo.angelo

Regex:
(\d{1,3}[.,]){0,1}(\d{3}[.,]){0,}\d{3}([.,]\d{2}){0,1}

Como o R e o $ não interferem no número a ser gerado, a regex nem os considera xD

Explicando a Regex em 3 partes:

 Parte:

<a>b</a>{0,1}<a>/b</a>{0,}\d{3}([.,]\d{2}){0,1}

Qualquer número com 1 a tres dígitos --> \d{1,3}  seguido por um ponto ou uma vírgula --> [.,] que pode aparecer zero ou 1 vez --> {0,1}

Essa parte representa o início do número, por exemplo 123,456,789.00 / 1,000.00
 Parte:

(\d{1,3}[.,]){0,1}<a>b</a>{0,}[/b]\d{3}([.,]\d{2}){0,1}

Três dígitos, seguidos por ponto ou vírgula --> (\d{3}[.,]) que pode aparecer zero ou mais vezes --> {0,}

3° Parte:
(\d{1,3}[.,]){0,1}(\d{3}[.,]){0,}\d{3}([.,]\d{2}){0,1}
Últimos tres dígitos seguidos por ponto ou vírgula e duas casas decimais

R

Cara,

a ultima regEX funcionou perfeitamente.

muito obrigado…

vlw pela força galera…

Criado 9 de fevereiro de 2011
Ultima resposta 16 de fev. de 2011
Respostas 15
Participantes 3