PDA

Ver la Versión Completa : Error en TObjectList


sleep25000
19-06-2013, 18:41:06
Buenas tardes,

He creado un modulo para una aplicacion, en la que añado imagenes sobre otra que mas o menos hace de un plano.
El nombre de la imagen, la posicion x, la posición y, están almacenadas en una tabla con una relacion maestro-detalle.
A medida que yo me desplazo por cada registro, carga sus correspondiente images, las cuales las almaceno en un TObjectList, para poder eliminarlas, antes de pasar al siguiente registro, elimino las imagenes cargadas de la siguiente manera:

-. Al crear el form
BrandsLst := TObjectList.Create(True);

-. Al pasar el siguiente registro:
// Borrar imagens
for I := Pred(BrandsLst.Count) downto 0 do
BrandsLst.delete(I);

// Crear imagenes
with dsBrands.DataSet do
begin
if NOT(IsEmpty) then
begin
NUM := RecordCount;
while NOT(Eof) do
begin
ID := FieldByName('id').Value;
AName := FieldByName('name').Value;
ALeft := FieldByName('x').Value;
ATop := FieldByName('y').Value;

// Cargar marcas
BrandsLst.Add(CreateBrand(AName, pnlReview, ALeft, ATop, TypeBrand, ID));

// Siguiente Registro
Next;
end;
end;
end;

-. Al cerrar el form
BrandsLst.Free

Si cierro el formulario me genera el siguiente error siempre que borre algun elemento del TObjectList(BrandsLst), si no funciona bien:
raised exception class EArgumentOutOfRangeException with message "Argument out of range"

Pueden ayudarme?

Un saludo.

Casimiro Notevi
19-06-2013, 19:07:59
Bienvenido a clubdelphi, ¿ya leiste nuestra guía de estilo (http://www.clubdelphi.com/foros/guiaestilo.php)?, gracias por tu colaboración :)

Recuerda poner los tags al código fuente, ejemplo:

http://www.clubdelphi.com/images/UtilizarTAGs.png

Gracias :)

Y no olvides poner títulos descriptivos a tus preguntas, gracias :)

ecfisa
19-06-2013, 22:15:58
Hola sleep25000.

Para eliminar los elementos de la lista:
BrandsLst.Clear;

Al finalizar:

...
begin
if Assigned(BrandsLst) then
BrandsLst.Free;
end;

Aunque faltaría ver el procedimiento CreateBrand para descartar otro motivo...

Saludos. :)

sleep25000
21-06-2013, 13:35:27
Gracias por tu respueta, lo he probado y me sigue dando el error, incluso he borrado todos los registros de marcas, me muevo por los registros maestros y cierro el form, y todo bien, pero si vuelvo a entrar en el form me salta un error:

Al cambiar el id, realizo las siguientes operaciones:

procedure TfmHorses.edIDChange(Sender: TObject);
var
DirImage, TypeBrand: String;
Left, Top, ID: Integer;
Img: TImage;

begin
inherited;
BindingExpressions(Sender);

// Archivo
DirImage := dsHorseImages.DataSet.FieldByName('imageName').AsString;
Image.Picture := NIL;
// Obtenemos ficheros y rutas
if RemoveWriteSpace(DirImage) <> '' then
begin
DirImage := iniPathImagesHorses + DirImage;

// Si existe el fichero, cargamos la foto
if fileExists(DirImage) then
Image.Picture.LoadFromFile(DirImage);
end;

// Cargamos Marcas
Load_Brands;
end;



Aquí cargo las marcas:

procedure TfmHorses.Load_Brands;
var
AName, TypeBrand:String;
NUM, ID, ALeft, ATop, I, Index:Integer;

begin

if BrandsLst.Count > 1 then
BrandsLst.Clear;

// Creamos archivo configuracion
with dsHorseBrands.DataSet do
begin
if NOT(IsEmpty) then
begin
NUM := RecordCount;
while NOT(Eof) do
begin
ID := FieldByName('id').Value;
AName := FieldByName('name').Value;
ALeft := FieldByName('x').Value;
ATop := FieldByName('y').Value;
TypeBrand := iniPathImages + IMAGES_BRANDS + FieldByName('type').Value;

// Cargar marcas
BrandsLst.Add(CreateBrand(AName, pnlReview, ALeft, ATop, TypeBrand, ID));

// Siguiente Registro
Next;
end;
end;
end;

y al cerrar el form, hago lo siguiente desde el form que hereda:

//==============================================================================
// PROCEDIMIENTO FORM CLOSE
//==============================================================================
procedure TfmAncestor.FormClose(Sender: TObject; var Action: TCloseAction);
var
I: Integer;
C: TComponent;
//DB: TClientDataSet;

begin

Action := TCloseAction.caFree;

// Comprobamos todos los componentes del formularios, en busca
// de un TDataSource, y cerramos la tabla
for I := 0 to ComponentCount - 1 do
begin
C := Components[I];

// Cerramos dataset y establecemos la consulta inicial
if (C is TDataSource) and (Assigned(TDataSource(C).DataSet)) then
begin
TDataSource(C).DataSet.Close;

if TDataSource(C).Name = 'dsAllRows' then
with TDataSource(C).DataSet as TClientDataSet do
CommandText := SQL;
end;
end;
end;



Acabo de realizar una pruebas, he eliminado la siguiente sentencia del procedimiento Load_Brands, y de esta forma no me da ningún error:

if BrandsLst.Count > 1 then
BrandsLst.Clear;

maeyanes
21-06-2013, 17:02:07
Hola...

La condición debería ser:


if BrandsLst.Count > 0 then
BrandsLst.Clear


Ahora, por tu código, no veo la razón del por que te da el error mencionado. ¿Ya probaste haciendo un seguimiento línea a línea de tú código (Tecla F7)?



Saludos...

sleep25000
22-06-2013, 12:59:44
Hola maeyanes,

He modificado el codigo a:

if BrandsLst.Count > 0 then
BrandsLst.Clear

Tal y como te indique, no tengo ningún registro en la tabla brands, no me muevo por los registros maestros, y cierro el form y todo bien, al abrir otra vez el formulario me da un error en ese mismo fragmento de código.
Yo para liberar el BrandsLst, hago lo siguiente:

procedure TfmHorses.FormClose(Sender: TObject; var Action: TCloseAction);
begin

inherited;

if Assigned(BrandsLst) then
BrandsLst.Free;
end;


Este hereda de:

procedure TfmAncestor.FormClose(Sender: TObject; var Action: TCloseAction);
var
I: Integer;
C: TComponent;
//DB: TClientDataSet;

begin

Action := TCloseAction.caFree;

// Comprobamos todos los componentes del formularios, en busca
// de un TDataSource, y cerramos la tabla
for I := 0 to ComponentCount - 1 do
begin
C := Components[I];

// Cerramos dataset y establecemos la consulta inicial
if (C is TDataSource) and (Assigned(TDataSource(C).DataSet)) then
begin
TDataSource(C).DataSet.Close;

if TDataSource(C).Name = 'dsAllRows' then
with TDataSource(C).DataSet as TClientDataSet do
CommandText := SQL;
end;
end;
end;