PDA

Ver la Versión Completa : Saber si es un numero


Nomad
06-07-2007, 23:32:43
Como hace uno para saber si lo que estoy leyendo de un dbstringgrid es un numero o una letra?

Gracias

jhonny
06-07-2007, 23:46:30
La verdad es que no conozco el TDBStringGrid, pero Con un TEdit se puede hacer asi:

var
N :Integer;
begin
N := StrToIntDef(Edit1.Text, -1);
if N = -1 then
ShowMessage('Letra')
else
ShowMessage('Numero');
end;
Si adecuas este ejemplo a lo que necesitas seguramente te sera útil. ;)

eduarcol
06-07-2007, 23:54:10
No tengo delphi a mano ahorita pero tambien esta la funcion IsNumeric que devuelve true si es un numero


if IsNumeric(StringGrid1.Cells[x,y]) then

jhonny
06-07-2007, 23:59:13
No se si me equivoco, pero tengo entendido que IsNumeric solo recibe como parámetro un Char, de manera que solo servirá para comprobar los números del 0 al 9.

eduarcol
07-07-2007, 00:09:11
Por eso decia que no tenia delphi a mano de hecho lo escribi de memoria, es mas despues que postee me puse a pensar si no sera de otro lenguaje :confused:

jhonny
07-07-2007, 00:24:11
Pero siempre podremos hacer nuestra función personalizada :D.

function TForm1.EsNumero(Numero: String): Boolean;
var
i :Integer;
begin
i := 0;
Result := True;
while ((i <= Length(Numero)-1) and (Result = True)) do
begin
inc(i);
Result := IsNumeric(Numero[i]);
end;
end;

Para usarla es:
if EsNumero(StringGrid1.Cells[x,y]) then
begin
ShowMessage('Es Numerico¡');
end
else
begin
ShowMessage('Es Alfanumerico¡');
end;


Nota: IsNumeric pertenece a la unidad IdGlobal.Pas

jhonny
07-07-2007, 00:32:30
Un pequeño ajuste a esa función ya que si le envían '' me diría que es Numérico y si envían un numero negativo diría que es alfanumerico:

function TForm1.EsNumero(Numero: String): Boolean;
var
i :Integer;
begin
i := 0;
Result := (Length(Numero)<>0);
while ((i <= Length(Numero)-1) and (Result = True)) do
begin
inc(i);
Result := (IsNumeric(Numero[i]) or (Numero[i]='-'));
end;
end;


Seguro que esa función debe tener errores aun, pues no tiene en cuenta los flotantes o si le envian algo como -1222-566 tambien presentaria problemas, pero alli se las dejo por si alguien quiere refinarla.

eduarcol
07-07-2007, 00:33:31
Buena esa jhonny :)

yo añadiria


function TForm1.EsNumero(Numero: String): Boolean;
var
i :Integer;
begin
i := 0;
Result := (Length(Numero)<>0);
while ((i <= Length(Numero)-1) and (Result = True)) do
begin
inc(i);
Result := (IsNumeric(Numero[i]) or (Numero[i]='-') or (Numero[i]=DecimalSeparator) );
end;
end;

eduarcol
07-07-2007, 18:26:37
No la he probado pero esto deberia funcionar


function TTexto.EsNumero(cValor: String): Boolean
var
i :Integer;
nSigno, nSeparador: Integer; //nSigno cuenta la cantidad de signos escritas debe ser solo uno nSimbolo la cantidad de simbolo decimal
begin
i := 0;
Result := (Length(cValor)>0);
while ((i <= Length(cValor)-1) and (Result = True)) do
begin
inc(i);
Result := (IsNumeric(cValor[i]) or ((cValor[i]='-') and (nSigno = 0)) or ((cValor[i]=DecimalSeparator) and (nSeparador = 0));
//Determina si se escribio para incrementar el contador
if (cValor[i]='-') then
Inc(nSigno);
if (cValor[i]=DecimalSeparator) then
Inc(nSeparador);
end;
end;

jhonny
07-07-2007, 18:36:55
:D, Bueno, pero entonces el problema ahora sería porque el siguiente tampoco es un numero y dicha función dirá que si:

9999-

Este tipo de cosas son realmente curiosas :D.

jhonny
07-07-2007, 18:41:50
Ahora el siguiente tendría problema también:

999-999

Caracoles, cada vez le encuentro mas problemas, creo que tendré que ponerme a buscar soluciones :).

