Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   problema son StrToFloat (https://www.clubdelphi.com/foros/showthread.php?t=96132)

juggern 24-02-2023 17:53:31

problema son StrToFloat
 
Buenas tardes chicos:

Hace mucho tiempo puse un problema aquí pero al final no conseguí solucionarlo y salté a otra cosa porque era un proyecto pequeño, ahora me vuelve a saltar y ya no se que hacer.

Resulta que tengo un string que es un valor sin coma (155) y otro con coma (110,2), necesito pasarlo a número para poder tratarlos, hago lo siguiente:
Código Delphi [-]
var
 cad1,cad2: string;
 valor1, valor2: double;

 cad1:= '100';
 cad2:= '105,5';

 valor1:= strtofloat(cad1);
 valor2:= strtofloat(cad2);

En realidad los valores string me vienen de datos que cojo de un fichero, os lo pongo así para simplificarlo.
Voy depurando paso por paso y cad1 y cad2 llevan bien el valor, pero al pasarlos a valor1 y valor2, las dos variables double pone 0, no consigo que coja el número.
No arroja ningún error, todo funciona sin errores pero los valores de valor1 y valor2 pone 0.

Estoy usando delphi 10 y ya no se que hacer, no entiendo que pasa, en delphi 7 funciona perfectamente.

He probado con variables extended y las deja a 0 igual, he probado también con variables currency y usar strtocurr pero también lo deja a 0.

Hay alguna otra forma de hacerlo? me estoy volviendo loco, necesito que sean double para calcular cosas con esos datos, iva y cosas así.


Muchas gracias.

pgranados 24-02-2023 18:10:14

Dale una checada a este hilo y mira si te funciona

https://www.clubdelphi.com/foros/showthread.php?t=51740

juggern 24-02-2023 18:28:40

Hola!

No, porque no me da ningún error. El problema tampoco es el separador decimal, porque ya lo trato yo para que sea una ",".

Os dejo más datos, es que es muy raro. Yo ahora cojo ese string y lo guardo en un campo sql que es currency, para ello uso strtocurr y en la base de datos me lo guarda correctamente.
Vuelvo a coger ese dato, esta vez directamente de la base de datos, y lo guardo en la variable, y me guarda un 0! no lo entiendo, he probado combinaciones de variables double, extended y currency y de los métodos .toString y ToCurrency del query y nada, me guarda un 0.
Si muestro un showmessage del campo:
Código Delphi [-]
ShowMessage(Query.FieldByName('Precio').AsString);

me muestra correctamente el dato, con lo que el problema que creo que me está pasando es al meter el valor en la variable que no es string. Porque me pasa al meter valor en la variable desde donde sea.
No lo entiendo, seguro que es una chorrada pero no lo veo.

Añado para que se vea más claro mi problema:
Código Delphi [-]
var
 dPrecio: currency;

  dPrecio:= Query.FieldByName('Precio').AsCurrency;
  ShowMessage(Query.FieldByName('Precio').AsString);

Esto me mete un 0 en dPrecio y me muestra en el showmessage un 102 (que es el valor que hay en la base de datos).

chenech 24-02-2023 18:52:59

Prueba a poner esto en la creación del form principal, igual no es pero yo lo tengo para muiltiidiomas que en inglés usan el punto y en España la coma, si no me daba error cuando no era el correcto, quizás no esté tomando la coma como decimal, prueba también a usar 102.5 en lugar de 105,5 en la prueba. A mi me funciona bien el StrToFloat con los importes, uso Rad Studio 10.4 y Windows 10.
Código:

  FormatSettings.DecimalSeparator = ',';
  FormatSettings.ThousandSeparator = '.';


Casimiro Notevi 24-02-2023 19:07:12

¿El campo en la BD seguro que no es de texto?

juggern 24-02-2023 20:38:10

Hola chicos,

No, ya os digo que el problema no es la coma decimal, es que el valor lo mete a 0. No da ningún error. De hecho, si te fijas en el ejemplo, no lleva decimales en ese caso.

Acabo de revisarlo por si acaso para decírtelo fijo, no siendo que lo hubiera mirado mal y el campo de la base de datos es Money.

Incluso si directamente hago
Código Delphi [-]
Valor1:= 100;

Me mete un 0.

movorack 24-02-2023 21:00:49

¿Podría ser que en tu código exista una función que se llame StrToFloat?

Prueba a usar la función de conversión como "System.SysUtils.StrToFloat"

Código Delphi [-]
function StrToFloat(S: string): Extended;
begin
  Result := 0;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  D: Extended;
begin
  //Acá se usa la función StrToFloat local y devuelve un 0
  D := StrToFloat('100');
  ShowMessage(FloatToStr(D));

  //Acá se usa la función StrToFloat de la VCL y devuelve el valor correcto
  D := System.SysUtils.StrToFloat('100');
  ShowMessage(FloatToStr(D));
end;

Casimiro Notevi 24-02-2023 21:04:05

Creo que te estás confundiendo.
Para empezar, deberías usar una nomenclatura que aclare qué tipo de dato es cada uno, porque var1, valor1, cad1... confunde, cambia el nombre de las variables según su tipo, ejemplos:
Código Delphi [-]
sValor :String;
iValor :Integer;
fValor1, fValor2: Float;

fValor1 := 125,25;
sValor := FloatToStr(fValor1);
fValor2 := StrToFloat(sValor);
De esta manera estarás seguro de lo que estás haciendo.

mamcx 24-02-2023 21:16:56

Lo que estas colocando de `strtofloat` no tiene que ver con el problema que muestras aqui:

Cita:

Empezado por juggern (Mensaje 550565)
Añado para que se vea más claro mi problema:
Código Delphi [-]
var
 dPrecio: currency;

  dPrecio:= Query.FieldByName('Precio').AsCurrency;
  ShowMessage(Query.FieldByName('Precio').AsString);

Esto me mete un 0 en dPrecio y me muestra en el showmessage un 102 (que es el valor que hay en la base de datos).

Floats y Currency son tipos distintos. `AsCurrency` no esta ejecutando `strtofloat`. Como esta definido el campo en la Bd?

juggern 25-02-2023 07:50:27

Buenos días chicos,

Lo de strtofloat y .AsCurrency lo puse porque buscando alternativas, probé también eso y veo que de esa forma me sigue asignando un 0.
Vuelvo a hacerlo con más calma aclarando las variables, quizás como dice Casimiro, al hacerlo rápido no fui muy limpio.

Código Delphi [-]
var
  ePrecio:Extended;
  dPrecio: Double;
  rPrecio: real;
  siPrecio: Single;
  cPrecio: Currency;
  sPrecio: string;

begin
      sPrecio:= '105';
      ePrecio:= StrToFloat(sPrecio);
      dPrecio:= StrToFloat(sPrecio);
      rPrecio:= StrToFloat(sPrecio);
      siPrecio:= StrToFloat(sPrecio);
      cPrecio:= StrToFloat(sPrecio);
      cPrecio:= StrToCurr(sPrecio);
end

Todo eso, me asigna todo el rato un 0 salvo sPrecio, que me guarda un 105;


Para buscar alternativas, he hecho lo de guardar el valor en un campo de una tabla y luego recogerlo de nuevo.
El campo de la tabla es money

Me lo guarda correctamente, y al recuperarlos, me sigue guardando un 0 salvo en la variable string que me lo guarda correctamente:

Código Delphi [-]
      Query.FieldByName('Precio').Value:= StrToCurr(sPrecio);

      Query.Post;
      cPrecio:= Query.FieldByName('Precio').AsCurrency;
      dPrecio:= Query.FieldByName('Precio').AsFloat;
      sPrecio:= Query.FieldByName('Precio').AsString;

He revisado lo que comenta movorack por si acaso y no existe otra función en el programa y al seguirla me lleva correctamente a SysUtils.

Como estoy guardando el valor en las variables de varias formas, tanto usando los métodos de sysutils como los del ADOQuery y con todos me guarda un 0, pues por eso os decía lo de que creía que había algún problema al guardar.

No se, estoy bastante despistado. He usado mas veces en otros sitios estas conversiones y no he tenido problemas salvo la otra vez hace tanto tiempo que os comenté.

He probado a hacer un Clean del proyecto, pero nada.

Edito**: Había insertado imágenes con la watch list desde delphi pero se ve que no me lo ha cogido

juggern 25-02-2023 16:34:17

Hola chicos,

Creo que he dado con la clave, el problema está en el ámbito de las variables o algo de eso.
Cuando hago la asignación a cualquier variable que declaro dentro del procedimiento, me las deja a 0, salvo las de tipo string, pero si declaro una variable global, en esa si que me guarda bien el dato.
El procedimiento lo tengo declarado dentro de la clase del formulario principal, pero he probado a declarar el procedimiento en distintos sitios, incluso global y nada. Solo me asigna bien el valor si lo meto en una variable global.

duilioisola 27-02-2023 09:23:56

Quizás tengas el mismo nombre de variable gobal y de procedimiento y eso te esté confundiendo...
Si utilizas varables globales la recomendación es ponerles un prefijo para no mezclarlas con otras de ámbito más restringido
Por ejemplo "GLB_Precio".

Código Delphi [-]
unit TEST;

var
  Precio : double;

procedure PRUEBA;
var
  Precio : double;
begin
  // Esta variable Precio es la del procedimiento. La global no se modifica.
  Precio := 200;
end;

begin
  Precio := 0;
  Prueba;
  ShowMessage(FloatToStr(Precio);  // <--- Esto imprime 0 porque toma la variable global
end.

juggern 28-02-2023 09:05:30

Hola!!!

Al final lo he solucionado usando variables globales.

Las variables globales siempre les pongo otro prefijo para distinguirlas y no hay otra con ese nombre, igualmente, el valor se lo asigno dentro de la función y la uso dentro de la función, es una variable local y lo que hace es que no me deja asignarle ningún valor, se queda a 0. Me pasa con las tipo numérico no con las string, asique debe ser algo de acceso a memoria o yo que se jeje.

Casimiro Notevi 28-02-2023 10:19:07

Cita:

Empezado por juggern (Mensaje 550607)
Hola!!!
Al final lo he solucionado usando variables globales.
Las variables globales siempre les pongo otro prefijo para distinguirlas y no hay otra con ese nombre, igualmente, el valor se lo asigno dentro de la función y la uso dentro de la función, es una variable local y lo que hace es que no me deja asignarle ningún valor, se queda a 0. Me pasa con las tipo numérico no con las string, asique debe ser algo de acceso a memoria o yo que se jeje.

Las variables globales solamente para cuando no tenga más remedio que usarla. Nunca jamás para resolver un problema. Solamente te va a traer dolores de cabeza después.
Pon tu proyecto, o un ejemplo de tu proyecto, para que le demos un vistazo, así lo solucionamos "de verdad",


La franja horaria es GMT +2. Ahora son las 17:49:18.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi