Recent

Author Topic: Test Variant on Null/nil gives error  (Read 1591 times)

SymbolicFrank

  • Hero Member
  • *****
  • Posts: 745
Test Variant on Null/nil gives error
« 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.
« Last Edit: October 26, 2021, 02:53:26 pm by SymbolicFrank »

avk

  • Hero Member
  • *****
  • Posts: 505
    • my self-education project
Re: Test Variant on Null/nil gives error
« Reply #1 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.  

SymbolicFrank

  • Hero Member
  • *****
  • Posts: 745
Re: Test Variant on Null/nil gives error
« Reply #2 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.

SymbolicFrank

  • Hero Member
  • *****
  • Posts: 745
Re: Test Variant on Null/nil gives error
« Reply #3 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.

wp

  • Hero Member
  • *****
  • Posts: 9051
Re: Test Variant on Null/nil gives error
« Reply #4 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;
Mainly Lazarus trunk / fpc 3.2.0 / all 32-bit on Win-10, but many more...

SymbolicFrank

  • Hero Member
  • *****
  • Posts: 745
Re: Test Variant on Null/nil gives error
« Reply #5 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.

SymbolicFrank

  • Hero Member
  • *****
  • Posts: 745
Re: Test Variant on Null/nil gives error
« Reply #6 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