Subject Re: [IBO] OnAfterModify event fire twice if using TIB_Column.AsVariant
Author Andreas Hesse
Helen Borrie wrote:
> At 04:10 PM 13/02/2005 +0100, you wrote:
>>OnAfterModify event fire twice if using IB_Column.AsVariant:
>>- first when setting the field as not Null
>>- second when setting the value of the field
>>IB_Column.AsString work as expected - fire only once
>>IB_Column.AsVariant := 'test';
>>IB_Column.AsString := 'test';
>>should behave the same.
> Why? AsVariant has to test and perform two conversions. You get what you
> request.

No, AsString test 2 conditions, too, but it calls SysSetIsNull(),
which does not fire any events at all
(or should not, because setting a boolean field not null
that was before null will fire events because of call of AsString method!

SetAsVariant work like this:

1) Test, if the new Value is null, then if the Column is not null
set the Column to "IsNull := true" state. (OK)
==> this fire OnAfterModify Event

if VarIsNull(NewValue) or VarIsEmpty(NewValue) then begin
if not IsNull then IsNull := true;

2) set the Column to "IsNull := false" state (WRONG - why should it be done?)
==> if the column was null before then this fire OnAfterModify Event
with normally the wrong new column value.

else begin
IsNull := true;

3) Change value of the column based on the type of the column,
if the new value is not like the actual value
==> this fire OnAfterModify Event

// for example String Type
if AsString <> NewValue then
AsString := NewValue;


I think it is enough to use the setting methods based on the field type,
because this setters to all the rest
(test, if to set null/notNull, set the columns value).

What are the opinions of the others.
Jason, what do you think?

>>The logic of setting a variant value (and TIB_Column.Assign(TIB_Column))
>>should be changed.
> I'm curious as to why you need to use AsVariant at all. Why not just use
> the Value property? It will trip any necessary type validation, as
> required, and avoid exceptions on nulls...

In TIB_Column AsVariant is the same then Value.
Here is the property definition:

property AsVariant: variant read GetAsVariant write SetAsVariant;
property Value: variant read GetAsVariant write SetAsVariant;

that will be replace by other property Value definitons based on the
concrete Column class, for text column:

property Value: string read GetValue write SetValue;

But if I only use a TIB_Column variable, using Dataset.FieldByName(''),
then it will call the default Value property, that is the same as AsVariant
(it is not a virtual method).

> Helen