eduarcol
07-07-2007, 18:48:41
Caracoles, cada vez le encuentro mas problemas, creo que tendré que ponerme a buscar soluciones :).

jajaja pues bienvenida sea la ayuda, pero creo que la solucion es facil


function TTexto.EsNumero(cValor: String): Boolean
var
i :Integer;
nSigno, nSeparador: Integer; //nSigno cuenta la cantidad de signos escritas debe ser solo uno nSimbolo la cantidad de simbolo decimal
begin
i := 0;
Result := (Length(cValor)>0);
while ((i <= Length(cValor)-1) and (Result = True)) do
begin
inc(i);
Result := (IsNumeric(cValor[i]) or ((cValor[i]='-') and (nSigno = 0) and (i = 1)) or ((cValor[i]=DecimalSeparator) and (nSeparador = 0));
//Determina si se escribio para incrementar el contador
if (cValor[i]='-') then
Inc(nSigno);
if (cValor[i]=DecimalSeparator) then
Inc(nSeparador);
end;
end;


Ahora solo falta saber si le sirvio la respuesta a nomad para pasarle la factura jejeje

jhonny
07-07-2007, 19:00:35
Jejeje, no he probado tu solución aun pero me imagino que con el siguiente dirá que es numero

9999. //Nunca he visto un numero con ese punto al final :D

jhonny
07-07-2007, 19:07:15
Que tal asi?, la probé y funciono, con las condiciones que hemos nombrado hasta aquí:

var
i :Integer;
nSigno, nSeparador: Integer; //nSigno cuenta la cantidad de signos escritas debe ser solo uno nSimbolo la cantidad de simbolo decimal
begin
i := 0;
nSigno := 0;
nSeparador := 0;
Result := (Length(cValor)>0);
while ((i <= Length(cValor)-1) and (Result = True)) do
begin
inc(i);
Result := (IsNumeric(cValor[i]) or ((cValor[i]='-') and (nSigno = 0) and (i = 1)) or ((cValor[i]=DecimalSeparator) and (nSeparador = 0) and (i <> Length(cValor))));
//Determina si se escribio para incrementar el contador
if (cValor[i]='-') then
Inc(nSigno);
if (cValor[i]=DecimalSeparator) then
Inc(nSeparador);
end;

jhonny
07-07-2007, 19:09:52
Ahora solo falta saber si le sirvio la respuesta a nomad para pasarle la factura jejeje

Jejeje, Cierto¡¡¡, Ojala le sirva una de tantas cosas que hemos dicho aquí :).

eduarcol
07-07-2007, 19:14:14
Aja mas problemas a ver a ver

jhonny
07-07-2007, 19:24:37
Aja mas problemas a ver a ver

Solo una cosa, ¿El siguiente debería considerarse como numero? (Omitiendo las comillas),
"999 " (Con espacio al final, por ejemplo).
Esa función dirá que es alfanumérico. Pero la siguiente no.


function TTexto.EsNumero(cValor: String): Boolean;
var
i :Integer;
nSigno, nSeparador: Integer; //nSigno cuenta la cantidad de signos escritas debe ser solo uno nSimbolo la cantidad de simbolo decimal
begin
cValor := Trim(cValor);
i := 0;
nSigno := 0;
nSeparador := 0;
Result := (Length(cValor)>0);
while ((i <= Length(cValor)-1) and (Result = True)) do
begin
inc(i);
Result := (IsNumeric(cValor[i]) or ((cValor[i]='-') and (nSigno = 0) and (i = 1)) or ((cValor[i]=DecimalSeparator) and (nSeparador = 0) and (i <> Length(cValor))));
//Determina si se escribio para incrementar el contador
if (cValor[i]='-') then
Inc(nSigno);
if (cValor[i]=DecimalSeparator) then
Inc(nSeparador);
end;
end;

