Subject RE: [IBO] KeyDescLinks prevents OnDataChange from firing
Author Jason Wharton
What this means is you only want a single event notification if field
change(s) take place and so if multiple fields were changed then instead of
sending a pointer to a field object it just sends a nil because there isn't
a way to distinguish each of them in a single event invocation. I remember
really working on this quite a bit and I know there is an important reason I
have it the way I do. Is there a way you can do what you need to do with it
the way I have it?

Jason

> -----Original Message-----
> From: Guido Klapperich [mailto:guido.klapperich@...]
> Sent: Friday, March 11, 2005 12:23 AM
> To: IBObjects@yahoogroups.com
> Subject: Re: [IBO] KeyDescLinks prevents OnDataChange from firing
>
>
>
> > Test whether using the full recommended syntax for
> KeyDescLinks changes the
> > behaviour: set it as PCQUERY.MPNAME=MPNAME. Also, make
> sure that the
> > table MAINPRODUCTGROUPS has no records with null in MPNAME,
> since the
> > KeyDescLinks matching won't match null to null.
>
> I have used the recommended syntax and MPNAME is not NULL,
> but the same
> behaviour. I have done some debugging in the IBO-Code and I have a
> guess, what the reason could be.
> The procedure TIB_Dataset.SysUpdateKeyLinksData in the
> IB_Components.pas
> has the following code:
>
> ...
> if KeyChildUpdatingLevel = 0 then
> begin
> wasExcp := false;
> BeginKeyDataFreeze;
> KeyDataset.Fields.BeginUpdate;
> try
> try
> for ii := 0 to KeyLinks.Count - 1 do
> begin
> tmpCanModifyKeyLinkField := true;
> tmpCol := FieldByName( KeyLinks.IndexNames[ ii ] );
> for jj := 0 to MasterLinks.Count - 1 do
> if tmpCol = FieldByName(
> MasterLinks.IndexNames[jj] ) then
> begin
> tmpCanModifyKeyLinkField := false;
> Break;
> end;
> if tmpCanModifyKeyLinkField then
> KeyDataset.FieldByName( KeyLinks.IndexValues[ ii ]
> ).Assign(
> FieldByName( KeyLinks.IndexNames[ ii ] ));
> end;
> if KeyDataset.NeedToPost then
> for ii := 0 to KeyDescLinks.Count - 1 do
> KeyDataset.FieldByName(
> KeyDescLinks.IndexValues[ ii ]
> ).Assign(
> FieldByName( KeyDescLinks.IndexNames[ ii ] ));
> except
> wasExcp := true;
> raise;
> end;
> finally
> KeyDataset.Fields.EndUpdate( true ); <-------------
> EndKeyDataFreeze;
> if wasExcp then
> SysKeyDataChange( nil );
> end;
> end;
> ...
>
> I have changed the marked line from
> KeyDataset.Fields.EndUpdate( true );
> to KeyDataset.Fields.EndUpdate( false ); and now it works. The
> KeyDescLinks are the last values, that are assigned. And because the
> SingleEventOnly-parameter of Fields.EndUpdate is set to true, the
> changes to the KeyFields are suppressed. But why in the
> OnDataChange-Event the field-parameter null is, is not clear to me.
>
> Regards
>
> Guido
>