Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Conexión con bases de datos (https://www.clubdelphi.com/foros/forumdisplay.php?f=2)
-   -   Update un campo sumando existencia (Inventario) (https://www.clubdelphi.com/foros/showthread.php?t=48893)

enecumene 07-10-2007 03:11:03

Update un campo sumando existencia (Inventario)
 
Hola compañeros del foro, aqui vuelvo con un obstaculo que me he topado, he aqui el codigo:

Código Delphi [-]
//suma la existecia del articulo
ZSumaInventario.Close;
ZSumaInventario.SQL.Clear;
ZSumaInventario.SQL.Add('update articulos set cantidad = :inv where ref = :cod');
ZSumaInventario.ParamByName('inv').Value := strtoint(ZInventario.Fields[3].Value) + strtoint(ZTemp.Fields[3].Value);
ZSumaInventario.ParamByName('cod').Value := ZTemp.Fields[1].Value;
ZSumaInventario.ExecSQL;

Objetivo: estoy haciendo un sistema de inventario, estoy haciendo la entrada a traves de un DBGrid enlazado a una tabla temporal, en la tabla articulos hay un campo llamado cantidad, estoy tratando de hacer un update donde me sume la cantidad ingresada en la tabla temporal mas la cantidad en la tabla articulos. ejemplo:

Cita:

Tabla articulo

Articulo -------cabtidad--
toner -------1--

tabla temporal

Articulo -------cantidad--
toner -------5--
con el update que estoy tratando de hacer es que en la tabla articulo se me sume los cincos de la tabla temporal que serian de 1 a 6. no se si me hice entender.

al correr me sale el siguiente error:

Cita:

---------------------------
Debugger Exception Notification
---------------------------
Project Almacen.exe raised exception class EVariantTypeCastError with message 'Could not convert variant of type (Null) into type (String)'. Process stopped. Use Step or Run to continue.
---------------------------
OK Help
---------------------------
que estaria haciendo mal?

Saludos.

Caral 07-10-2007 04:10:35

Hola
Para mi el orden no esta bien, pero bueno, tal vez funcione asi.
Sabemos que ZSumaInventario hace toda la operacion, pero:
Para empezar me gustaria saber:
Cantidad
Inv
Cod
ZInventario, 3
ZTemp, 3
Bueno que tipo de datos contienen cada uno de ellos, me lo puedo imaginar pero me parece mejor preguntarlo.
Se nota que soy ademas de novato, curioso.
Saludos

Delphius 07-10-2007 06:44:07

Hola enecumene,
¿Podrías decirme en que parte del código te arroja el error?

Al parecer dicho error se produce debido a que en tu consulta hay un campo Nulo por lo que al ejecutarse la instrucción SQL falla. Lo que se trató de hacer es convertir Null es un string...

Esto me resulta rarísimo... ¿para que hacer conversiones de strings? ¿No es mejor estar guardandolo directamente como integer?

Saludos,

enecumene 07-10-2007 16:30:00

Cita:

Empezado por Caral (Mensaje 236736)
Hola
Para mi el orden no esta bien, pero bueno, tal vez funcione asi.
Sabemos que ZSumaInventario hace toda la operacion, pero:
Para empezar me gustaria saber:
Cantidad
Inv
Cod
ZInventario, 3
ZTemp, 3
Bueno que tipo de datos contienen cada uno de ellos, me lo puedo imaginar pero me parece mejor preguntarlo.
Se nota que soy ademas de novato, curioso.
Saludos

Inv := la suma de la nueva cantidad mas la ya existente en la base de datos
Cod := el codigo o referencia del articulo donde la cual cumple como condicion.
ZInventario[3] := es el campo cantidad de tipo integer de la tabla Articulos.
ZTemp[3] := es el campo cantidad de tipo integer de la tabla temporal.

Cita:

Empezado por Delphius
Hola enecumene,
¿Podrías decirme en que parte del código te arroja el error?

Al parecer dicho error se produce debido a que en tu consulta hay un campo Nulo por lo que al ejecutarse la instrucción SQL falla. Lo que se trató de hacer es convertir Null es un string...

Esto me resulta rarísimo... ¿para que hacer conversiones de strings? ¿No es mejor estar guardandolo directamente como integer?

Saludos,
el error se produce en esta linea:

Código Delphi [-]
ZSumaInventario.ParamByName('inv').Value := strtoint(ZInventario.Fields[3].Value) + strtoint(ZTemp.Fields[3].Value);

P.D.: se me habia olvidado decir que estoy trabajando con access y delphi7.

Saludos.

enecumene 07-10-2007 19:01:53

uffff!!!!, ya he ultilizado el 100% de mi pequeña cabecita y no he logrado el objetivo:(, pues seguire descansando y tomando mi cervecita:D.

Saludos.

Caral 07-10-2007 19:08:13

Hola
Intenta esta tonteria:
Código Delphi [-]
ZSumaInventario.Close;
ZSumaInventario.SQL.Clear;
ZSumaInventario.SQL.Add('update articulos set cantidad = :inv where ref = :cod');
ZSumaInventario.ParamByName('cod').Value := ZTemp.Fields[1].Value;
ZSumaInventario.ParamByName('inv').Value := strtoint(ZInventario.Fields[3].Value) + strtoint(ZTemp.Fields[3].Value);
ZSumaInventario.ExecSQL;
Saludos

enecumene 07-10-2007 19:31:45

Hola Caral, el mismo error:(.

Saludos.

Caral 07-10-2007 19:42:46

Hola
Me deja mal este error, no logro verlo, si puede poner el programa, me gustaria probarlo.
Saludos

enecumene 07-10-2007 19:44:41

Vale, el programa esta a medias vere como lo posteo, dame unos minutos.

Saludos.

enecumene 07-10-2007 19:52:38

A ver si funciona el link:

Almacen.rar

Saludos.

Caral 07-10-2007 20:02:00

Ya lo tengo, lo voy a revisra
Ya lo comentamos, un minuto

Caral 07-10-2007 20:13:23

Hola
Veamos una prueba, a ver que datos muestra:
Código Delphi [-]
ZSumaInventario.SQL.Add('update articulos set cantidad = :inv where ref = :cod');
ZSumaInventario.ParamByName('cod').Value := ZTemp.Fields[1].Value;
ZSumaInventario.ParamByName('inv').Value := strtoint(ZInventario.Fields[3].Value) + strtoint(ZTemp.Fields[3].Value);
Showmessage(ZSumaInventario.ParamByName('inv').Value);
//ZSumaInventario.ExecSQL;
Si lo puedes hacer con cod, tambien pues mejor.
Saludos

enecumene 07-10-2007 20:17:24

Ni siquiera salio el showmessage:

Cita:

---------------------------
Debugger Exception Notification
---------------------------
Project Almacen.exe raised exception class EVariantTypeCastError with message 'Could not convert variant of type (Null) into type (String)'. Process stopped. Use Step or Run to continue.
---------------------------
OK Help
---------------------------
se detiene en:

Código Delphi [-]
ZSumaInventario.ParamByName('inv').Value := strtoint(ZInventario.Fields[3].Value) + strtoint(ZTemp.Fields[3].Value);

Caral 07-10-2007 20:25:06

Hola
Te pido que hagas esto por que me olvide que no tengo instalado zeos asi que no puedo correrlo.
Intenta esto:
Código Delphi [-]
ZSumaInventario.SQL.Add('update articulos set cantidad = :inv where ref = :cod');
ZSumaInventario.ParamByName('cod').Value := ZTemp.Fields[1].Value;
ZSumaInventario.ParamByName('inv').Value := 1 + 2; 
Showmessage(ZSumaInventario.ParamByName('cod').Value);
//strtoint(ZInventario.Fields[3].Value) + strtoint(ZTemp.Fields[3].Value);
//Showmessage(ZSumaInventario.ParamByName('inv').Value);
//ZSumaInventario.ExecSQL;
Veamos
Saludos

enecumene 07-10-2007 20:30:12

de tres articulos que hay en la tabla me tiro una sola referencia, me imagino que esta bien o deberia aparecer todos?:

Cita:

---------------------------
Almacen
---------------------------
Q2612A
---------------------------
OK
---------------------------
Saludos.

Caral 07-10-2007 20:35:03

Hola
Cambia esta linea, quiero ver que pasa.
Código Delphi [-]
ZSumaInventario.ParamByName('inv').Value := 1;
Saludos

Caral 07-10-2007 20:36:58

Hola
Perdona, tambien pruebalo con 2 en vez de 1.
Saludos

enecumene 07-10-2007 20:40:28

me salio el mismo showmessage del post #15, pero me estoy dando cuenta de algo, dejame hacer un prueba y luego te comento.

Saludos.

enecumene 07-10-2007 20:50:38

Igual el showmessage del post #15 y no tira errores de las dos maneras. y la otra prueba que hice tambien fallo pense que era que habia un append de por medio y como estaba vacio era null, pero que va el mismo error.

Saludos.

Caral 07-10-2007 20:56:21

Hola
Tratemos de entender mas.
Código Delphi [-]
ZSumaInventario.SQL.Add('update articulos set cantidad = :inv where ref = :cod');
ZSumaInventario.ParamByName('cod').Value := ZTemp.Fields[1].Value;
ZSumaInventario.ParamByName('inv').Value := strtoint(ZInventario.Fields[3].Value); 
Showmessage(ZSumaInventario.ParamByName('cod').Value);
Showmessage(ZSumaInventario.ParamByName('inv').Value);
Aqui hay dos mensajes cod e inv, veamos que nos envia
Segun veo deberia enviar esto:
el primer mensaje: Q2612A
el segundo mensaje: 5
Saludos

enecumene 07-10-2007 21:02:22

me los presento los dos sin problemas Q2612A y 5

Caral 07-10-2007 21:13:43

Hola
Estoy perdido, pero me divierto mucho.
Probemos esto:
Código Delphi [-]
ZSumaInventario.SQL.Add('update articulos set cantidad = :inv where ref = :cod');
ZSumaInventario.ParamByName('cod').Value := ZTemp.Fields[1].Value;
ZSumaInventario.ParamByName('inv').Value := IntToStr(strtoint(ZTemp.Fields[3].Value) + strtoint(ZInventario.Fields[3].Value)); 
Showmessage(ZSumaInventario.ParamByName('cod').Value);
Showmessage(ZSumaInventario.ParamByName('inv').Value);

//strtoint(ZInventario.Fields[3].Value) + strtoint(ZTemp.Fields[3].Value);
//Showmessage(ZSumaInventario.ParamByName('inv').Value);
//ZSumaInventario.ExecSQL;
Aqui puede estar el asunto, veamos que pasa.
Deberia:
el primer mensaje: Q2612A
el segundo mensaje: 10
Si se rompe algo no es mi culpa:D
Saludos

basti 07-10-2007 21:23:26

Creo que el problema es con el uso del .value y los parámetros. Value no hace una conversión automática de tipos.

Prueba lo siguiente
Código Delphi [-]
//suma la existecia del articulo
ZSumaInventario.Close;
ZSumaInventario.SQL.Clear;
ZSumaInventario.SQL.Add('update articulos set cantidad = :inv where ref = :cod');
ZSumaInventario.ParamByName('inv').AsInteger := ZInventario.Fields[3].AsInteger + ZTemp.Fields[3].AsInteger;
ZSumaInventario.ParamByName('cod').AsString := ZTemp.Fields[1].AsString;
ZSumaInventario.ExecSQL;

basti 07-10-2007 21:27:37

Añado una cosa, yo prefiero usar FieldByName que Fields. La razón es que si cambias la estructura de la tabla, tendrás que revisar el índice de Fields en todos los sitios. Quedaría algo así:

Código Delphi [-]
//suma la existecia del articulo
ZSumaInventario.Close;
ZSumaInventario.SQL.Clear;
ZSumaInventario.SQL.Add('update articulos set cantidad = :inv where ref = :cod');
ZSumaInventario.ParamByName('inv').AsInteger := ZInventario.FieldByName('Cantidad').AsInteger + ZTemp.FieldByName('Cantidad').AsInteger;
ZSumaInventario.ParamByName('cod').AsString := ZTemp.FieldByName('¿Código?').AsString;
ZSumaInventario.ExecSQL;

Caral 07-10-2007 21:27:55

Hola
Esta es muy buena logica, lo pense tambien, pero no estaba seguro, por eso solicite que se pusieran los mensajes para ver que tipo de datos daba.
Muy bueno basti
Saludos

enecumene 07-10-2007 21:41:26

efectivamente Basti me funciono perfecto, pero ahora tengo otro problema, que solo toma como referencia la primera fila de la tabla temporal que son los detalles que presenta el dbgrid y deberia de hacerlo con todos no? puse dos articulos y solamente me actualiza la primera fila.:confused::confused::confused:.

Saludos.

Caral 07-10-2007 21:49:04

Hola
Ya que me hicieron a un lado:D solo me queda lo ultimo.
Cambia esto a ver:
Código Delphi [-]
ZSumaInventario.ParamByName('cod').AsString := ZInventario.Fields[0].AsInteger
Saludos

enecumene 07-10-2007 22:08:35

Hola Caral, y disculpa, pero no funciono y no hizo nada, no actualiza, solamente con ZTemp lo hace, pero solo lo hace con una sola linea, no hay una forma donde jale todos los registros del ref de ZTemp, porque si tengo dos articulos en la tabla temporal(ZTemp) en el showmessage me deberia salir por ejemplo "Q2612A, C7115A", pero solo me sale por ejemplo "C7115A".

Saludos.

basti 07-10-2007 22:23:35

Cita:

Empezado por enecumene (Mensaje 236812)
efectivamente Basti me funciono perfecto, pero ahora tengo otro problema, que solo toma como referencia la primera fila de la tabla temporal que son los detalles que presenta el dbgrid y deberia de hacerlo con todos no? puse dos articulos y solamente me actualiza la primera fila..

Saludos.

No, la consulta sólo te actualizará el registro que tienes activo en ZTemp.
Tienes que recorrer la tabla ZTemp.
Código Delphi [-]
ZSumaInventario.Close;
ZSumaInventario.SQL.Clear;
ZSumaInventario.SQL.Add('update articulos set cantidad = :inv where ref = :cod');
ZTemp.First;
while not ZTemp.Eof do
begin
  //suma la existecia del articulo
  ZSumaInventario.ParamByName('inv').AsInteger := ZInventario.FieldByName('Cantidad').AsInteger + ZTemp.FieldByName('Cantidad').AsInteger;
  ZSumaInventario.ParamByName('cod').AsString := ZTemp.FieldByName('¿Código?').AsString;
  ZSumaInventario.ExecSQL;
  ZTemp.Next;
end;

enecumene 07-10-2007 22:35:12

Hola, Gracias Basti, Ahora si funciona, va de pelos, y muchas gracias a ti Caral por dedicar tu tiempo en ayudarme, te los agradezco a los dos. ya con esto hago la inversa en el modulo de salida de inventario igual en los ajustes de inventario.

Saludos.


La franja horaria es GMT +2. Ahora son las 12:59:40.

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