eduarcol
07-07-2007, 20:01:53
Ok jhonny hoy tengo el cerebro en off por mas qe trato le busco problemas y no se me ocurre ni uno jejeje

creo que me gusta mas pensar en soluciones que en problemas

jhonny
07-07-2007, 20:08:27
Ok jhonny hoy tengo el cerebro en off por mas qe trato le busco problemas y no se me ocurre ni uno jejeje

creo que me gusta mas pensar en soluciones que en problemas

Bueno, la naturaleza humana es la que hace que seamos optimistas en estos casos ;). Seguramente si no tuvieramos esa actitud nunca hubiéramos inventado algo. :D

gabrielkc
07-07-2007, 20:22:35
function EsNumero(cValue: string):Boolean;
var i,Estado:Byte;
begin
if Length(cValue)>0 then
Estado:=1
else
Estado:=0;
i:=1;
while (i<=Length(cValue))and(Estado<>0) do
begin
case Estado of
1:case cValue[i] of
'0'..'9':Estado:=2;
'-':Estado:=3;
else Estado:=0;
end;
2:case cValue[i] of
'0'..'9':Estado:=2;
'.':Estado:=4;
'-':Estado:=0;
else Estado:=0;
end;
3:case cValue[i] of
'0'..'9':Estado:=2;
else Estado:=0;
end;
4:case cValue[i] of
'0'..'9':Estado:=5;
else Estado:=0;
end;
5:case cValue[i] of
'0'..'9':Estado:=5;
else Estado:=0;
end;
end;
Inc(i)
end;
Result:=(Estado in [2,5])
end;


Con un Autómata


procedure TForm1.Button1Click(Sender: TObject);
begin
if EsNumero(edit1.Text) then
ShowMessage('si')
else
ShowMessage('no')
end;


Así se llamaría, si no me equivoco...... funciona en todos los casos.

egostar
07-07-2007, 20:46:47
He estado observando todos los post, pero me parece que nos estamos liando.

Según lo que comenta incialmente Nomad


Como hace uno para saber si lo que estoy leyendo de un dbstringgrid es un numero o una letra?


Esto sugiere (desde mi mente cochambrosa:D) que quiere saber el contenido de todo el DBStringGrid, no caracter por caracter, aunque puede ser que solo sea un caracter y no una cadena, o si, no se, seria cosa de que apareciera y nos diera mas información. :rolleyes:

Creo que la respuesta debería ser mas simple.

Aqui les dejo el código, probado con las diferentes posibilidades.


{
Posibilidades.

1) StringGrid1.Cells[1,1] := '-123456-754333';
2) StringGrid1.Cells[1,1] := '-123456754333';
3) StringGrid1.Cells[1,1] := '123456754333';
4) StringGrid1.Cells[1,1] := 'A1B2C3d4C5';
}

Try
StrtoFloat(StringGrid1.Cells[1,1])
except
ShowMessage('No es número');
end;



Salud OS.

eduarcol
07-07-2007, 20:57:25
No se si son manias o es que lo lei pero el asunto es que no me gusta crear excepciones que pueden ser evitadas.

jejej ademas si no nos hubieramos liado asi luego en que entretenernos

egostar
07-07-2007, 21:03:51
No se si son manias o es que lo lei pero el asunto es que no me gusta crear excepciones que pueden ser evitadas.

jejej ademas si no nos hubieramos liado asi luego en que entretenernos

:D:D:D, pues si es bonito hacer trabajar la mente torcida, sin embargo, hay que evaluar los costos de evitar una excepción.

En fin, cada perro tiene su método para matar pulgas.:D:D

Salud OS.

jhonny
07-07-2007, 21:21:01
Hay diosssss, a veces me parece que debí dejar todo en el primer post que escribí (Que por cierto es muy parecido al codigo que acaba de escribir egostar). :D, pero otra veces me doy cuenta de que me he divertido con este hilo :p .

Delphius
07-07-2007, 21:30:32
He estado siguiendo a este hilo y la verdad es que como que le dieron demasiada rosca al asunto:D.


No se si son manias o es que lo lei pero el asunto es que no me gusta crear excepciones que pueden ser evitadas.

