Subject Re: [IBO] OnAfterModify event fire twice if using TIB_Column.AsVariant
Author Andreas Hesse
Andreas Hesse wrote:

Any other opinions for the OnAfterModify problem?

> 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';
>>>and
>>>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;
> end
>
> 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;
>
> end;
>
> 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
>>
>
>
> Regards,
> Andreas
>