Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Error en TObjectList (https://www.clubdelphi.com/foros/showthread.php?t=83447)

sleep25000 19-06-2013 18:41:06

Error en TObjectList
 
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?, gracias por tu colaboración :)

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



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:
Código Delphi [-]
BrandsLst.Clear;

Al finalizar:
Código Delphi [-]
...
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

Error en TObjectList
 
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:
Código Delphi [-]
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:
Código Delphi [-]
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:
Código Delphi [-]
//==============================================================================
// 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:
Código Delphi [-]
if BrandsLst.Count > 1 then
    BrandsLst.Clear;

maeyanes 21-06-2013 17:02:07

Hola...

La condición debería ser:

Código Delphi [-]
  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:
Código Delphi [-]
 
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:
Código Delphi [-]
procedure TfmHorses.FormClose(Sender: TObject; var Action: TCloseAction);
begin

  inherited;

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

Este hereda de:
Código Delphi [-]
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;


La franja horaria es GMT +2. Ahora son las 08:51:17.

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