Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > OOP
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 17-01-2008
air_erik air_erik is offline
Registrado
 
Registrado: ene 2008
Posts: 6
Poder: 0
air_erik Va por buen camino
Problemas con TList

Hola, resulta q quiero editar los datos de una tabla de base de datos, y bueno quiero hacerlos dinamicamente, cuando creo los TList de TLabels y de TEdit, me muestra todo bien, pero cuando quiero guardar las modificaciones, me saca un error q dice "List index out of bound (0)".
Pero eso no es todo, cuando vuelvo a ejecutar y logra guardar, me guarda valores q imagino quedaron residentes en memoria, q son distintos a los q modifique en los edit creados.

Finalmente cuando cierro el form, quiero destruir las listas y me saca error de acceso o violación.

Este es el codigo:
por favor ayudenme con sugerencias.

Código Delphi [-]
unit ventana_ver_refrigerio;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, DB, DBTables;
type
Twindow_ver_refrigerio = class(TForm)
Label5: TLabel;
sql01: TQuery;
Label1: TLabel;
Label2: TLabel;
Button1: TButton;
Button2: TButton;
Label3: TLabel;
procedure FormShow(Sender: TObject);
procedure crear_listas(lista_etiquetas, lista_ed_cantidades, lista_ed_costos, lista_codigos: TList);
procedure Button2Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
public
{ Public declarations }
end;
var
window_ver_refrigerio: Twindow_ver_refrigerio;
FLabelList2, FeditList, FeditList2, FLabelList: TList;
implementation
{$R *.dfm}
procedure Twindow_ver_refrigerio.FormShow(Sender: TObject);
begin
FLabelList:=TList.Create;
FLabelList2:=TList.Create;
FEditList:=TList.Create;
FEditList2:=TList.Create;
crear_listas(FLabelList, FEditList, FEditList, FLabelList2); // Crea etiquetas y cuadros de edición y los guarda en listas
Button1.Enabled:=TRUE;
end;
procedure Twindow_ver_refrigerio.crear_listas(lista_etiquetas, lista_ed_cantidades, lista_ed_costos, lista_codigos: TList);
var
codigos, etiquetas: TLabel;
edit_cant: TEdit;
edit_costo: TEdit;
i: Integer;
begin
i:=1;
sql01.Close;
sql01.SQL.Clear;
sql01.SQL.Add('SELECT * FROM Insumos;');
sql01.Open;
sql01.First;
While not sql01.Eof do
begin
etiquetas:=TLabel.Create(Self);
etiquetas.Caption:=Format(sql01.FieldByName('detalle').asString, [i]);
etiquetas.Parent:=Self;
etiquetas.Font.Charset:=DEFAULT_CHARSET;
etiquetas.Font.Color:=clWhite;
etiquetas.Font.Height:=-13;
etiquetas.Font.Name:='MS Sans Serif';
etiquetas.Font.Pitch:=fpDefault;
etiquetas.Font.Size:=10;
etiquetas.Font.Style:=[fsBold];
etiquetas.Left:=8;
etiquetas.Top:=50+i*20;
lista_etiquetas.Add(etiquetas);
edit_cant:=TEdit.Create(Self);
edit_cant.Text:=sql01.FieldByName('cantidad_stock').asString;
edit_cant.Parent:=Self;
edit_cant.Left:=310;
edit_cant.Width:=33;
edit_cant.Top:=50+i*20;
lista_ed_cantidades.Add(edit_cant);
edit_costo:=TEdit.Create(Self);
edit_costo.Text:=Format(sql01.FieldByName('costo').asString, [i]);
edit_costo.Parent:=Self;
edit_costo.Left:=235;
edit_costo.Width:=33;
edit_costo.Top:=50+i*20;
lista_ed_costos.Add(edit_costo);
codigos:=TLabel.Create(Self);
codigos.Caption:=Format(sql01.FieldByName('cod_ins').asString, [i]);
codigos.Parent:=Self;
codigos.Visible:=FALSE;
lista_codigos.Add(codigos);
i:=i+1;
sql01.next;
end;
end;
procedure Twindow_ver_refrigerio.Button2Click(Sender: TObject);
begin
window_ver_refrigerio.Close;
FlabelList:=nil;
FLabelList.Free;
FLabelList2:=nil;
FLabelList2.Free;
FEditList:=nil;
FEditList.Free;
FEditList2:=nil;
FEditList2.Free;
FLabelList.Destroy;
FLabelList2.Destroy;
FEditList.Destroy;
FEditList2.Destroy;
end;
procedure Twindow_ver_refrigerio.Button1Click(Sender: TObject); //Boton para guardar las modificaciones realizadas en los cuadros de edición
var
cod_ins: TLabel;
cantidad, costo: TEdit;
i, j, k: Pointer;
ban, h: Integer;
begin
ban:=0;
if Application.MessageBox('Está Seguro que desea Guardar las modificaciones?','Modificación de Refrigerios',1+Mb_IconInformation)=1 then
begin
ShowMessage(IntToStr(FEditList.Count));
for h:=0 to FLabelList.Count-1 do
begin
i:=FLabelList2.First;
j:=FEditList.First;
k:=FEditList2.First;
cod_ins:=FLabelList2.Extract(i);
cantidad:=FEditList.Extract(j);
costo:=FEditList2.Extract(k);
if ((cantidad.Text<>'') and (costo.Text<>'')) then //verificamos q ningun campo de edición esté vacio
begin
sql01.Close;
sql01.SQL.Clear;
sql01.SQL.Add('UPDATE Insumos SET costo='+costo.Text+', cantidad_stock='+cantidad.Text+' WHERE cod_ins='''+cod_ins.Caption+''';');
sql01.ExecSQL;
Button1.Enabled:=FALSE;
end
else
begin
ban:=1;
end;
end;
if ban=1 then ShowMessage('Ningún Campo debe estar vacío, el valor mínimo es CERO');
if ban=0 then ShowMessage('Sus datos fueron guardados con éxito');
end;
end;
procedure Twindow_ver_refrigerio.FormClose(Sender: TObject; var Action: TCloseAction);
begin
FlabelList:=nil;
FLabelList.Free;
FLabelList2:=nil;
FLabelList2.Free;
FEditList:=nil;
FEditList.Free;
FEditList2:=nil;
FEditList2.Free;
FLabelList.Destroy;
FLabelList2.Destroy;
FEditList.Destroy;
FEditList2.Destroy;
end;
end.

Un Saludo Erik

PD: perdon por colocar todo el Unit, pero no quiero q se pierda detalles

Última edición por dec fecha: 18-01-2008 a las 01:58:10.
Responder Con Cita
  #2  
Antiguo 17-01-2008
Avatar de cHackAll
[cHackAll] cHackAll is offline
Baneado?
 
Registrado: oct 2006
Posts: 2.159
Poder: 20
cHackAll Va por buen camino
Bienvenido; en primer lugar nunca dejes de utilizar las etiquetas [ delphi ]
Código Delphi [-]
 begin
  begin
   // el código va acá por ejemplo
  end;
 end;

Tambien sería util que nos digas la linea donde se genera el error.

Inicialmente i j k supuestamente es siempre 0... entonces para que usas h??? bueno... con mas datos podría responder "algo".

Saludos
Responder Con Cita
  #3  
Antiguo 17-01-2008
air_erik air_erik is offline
Registrado
 
Registrado: ene 2008
Posts: 6
Poder: 0
air_erik Va por buen camino
Gracias por la sugerencia.

Bueno i,j,k son punteros q apuntan a primer elemento de cada lista (son 3 listas) y h es un entero q ayuda a recorrer toda la lista e ir guardando en la bd cada item.

En realidad el problema se da cuando presiono el Button1 (con el q guarda los cambios realizados en los valores de edit dinamicos), y el otro problema cuando trato de destruir las LISTAS con el metodo FormClose y el Button2 (Cancelar)
Responder Con Cita
  #4  
Antiguo 18-01-2008
air_erik air_erik is offline
Registrado
 
Registrado: ene 2008
Posts: 6
Poder: 0
air_erik Va por buen camino
Hola de nuevo, perdonenme el hecho de no poder explicarme bien anteriormente, felizmente corregí muchos errores q tenia.

Ahora la unica pregunta q tengo es:
Como se destruyen los TList.

Cuando hice:

Código Delphi [-]
FlabelList:=nil;
FLabelList.Free;
FLabelList2:=nil;
FLabelList2.Free;
FEditList:=nil;
FEditList.Free;
FEditList2:=nil;
FEditList2.Free;

Funciona bien, pero cuando le agrego

Código Delphi [-]
FLabelList.Destroy;
FLabelList2.Destroy;
FEditList.Destroy;
FEditList2.Destroy;

Me sale error de Vil¡olacion de acceso

Gracias nuevamente

Última edición por dec fecha: 18-01-2008 a las 01:59:13.
Responder Con Cita
  #5  
Antiguo 18-01-2008
Avatar de xEsk
[xEsk] xEsk is offline
Miembro Premium
 
Registrado: feb 2006
Posts: 454
Poder: 19
xEsk Va por buen camino
Código Delphi [-]
procedure Twindow_ver_refrigerio.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  FlabelList:=nil;
  FLabelList.Free;
  FLabelList2:=nil;
  FLabelList2.Free;
  FEditList:=nil;
  FEditList.Free;
  FEditList2:=nil;
  FEditList2.Free;
  FLabelList.Destroy;
  FLabelList2.Destroy;
  FEditList.Destroy;
  FEditList2.Destroy;
end;
A mi parecer, no tiene mucho sentido lo que haces aquí:
- Pones a nil antes de hacer Free? Lo normal, seria liberar y después ponerlo a nil, pero para hacer esto, es mejor "FreeAndNil(FlabelList);" por ejemplo.
- El destroy no se usa, hehe... esto te va a provocar un error. De ahí que te explote al cerrar el formulario.

Saludos.
Responder Con Cita
  #6  
Antiguo 27-01-2008
air_erik air_erik is offline
Registrado
 
Registrado: ene 2008
Posts: 6
Poder: 0
air_erik Va por buen camino
xEsk Gracias por la sugerencia, te cuento q en algun lugar lei q primero habia q hacer q el puntero apunte a nil y luego liberarlo, y eso fue lo q hice pero probare la alternativa q me das.

Lo q me gustaria es q me pudieran explicar un poco como funcionan esto de los punteros porq no funciona el destroy, q es lo q hace el free y cual la diferencia entre ambos.

Gracias, Saludos
Responder Con Cita
  #7  
Antiguo 28-01-2008
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 28
Lepe Va por buen camino
.Free -> Primero se asegura que el objeto es distinto de nil (puntero nulo), si es distinto, llama a Destroy
.Destroy -> elimina de memoria el objeto, si es un puntero nulo, dará un access violation.

"FLabelList" es de por sí, un puntero. Si le asignas nil y después llamas a Flabellist.Free no hará nada, pero la memoria que tenía asignada ¡¡se queda ahí reservada!! es lo que se llama, dejar el objeto en el limbo, (la memoria queda asignada pero no puedes acceder a esos elementos para nada).

Si después de todo esto, llamas a FlabelList.destroy, estás ordenando liberar la memoria de un puntero nulo, por eso casca.

Tu amigo te diría al contrario, es decir:
FlabelList.Free;
FlabelList := nil;

Si te lo dijo al revés, se le trastornó la neurona .

Por supuesto, lo más cómodo, como comodon que es nuestro amigo xEsk: FreeAndnil(FlabelList); es lo que uso siempre

saludos
__________________
Si usted entendió mi comentario, contácteme y gustosamente,
se lo volveré a explicar hasta que no lo entienda, Gracias.
Responder Con Cita
  #8  
Antiguo 06-02-2008
air_erik air_erik is offline
Registrado
 
Registrado: ene 2008
Posts: 6
Poder: 0
air_erik Va por buen camino
Gracias Lepe por la aclaración.

te cuento q al principio cuando unicamente hice: FLabelList.Destroy en lugar de hacer el free y mandarlo a nil, igual me genero error de access violation, es por esa razon q no pude usar el Destroy, y no entiendo porq, ya q el puntero no era nulo.

Inicialmente solo era esto, pero sacaba error, la pregunta es porq saca error??, si supuestamente lo unico q hago es destruir el puntero.
procedure Twindow_ver_refrigerio.FormClose(Sender: TObject; var Action: TCloseAction);begin FLabelList.Destroy; FLabelList2.Destroy; FEditList.Destroy; FEditList2.Destroy;end;saludos
Responder Con Cita
  #9  
Antiguo 06-02-2008
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 28
Lepe Va por buen camino
La ayuda lo dice bien claro:
Cita:
Do not call Destroy directly. Instead, call Free
Tienes código repetido ahora mismo, en el Button2Click y en el OnClose.

Cuando ordenas cerrar la ventana con .Close, se ejecuta el evento Twindow_refrigerio.FormClose que libera las listas, después se sigue ejecutando el Button2Click que también libera las listas de nuevo, es por ahí que da el error.

Supongo que antes tendrías otros errores de diseño, de ahí que te aparecieran errores.

Saludos
__________________
Si usted entendió mi comentario, contácteme y gustosamente,
se lo volveré a explicar hasta que no lo entienda, Gracias.
Responder Con Cita
  #10  
Antiguo 09-02-2008
air_erik air_erik is offline
Registrado
 
Registrado: ene 2008
Posts: 6
Poder: 0
air_erik Va por buen camino
Mi estimado Lepe, gracias por toda la información brindada.

Bueno sobre el error q mencionas, si me percate de ello y lo corregi tiempito atras, y simplemente me quedaban las dudas conceptuales q me las aclarastes.

Muy Agradecido a todos del foro me despido.

Saludos
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
ordenar un TList elcigarra OOP 27 24-01-2009 00:22:34
TList Delphi rose Varios 4 08-05-2006 16:58:30
Uso del Objeto TList aromero OOP 10 21-10-2005 17:30:11
Problemas con TList arantzal .NET 2 09-12-2004 09:14:37
TList HERNAN Varios 2 10-10-2003 03:47:59


La franja horaria es GMT +2. Ahora son las 17:50:32.


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
Copyright 1996-2007 Club Delphi