PDA

Ver la Versión Completa : could not convert variant of type (null) into type (string)


The Cid James
14-11-2017, 11:01:50
Bueno como me dice el error la variable no puede ser convertida si es null aca les dejo el codigo, estoy tratando de usar un TEdit y convertirlo a integer (que es el valor que la tabla guarda en ese campo)

procedure Tfcantidad.BCokClick(Sender: TObject);
var
a: integer;
begin
a := StrToInt(Ecantidad.Text); // no se supone que aca le estoy dando un valor a la variable :confused:
if (strtoint(Ecantidad.Text)<=0)
then
begin
Application.MessageBox('El valor ingresado debe ser mayor a O', 'Drugstore',mb_yesno+mb_iconquestion);
end
else
a := fmodulo.tVentadetalle ['cantidad'];
fmodulo.tVentadetalle ['id_producto'] := fmodulo.tProductos ['id_producto'];
fmodulo.tVentadetalle['Precio_v'] := ( a * fmodulo.tProductos ['precio_vent']) ;

end;

Soa Pelaez
14-11-2017, 13:50:16
Debes validar antes que el edit no esté vacío, en caso de que lo este lo puedes completar con un 0 o abortar el proceso e informarle al usuario que el edit debe tener un valor.

if Trim(Ecantidad.Text) = '' //
//Opción 1 --> Aqui colocas una validación informando al usuario que el edit está vacío y que debe tener un valor.
//Opción 2 --> Si no le deseas informar al usuario puedes completar el edit con un valor 0

Lo importante es que asegures que antes de asignarlo a la variable entera contenga un valor.

Espero haber ayudado.

movorack
14-11-2017, 15:23:36
Hola,

Debes validar antes que el edit no esté vacío,
Si bien debes hacer la validación que te dice Soa, esta la puedes hacer usando TryStrToInt (http://docwiki.embarcadero.com/Libraries/Tokyo/en/System.SysUtils.TryStrToInt)

Aunque creo que el error está en una de estas asignaciones:


procedure Tfcantidad.BCokClick(Sender: TObject);
begin
//..
a := fmodulo.tVentadetalle ['cantidad'];

fmodulo.tVentadetalle ['id_producto'] := fmodulo.tProductos ['id_producto'];
fmodulo.tVentadetalle['Precio_v'] := ( a * fmodulo.tProductos ['precio_vent']) ;
//..
end;

Verás. Ahí estás intentando obtener un valor variant del dataset por mucho que en la tabla este sea una varchar.

Lo que debes hacer es especificar el tipo de dato para ese campo al momento de usarlo.

Ej:


procedure Tfcantidad.BCokClick(Sender: TObject);
begin
//..
a := fmodulo.tVentadetalle.Fields.FieldByName('cantidad').AsInteger;

fmodulo.tVentadetalle.Fields.FieldByName('id_producto').AsInteger := fmodulo.tProductos .Fields.FieldByName('id_producto').AsInteger;
fmodulo.tVentadetalle.Fields.FieldByName('Precio_v').AsFloat := ( a * fmodulo.tProductos .Fields.FieldByName('precio_vent').AsFloat) ;
//..
end;


Si el campo es nulo, y haces el llamado con un AsString retornará una cadena vacía y si lo llamas con un AsInteger retornará un 0.

Recomendación: Haz este cambio en todo tu sistema. No sabrás cuando a algún usuario se le dé por jugar con los datos y cargar datos nulos donde nunca los esperarías.

AgustinOrtu
14-11-2017, 15:46:58
+1 a todo lo dicho por [movorack]

De todos modos, el codigo que publicaste esta raro y por eso te da problemas.
Primero convertis de string a Integer el contenido del edit, y lo guardas en una variable.
Luego, en lugar de usar esa variable, volves a convertir para la validacion.
Y despues de validar, asignas en la misma variable el valor de un campo de la tabla, osea el valor que asignaste al principio nunca lo usaste. Creo que eso responde al "no se supone que le estoy dando valor?"

roman
14-11-2017, 17:54:19
Otra opción a lo que te comenta movorack es poner la variable global NullStrictConvert a false. Eso hará que el valor NULL de un variant se convierta automáticamente dependiendo del tipo de datos de la variable a la que asignas (numérica: 0, booleana: false, string: cadena vacía).

LineComment Saludos

The Cid James
14-11-2017, 20:55:03
Debes validar antes que el edit no esté vacío, en caso de que lo este lo puedes completar con un 0 o abortar el proceso e informarle al usuario que el edit debe tener un valor.

if Trim(Ecantidad.Text) = '' //
//Opción 1 --> Aqui colocas una validación informando al usuario que el edit está vacío y que debe tener un valor.
//Opción 2 --> Si no le deseas informar al usuario puedes completar el edit con un valor 0

Lo importante es que asegures que antes de asignarlo a la variable entera contenga un valor.

Espero haber ayudado.

Gracia mas que claro todo

Hola,


Si bien debes hacer la validación que te dice Soa, esta la puedes hacer usando TryStrToInt (http://docwiki.embarcadero.com/Libraries/Tokyo/en/System.SysUtils.TryStrToInt)

Aunque creo que el error está en una de estas asignaciones:



Verás. Ahí estás intentando obtener un valor variant del dataset por mucho que en la tabla este sea una varchar.

Lo que debes hacer es especificar el tipo de dato para ese campo al momento de usarlo.

Ej:


procedure Tfcantidad.BCokClick(Sender: TObject);
begin
//..
a := fmodulo.tVentadetalle.Fields.FieldByName('cantidad').AsInteger;

fmodulo.tVentadetalle.Fields.FieldByName('id_producto').AsInteger := fmodulo.tProductos .Fields.FieldByName('id_producto').AsInteger;
fmodulo.tVentadetalle.Fields.FieldByName('Precio_v').AsFloat := ( a * fmodulo.tProductos .Fields.FieldByName('precio_vent').AsFloat) ;
//..
end;



Si el campo es nulo, y haces el llamado con un AsString retornará una cadena vacía y si lo llamas con un AsInteger retornará un 0.

Recomendación: Haz este cambio en todo tu sistema. No sabrás cuando a algún usuario se le dé por jugar con los datos y cargar datos nulos donde nunca los esperarías.
No sabia ese método muchas gracias, de todas formas como ya había tenido un error cargando datos me asegure que los campos necesarios sean "obligatorios" desde la base de datos. Con respecto a las declaraciones de los otros campos, trabajan bien no he tenido nungin problema con ellas y mandan todos los datos que necesito igual voy a leer lo que me pasaste para entenderlo, siempre es bueno entender mas cosas

+1 a todo lo dicho por [movorack]

De todos modos, el codigo que publicaste esta raro y por eso te da problemas.
Primero convertis de string a Integer el contenido del edit, y lo guardas en una variable.
Luego, en lugar de usar esa variable, volves a convertir para la validacion.
Y después de validar, asignas en la misma variable el valor de un campo de la tabla, osea el valor que asignaste al principio nunca lo usaste. Creo que eso responde al "no se supone que le estoy dando valor?"
Eso en realidad iba dentro del else por la hora no se como quedo ahi xD

Otra opción a lo que te comenta movorack es poner la variable global NullStrictConvert a false. Eso hará que el valor NULL de un variant se convierta automáticamente dependiendo del tipo de datos de la variable a la que asignas (numérica: 0, booleana: false, string: cadena vacía).

LineComment Saludos

Gracias a todos por las respuestas ahora me pongo a probar las opciones.
Saludos