Es cierto, si se puede evitar el asunto de las excepciones. Conviene.

Ahora, para encabronar, y seguir dandole rosca... ¿alguno no pensó el emplear la antigua función val()?

Con esto simplemente podríamos hacer algo así (que también es rebuscado ya que por esas dos líneas directamente conviene meterle un IF) :

function EsNumero(Numero: string): boolean;
var
Chequeo, Num: integer;
begin
val(Numero, Num, Chequeo);
result := (Chequeo = 0);
end;

Saludos,

jhonny
07-07-2007, 21:36:16
Delphius, Pues efectivamente dice que 13.5 es Alfanumérico :( :D

eduarcol
07-07-2007, 21:42:34
He estado observando todos los post, pero me parece que nos estamos liando.

He estado siguiendo a este hilo y la verdad es que como que le dieron demasiada rosca al asunto.


Sinceramente es pasion por ver sufrir al projimo :P


Ok val sirve para los enteros, ¿¿y los reales?? que son los que le dieron vuelta al asunto

jhonny
07-07-2007, 21:46:23
Sinceramente es pasion por ver sufrir al projimo :P


Estoy de acuerdo contigo eduarcol, ¡¡¡ Que cosita ola!!! :D:D:D

Delphius
07-07-2007, 21:53:26
Ok val sirve para los enteros, ¿¿y los reales??

¿Estas completamente seguro?
Fui a la ayuda y me di con esto:

Val converts the string value S to its numeric representation, as if it were read from a text file with Read.
S is a string-type expression; it must be a sequence of characters that form a signed real number.
V is an integer-type or real-type variable.

Para que funcione volví a la función y la alteré por esta:

function EsNumero(Numero: string): boolean;
var
Chequeo: integer;
Num: real;
begin
val(Numero, Num, Chequeo);
result := (Chequeo = 0);
end;

Saludos,

eduarcol
07-07-2007, 21:55:22
Upps :o que de cosas, yo lei lo mismo pero no se en que estaba pensando y en vez de real lo modifique por double, bueno es sabado las 4 de la tarde y en lo noche me toca viajar debe ser eso que me tiene la cabeza en otra parte

jhonny
07-07-2007, 22:03:02
Ya decia yo que alguien iba a venir he íbamos a tener que tirar todo a la basura :D, el único "problema" que veo es que parece que obliga a que se use como Separador decimal el Punto(.), de manera pues que si alguien esta acostumbrado a usar la coma (,) tendrá que cambiar de costumbres, ahh y volvió otro problema que ya habíamos evaluado, que el 999. (Con ese punto al final) no es valido :).

Jejeje, parece que estuviéramos volviendo a lo mismo :D.

jhonny
07-07-2007, 22:09:43
Bueno, fue muy divertido este asunto y gracias a Delphius por fin se pudo sacar una función muy bonita, asi pues que propongo finalmente este otro ajustecito y listo :D...


function EsNumero(Numero: string): boolean;
var
Chequeo: integer;
Num: real;
begin
Numero := Trim(Numero);
val(Numero, Num, Chequeo);
result := ((Chequeo = 0) and (Numero[Length(Numero)]<> '.'));
end;

egostar
07-07-2007, 22:10:42
Ya decia yo que alguien iba a venir he íbamos a tener que tirar todo a la basura :D, el único "problema" que veo es que parece que obliga a que se use como Separador decimal el Punto(.), de manera pues que si alguien esta acostumbrado a usar la coma (,) tendrá que cambiar de costumbres, ahh y volvió otro problema que ya habíamos evaluado, que el 999. (Con ese punto al final) no es valido :).

Jejeje, parece que estuviéramos volviendo a lo mismo :D.


:D:D, Si prueban con mi código, ya tiene contemplado los números que mencionas amigo jhonny.

Lo de las comas, :rolleyes:, se resuelve con la funcion:


StringReplace(NombreCampo,',','',[rfReplaceAll]);


:D:D

Salud OS.

jhonny
07-07-2007, 22:20:28
:D:D, Si prueban con mi código, ya tiene contemplado los números que mencionas amigo jhonny.

Lo de las comas, :rolleyes:, se resuelve con la funcion:



