Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 675
  • Last Modified:

Problem with variants

Hi all,

I have an object ( cut down version)

  TObjField = class( TObject)
    private
      FName: string;
      FValue: Variant;
      FFieldType: TFieldType;

      function GetAsFormattedString: string;
    public
      property Name: string           read FName      write FName;
      property Value: Variant         read FValue     write FValue;
      property FieldType: TFieldType  read FFieldType write FFieldType;
    end;

In my function GetAsFormattedString I am having problems.

function TObjField.GetAsFormattedString: string;
begin
  Result := '';

  if FValue = unassigned then Exit;

    case FFieldType of
      ftString,
      ftMemo      : Result := Trim( FValue);
      ftInteger,
      ftSmallint  : Result := IntToStr( FValue);
      ftFloat,
      ftBCD       : Result := Trim( FloatToStrF( FValue, ffFixed, 18, 2));
      ftCurrency  : Result := Trim( FloatToStrF( FValue, ffCurrency, 18, 2));
      ftDate      : Result := Trim( FormatDateTime( 'dd/mm/yyyy', FValue));
      ftBoolean   : if FValue then
                      Result := 'True'
                    else
                      Result := 'False'
    end;
end;

Now in code I have 2 field objects with the various properties

FFieldType = ftsmallint
with
FValue = 0

and

FFieldType = ftDate
with
FValue = unassigned

When I call the GetAsFormattedString for both of the objects,
the FValue = unassigned for BOTH of them is TRUE.

Why does the integer object also think 0 is unassigned?

0
mikelittlewood
Asked:
mikelittlewood
1 Solution
 
2266180Commented:
because unassigned uses varclear to make the necessary comparisons.
I have had such problems myself yesterday, also with varnull. my workaround is this function:

function isbadolevariant(v:olevariant):boolean;
var strtag:string;
begin
  result:=true;
  try
    if (VarType(v)=Vardispatch) and (integer(IDispatch(v))=0) then
      exit;
    strtag:=vartostr(v);
    if (strtag='0') or (strtag='1') then
      exit;
    result:=false;
  except
    on e:exception do
      showmessage('some error occured: '+e.message);
  end;
end;

of course I am working with interface types only so in my case a value of 0 or 1 (varempty and varnull) are invalid.

in your case you will probably have to work with testing the type as well :
if VarType(unassigned)=varempty then

ex:
var v:variant;
begin
  v:=VarAsType(0,varSmallint);
  if VarType(v) = varEmpty then
    showmessage('empty');
will not show the message.
wheras
  if VarType(unassigned) = varEmpty then
    showmessage('empty');
will show the message.

I don't know if I made a good exmplanation, but feel free to ask :)
0
 
mikelittlewoodAuthor Commented:
ah ok.

Taking your Empty example I changed it to

if VarIsEmpty( FValue) then exit;

This seems to work fine for both.

Cheers for the pointer
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now