We help IT Professionals succeed at work.

Assigning one TCollection to another

gasperz
gasperz asked
on
OK. Here are my objects and down below is code is use.

I'm getting error message while trying to assign one already created object
to another also already created object.They are of course the same type.
I'm trying to create a list of TIzvajalec under TIzvajalci, so if there is
another way (easy of course) let me know, but I would like to make it work my way.


type
  TPesem = class (TCollectionItem)
  private
    fPesem:string;
    fSongExt:TStringList;
  public
    constructor Create(Collection:TCollection);override;
    destructor Destroy;override;
  published
    property Pesem:string read fPesem write fPesem;
    property SongExt:TStringList read fSongExt write fSongExt;
  end;

  TPesmi = class(TCollection)
  private
     function GetItem(Index: Integer): TPesem;
     procedure SetItem(Index: Integer; Value: TPesem);
   public
     function Add:TPesem;
     property Items[Index: Integer]: TPesem read GetItem write SetItem; default;
  end;

  TAlbum = class(TCollectionItem)
  private
    fPesmi:TPesmi;
//    fAlbum:string;
    fSerNum:string;
    fTitle:string;
    fEntryType:string;
    fCategory:string;
    fYear:string;
    fNumTracks:string;
    fOrder:string;
    fNumPlay:string;
    fDiscExt:TStringList;
    fOther:TStringList;
  public
    constructor Create(Collection:TCollection);override;
    destructor Destroy;override;
  published
    property Pesmi:TPesmi read fPesmi write fPesmi;
//    property Album:string read fAlbum write fAlbum;
    property SerNum:string read fSerNum write fSerNum;
    property Title:string read fTitle write fTitle;
    property EntryType:string read fEntryType write fEntryType;
    property Category:string read fCategory write fCategory;
    property Year:string read fYear write fYear;
    property NumTracks:string read fNumTracks write fNumTracks;
    property Order:string read fOrder write fOrder;
    property NumPlay:string read fNumPlay write fNumPlay;
    property DiscExt:TStringList read fDiscExt write fDiscExt;
    property Other:TStringList read fOther write fOther;
  end;

  TAlbums = class(TCollection)
  private
     function GetItem(Index: Integer): TAlbum;
     procedure SetItem(Index: Integer; Value: TAlbum);
  public
    function Add:TAlbum;
    property Items[Index: Integer]: TAlbum read GetItem write SetItem; default;
  end;

  TIzvajalec = class(TCollectionItem)
  private
    fImeIzvajaleca:string;
    fAlbums:TAlbums;
  public
    constructor Create(Collection:TCollection);override;
    destructor Destroy;override;
  published
    property ImeIzvajalca:string read fImeIzvajaleca write fImeIzvajaleca;
    property Albums:TAlbums read fAlbums write fAlbums;
  end;

  TIzvajalci = class(TCollection)
  private
     function GetItem(Index: Integer): TIzvajalec;
     procedure SetItem(Index: Integer; Value: TIzvajalec);
  public
    function Add:TIzvajalec;
    property Items[Index: Integer]: TIzvajalec read GetItem write SetItem; default;
  end;

  TSeznam = class(TComponent)
  private
    fIzvajalci:TIzvajalci;
    CDPlayer:TextFile;
    CDPlayerLista:TStringList;
    procedure NapolniSeznam;
    procedure Dodaj(ListaEnega:TStringList);
    function NapolniEnega(ListaEnega:TStringList):TIzvajalec;
  public
    constructor Create(AOwner:TComponent);override;
    destructor Destroy;override;
    procedure NapolniIzTxt(ImeDat:string);
    function NajdiIzvajalca(Ime:string):integer;
  published
    property Izvajalci:TIzvajalci read fIzvajalci write fIzvajalci;
  end;



function TSeznam.NajdiIzvajalca(Ime:string):integer;
var i,Rez:integer;
begin
  Rez:=-1;
  for i:=0 to Izvajalci.Count-1 do
  begin//preveri ce ta izvajalec za obstaja
    if Izvajalci.Items[i].ImeIzvajalca=Ime then
    begin//izvajalec je enak pod njim dodamo samo album
      Rez:=i;
      break;
    end
  end;
  Result:=Rez;
end;


procedure TSeznam.Dodaj(ListaEnega:TStringList);
var pomIzv,pomIzv1:TIzvajalec;
    pomAlb:TAlbum;
    ind:integer;
begin
  pomIzv:=NapolniEnega(ListaEnega);
//in this function a crate object(pomIzv) with "pomIzv:=TIzvajalec.Create(nil);" and fill all properties
//of this object and objects below

  ind:=NajdiIzvajalca(pomIzv.ImeIzvajalca);
//this returns the position of object with same property ImeIzvajalca

  if ind<>-1 then
  begin//dodamo samo album pod tem izvajalcem
    pomAlb:=Izvajalci.Items[ind].Albums.Add;
    pomAlb.Assign(pomIzv.Albums.Items[0]);
  end
  else
  begin
    pomIzv1:=Izvajalci.Add;

    pomIzv1.Assign(pomIzv);
//here I get error message:
//EConvertError with message 'Cannot assign a TIzvajalec to a TIzvajalec'

  end;
//  ind:=NajdiIzvajalca(pomIzv.ImeIzvajalca);
end;
Comment
Watch Question

Commented:
Hi, in you need to override AssignTo method in your TCollectionItem descendant classes, e.g.:

type
  TIzvajalec = class(TCollectionItem)
  ...
  protected
    procedure AssignTo(Dest: TPersistent); override;
  ...
  end;

procedure TIzvajalec.AssignTo(Dest: TPersistent);
begin
  if Dest is TIzvajalec then
  begin
    TIzvajalec(Dest).fImeIzvajaleca := fImeIzvajaleca;
    TIzvajalec(Dest).fAlbums.Assign(fAlbums);
  end
  else
    inherited; // raise exception
end;

procedure TAlbum.AssignTo(Dest: TPersistent); override;
begin
  if Dest is TAlbum then
  begin
    TAlbum(Dest).fPesmi.Assign(fPesmi);
    TAlbum(Dest).fAlbum := fAlbum;
    TAlbum(Dest).fSerNum := fSerNum;
    TAlbum(Dest).fTitle := fTitle;
    TAlbum(Dest).fEntryType := fEntryType;
    TAlbum(Dest).fCategory := fCategory;
    TAlbum(Dest).fYear := fYear;
    TAlbum(Dest).fNumTracks := fNumTracks;
    TAlbum(Dest).fOrder := fOrder;
    TAlbum(Dest).fNumPlay := fNumPlay;
    TAlbum(Dest).fDiscExt.Assign(fDiscExt);
    TAlbum(Dest).fOther.Assign(fOther);
  end
  else
    inherited; // raise exception
end;

procedure TPesem.AssignTo(Dest: TPersistent);
begin
  if Dest is TPesem then
  begin
    TPesem(Dest).fPesem := fPesem;
    TPesem(Dest).fSongExt.Assign(fSongExt);
  end
  else
    inherited; // raise exception
end;

TCollection.Assign is already implemented (it clears Dest, adds and assigns all items from source), no additional work is needed in your collection classes.
I typed this directly into the browser, sorry if I've made any typos.

HTH
TOndrej

Author

Commented:
Thank you. You answer is really simple and it works for me.

Commented:
Glad to help :-)

Explore More ContentExplore courses, solutions, and other research materials related to this topic.