StringReplace(NombreCampo,',','',[rfReplaceAll]);

:D:D



Salud OS.

Jejeje, definitivamente esto si esta muy divertido, en ultimas todos tenemos algo de razón, tu dices que hay que cerciorarse de los costos vs access violations y tales y que pascuales y ya somos 4 invirtiéndole a esta solución :D, mientras que cierto personaje debe estar en casa con pantaloneta, tirado en su sillón viendo alguna buena pelicula de sábado con su familia :D.

Mi función en ese caso es:


StringReplace(DondeDeboEstar,'Oficina','Hogar',[rfReplaceAll]);


:D :D :D

eduarcol
07-07-2007, 22:38:28
Jajajajajajaja pues si definitivamente el amigo jhonny tiene una obsesion secreta con el 999. que realmente si es un numero, valdria decir

999 = 999. = 999.0

Pues yo ya llegue de la oficina a la casa pero no se preocupen aqui tengo tambien una oficina y hecha por mis propias manos vamos que hasta presentable me ha quedado, aunque sigo esperando que no se caiga, y el arquitecto y que si bases que si pilares que si cabilla, nah cemento y bloque jejeje

Delphius
08-07-2007, 00:57:28
Pues me he quedado un poco "picado", y se me ocurrió lo siguiente:

function Tform1.EsNumero(Numero: string; SepDecimal: char = '.'): boolean;
// Esta función ha sido diseñada para seguir dando rosca al asunto
// Espero que le sea de su agradado
const
PUNTO = '.';
var
Chequeo: integer;
Num: real;
begin
Numero := Trim(Numero);
// Si usa otro separador... lo sustiuimos por el punto para
// que se pueda transformar...
// quien sabe, en una de esas puede existir algún planeta
// en donde el separador sea el @
if SepDecimal <> PUNTO
then Numero := StringReplace(Numero,SepDecimal,PUNTO,[rfReplaceAll]);
val(Numero, Num, Chequeo);
result := ((Chequeo = 0) and (Numero[Length(Numero)]<> '.'));
end;

// Ejemplo de uso
procedure TForm1.Button1Click(Sender: TObject);
begin
if EsNumero('999,75',',')
then ShowMessage('Es un número')
else ShowMessage('En este planeta eso no es un número');
end;

Saludos,

eduarcol
08-07-2007, 01:01:38
Pues me he quedado un poco "picado",

JEJEJE entonces ya estas entendiendo de que venia el hilo

muy buena tu funcion mañana la pruebo y veo que tal, por los momentos que pasaria con 999,999.99

o el dilema de jhonny de 99.

courtois
08-07-2007, 07:58:59
por que no pruebas con las funciones TryStrToInt o TryStrToFloat? ambas devuelven true si es posible convertir str en un numero entero o flotante

jhonny
09-07-2007, 14:57:49
por que no pruebas con las funciones TryStrToInt o TryStrToFloat? ambas devuelven true si es posible convertir str en un numero entero o flotante

No les decia yo?

Parece que todo quedo reducido en esa función, incluso tiene en cuenta el 999. :D


var
Numero :Extended;
begin
if TryStrToFloat(Edit1.Text, Numero) then
ShowMessage('Numero¡¡¡')
else
ShowMessage('AlfaNumero¡¡¡');
end;


Lo que me produce un "no se que" que no se describir, es que en http://www.clubdelphi.com/foros/showthread.php?p=71772#post71772 ya había algo :D. Que curioso...

¡¡¡Buena esa courtois!!!

egostar
09-07-2007, 17:20:35
Pues el compañero nomad ya tiene opciones para decidir, pero, a todo esto, donde estará que no ha dicho ni pio.

Bajo estas circunstancias me viene a la mente esto que escribió nuestro amigo jhonny....


...definitivamente esto si esta muy divertido, en ultimas todos tenemos algo de razón, tu dices que hay que cerciorarse de los costos vs access violations y tales y que pascuales y ya somos 4 invirtiéndole a esta solución :D, mientras que cierto personaje debe estar en casa con pantaloneta, tirado en su sillón viendo alguna buena pelicula de sábado con su familia :D.


:D:D:D

Salud OS.