Lazarus

Free Pascal => Beginners => Topic started by: SymbolicFrank on October 26, 2021, 02:46:28 pm

Title: Test Variant on Null/nil gives error
Post by: SymbolicFrank on October 26, 2021, 02:46:28 pm
This gives an EVariantError: Invalid variant type cast.

Code: Pascal  [Select][+][-]
  1. function Test(v: Variant): Boolean;
  2. begin
  3.   Result := False;
  4.   if v = nil then Exit;
  5.   Result := True;
  6. end;
  7.  
  8. procedure TForm1.Button1Click(Sender: TObject);
  9. var
  10.   i: Integer;
  11. begin
  12.   i := 0;
  13.   Test(i);
  14. end;        

I try to write a function that encapsulates things like this:

Code: Pascal  [Select][+][-]
  1. MyData : TJSONData;
  2. ThisTable: TDataSet;
  3.  
  4. if not MyData.Items[i].FindPath('description').IsNull then
  5.   ThisTable.FieldByName('descr').Value := MyData.Items[i].FindPath('description').AsString;

So I have to test the value.
Title: Re: Test Variant on Null/nil gives error
Post by: avk on October 26, 2021, 03:05:58 pm
It seems to be something like this:
Code: Pascal  [Select][+][-]
  1. MyData, Found: TJSONData;
  2. ThisTable: TDataSet;
  3.  
  4. Found := MyData.Items[i].FindPath('description');
  5. if Found <> nil then
  6.   ThisTable.FieldByName('descr').Value := Found.AsString;
  7.  
Title: Re: Test Variant on Null/nil gives error
Post by: SymbolicFrank on October 26, 2021, 03:28:16 pm
I wrote this function for it:

Code: Pascal  [Select][+][-]
  1. function TForm1.AddValue(ThisTable: TDataSet; const FieldName: string;
  2.   ThisValue: Variant): Boolean;
  3. begin
  4.   Result := False;
  5.  
  6.   if ThisValue = nil then Exit;
  7.   if ThisValue.IsNull then Exit;
  8.  
  9.   if not Assigned(ThisTable) then
  10.   begin
  11.     Logging.Lines.Add('ERROR: Cannot add field to unassigned table!');
  12.     Exit;
  13.   end;
  14.  
  15.   if ThisTable.FindField(FieldName) = nil then
  16.   begin
  17.     Logging.Lines.Add('ERROR: Field ' + Name + ' does not exist!');
  18.     Exit;
  19.   end;
  20.  
  21.   ThisTable.FieldByName(FieldName).Value := ThisValue;
  22.  
  23.   Result := True;
  24. end;
  25.  

But that doesn't work. Strangely enough, it tries to convert a WideString to a Double for both tests. While I test it with a variant that contains an Integer.
Title: Re: Test Variant on Null/nil gives error
Post by: SymbolicFrank on October 26, 2021, 04:12:31 pm
I cannot read the value anyway before testing it on NULL. So it won't work anyway.

But it's a lot of long lines this way.
Title: Re: Test Variant on Null/nil gives error
Post by: wp on October 26, 2021, 04:16:30 pm
This gives an EVariantError: Invalid variant type cast.

Code: Pascal  [Select][+][-]
  1. function Test(v: Variant): Boolean;
  2. begin
  3.   Result := False;
  4.   if v = nil then Exit;
  5.   Result := True;
  6. end;        

Just to fix this:  You cannot check a variant against nil, use the function VarIsNull(v) instead (in unit variants):
Code: Pascal  [Select][+][-]
  1. uses
  2.   Variants;
  3.  
  4. function Test(v: Variant): Boolean;
  5. begin
  6.   Result := False;
  7.   if VarIsNull(v) then exit;
  8.   Result := True;
  9. end;
Title: Re: Test Variant on Null/nil gives error
Post by: SymbolicFrank on October 26, 2021, 04:35:44 pm
Thanks! That works.

I can pass the variant with ".Value", that way I can test it with VarIsNull. I just have to handle converting the type of the data in that function. Can do.
Title: Re: Test Variant on Null/nil gives error
Post by: SymbolicFrank on October 27, 2021, 11:06:40 am
I managed to get it to work :)

Variants in FPC are... weird. They behave quite different than you would expect. Sometimes, you have to cast them: String(MyVariant) instead of using MyVariant.AsString. Often, if you tell it what type you expect, it turns into an unsupported Custom type (3) and the conversion fails. I guess you are expected to use CastTo.
TinyPortal © 2005-2018