TTable copy (assign ?)

Hi all,

I have a component that is very similar to a TTable, and the problem I need to solve occurs in TTable too, so I´ll use TTable in my example:

I need to make a "copy" of a TTable instance, so I can change some properties and then "restore" the original condition. I tried this code:

   Table2.Assign(Table1);
   ... Changes
   Table1.Assign(Table2);

But I got a message Can not assign a TTable to a TTable.

Why ? Any workaround ?

TIA,
Itamar
LVL 4
itamarAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

hubdogCommented:
because ttable does not override the virtual assign method of tpersistent.
ttable.assign method no use.
you must write  a new component and override the assign method of tpersistent by yourself.

good luck

hubdog
0
hubdogCommented:
you can look the source of tpersistent.assign.it is very simple .then you will see it.

good luck

hubdog
0
itamarAuthor Commented:
Well,

i think there is no other way but write all the code to assign every property of my component with the source values...

I think that should be a clever way to copy two instances of the same object, perhaps using streams... WriteComponent...

still listening...

Thanks,
Itamar
0
Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

brunoheCommented:
This is a serious problem. There is no other way to copy property values than using you own derived class from TTable and overwrite Assign method.

Anything else would be a hack.
0
itamarAuthor Commented:
Well,

i think there is no other way but write all the code to assign every property of my component with the source values...

I think that should be a clever way to copy two instances of the same object, perhaps using streams... WriteComponent...

still listening...

Thanks,
Itamar
0
hubdogCommented:
as you have said , maybe you can use stream to copy a table
procedure TForm1.Button1Click(Sender: TObject);
var
  b:tmemorystream;
  a:Ttable;
begin
  b:=TmemoryStream.Create;
  b.WriteComponent(table1);
  b.Position:=0;
  RegisterClass(TTable);
  TComponent(a) := b.ReadComponent(nil);
  showmessage(a.name);
  b.free;
end;

good luck

hubdog
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
itamarAuthor Commented:
Hi hubdog,

i think this is a good way. But I tried:

procedure TTable.Assign(Source: TPersistent);
var
   MStream: TMemoryStream;
begin
   if Source is TTable then begin
   MStream := TMemoryStream.Create;
   MStream.WriteComponent(TComponent(Source));
   MStream.Position := 0;
   RegisterClass(TTable);
   TComponent(Self) := MStream.ReadComponent(nil);
   MStream.Free;
   end
   else
      inherited Assign(Source);
end;

There is no compiler or run-time error, but in the code below I can´t restore the original property value:

procedure TForm1.Button1Click(Sender: TObject);
var
   Copy: TTable;
begin
   Table1.Filter := 'X=0';
   Copy := TTable.Create(Self);
   Copy.Assign(Table1); // Save
   ShowMessage('Old filter: ' + Copy.Filter);
   Table1.Filter := 'dummy';
   ShowMessage('Table1.Filter = ' + Table1.Filter);
   Table1.Assign(Copy); // Restore
   ShowMessage('Table1.Filter = ' + Table1.Filter); //Should be 'X=0'
end;

Any ideas ???
0
hubdogCommented:
here is my program ,it is ok
procedure TForm1.Button1Click(Sender: TObject);
var
  b:tmemorystream;
begin
  table1.filter:='x=0';
  b:=TmemoryStream.Create;
  b.WriteComponent(table1);
  b.Position:=0;
  RegisterClass(TTable);
  TComponent(table2) := b.ReadComponent(nil);
  showmessage(table2.filter);//it do show x=0
  b.free;
end;
I do not know where you write your assign method.Do you change the vcl-source or write in your own program? maybe that is the problem.
I think you should paste more source

good luck

hubdog
0
itamarAuthor Commented:

You´re right ! Your code works, but I have decided to go further and use TMemoryStream to write a code for the Assign method of my component (overrided) - see the question text.
0
hubdogCommented:
procedure ttable.assign
   .....
   RegisterClass(TTable);
   TComponent(Self) := MStream.ReadComponent(nil);
   MStream.Free;
   showmessage(self.filter);//it do show 'x=0' .So I think self maybe is destroied after exit the procedure so the copy is not correctly setted the property.That is only a guess.
   .....

good luck

hubdog
0
hubdogCommented:
when i trace into assign
I found
@copy =$12f6b7
@self =$12f690

the two address not equal.
so i guess you should not use self

regards,hubdog
0
itamarAuthor Commented:
so...
0
hubdogCommented:
i guess the real reason is
  TComponent(Self) := MStream.ReadComponent(nil);
  this code create a new self which is not equal to previous self.

hubdog
0
itamarAuthor Commented:
wow !

It makes sense ! If you can go deeper, please let me know...

tkx
0
hubdogCommented:
because
  if code is
        ......
   {TComponent(self) := MStream.ReadComponent(nil);}

   MStream.Free;
   self.Filter:='a';
   end
   else
      inherited Assign(Source);

then copy.filter:='a';
if the code is
        ......
   TComponent(self) := MStream.ReadComponent(nil);

   MStream.Free;
   self.Filter:='a';
then copy.filter:='';
0
itamarAuthor Commented:
think we're done with this question.

Thanks,
Itamar
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.