2

I'm using Delphi XE4 and SuperObject 1.24

I Have the following structure :

type
  TMyArray = Array of Array of Variant;
  TMyRecord = Record
     Values : TMyArray;
  end;

var
 T,W : TMyRecord;
 S : String;
 i : integer;

begin
 SetLength(T.Values, 2 );
 for i := 0 to 1 do
   SetLEngth(T.Values[i],2);

 T.Values[0,0] := 'Hello World';
 T.Values[0,1] := 'Foo';
 T.Values[1,0] := 'Bar';
 T.Values[1,1] := 'is here';

 R := TSuperRttiContext.Create;

 S := R.AsJson<TMyRecord>(T).AsString;
 W := R.AsType<TMyRecord>( SO(S) );
 R.Free;
end;

S Contains {"Values":[["Hello World","Foo"],["Bar","is here"]]} which seems to be correct

W displays (((Delphi exception EVariantBadVarTypeError at $294AD325, Variant array of Unknown), (Variant array of Unknown, Variant array of Unknown)))

How can I recreate a multidimensional array correctly?

Jan Doggen
  • 8,799
  • 13
  • 70
  • 144
Clément
  • 91
  • 6
  • 1
    You can omit the loop with `SetLength(T.Values, 2, 2);` No idea about your question though. – NGLN Jun 02 '13 at 01:23

1 Answers1

4

I found a way to implement it. I searched a lot in google, but I found nothing I could use :( Here is the code I wrote:

// Types and routines
type
  TMyArray = Array of Array of Variant;
  TMyRecord = Record
     Lines   : Integer;
     Columns : Integer;
     Values  : TMyArray;
  end;

 function JSONToDynVariantArray( ctx: TSuperRttiContext; const aObj : ISuperObject;
      var aValue : TValue ) : Boolean;
 var
   i,j: Integer;
  Row,
  Col : ISuperObject;
  SuperType : TSuperType;

  MyData : TMyRecord;

begin
  SuperType := ObjectGetType(aObj);
  case SuperType of
     stNull : begin
       aValue := nil;
       Result := True;
     end;
     stArray : Begin
     End;
    stObject : Begin
        MyData.Lines := aObj.I['Lines'];
        MyData.Columns   := aObj.I['Columns'];
        SetLength(RecData.Values, MyData.Lines, MyData.Columns );
        for i := 0 to aObj.A['Values'].Length -1 do begin
           Row :=  aObj.A['Values'][i];
            for j := 0 to Row.AsArray.Length -1 do begin
                Col := Row.AsArray[j];
                SuperType := ObjectGetType(Col);
                case SuperType of
                   stNull     : MyData.Values[i,j] := varNull;
                   stBoolean  : MyData.Values[i,j] := Col.AsBoolean;
                   stDouble   : MyData.Values[i,j] := Col.AsDouble;
                   stCurrency : MyData.Values[i,j] := Col.AsCurrency;
                   stInt      : MyData.Values[i,j] := Col.AsInteger;
                   stString   : MyData.Values[i,j] := Col.AsString;
                end;
            end;
        end;
        TValue.Make(@MyData, Typeinfo(TMyRecord), aValue);
        Result := True;
    End;
  end;
end;

// Main code

var
  T ,
  W : TMyRecord;
  S : String;
  R : TSuperRttiContext;

begin
  inherited;
  T.Lines := 2;
  T.Columns   := 2;
  SetLength(T.Values, T.Lines,T.Columns );
  T.Values[0,0] := 'Hello World';
  T.Values[0,1] := Date;
  T.Values[1,0] := 10;
  T.Values[1,1] := 234.45;

  R := TSuperRttiContext.Create;

  // This is a very nice feature!!!
  R.SerialFromJson.Add(TypeInfo(TMyRecord), JSONToDynVariantArray );

  S := R.AsJson<TMyRecord>(T).AsString;
  W := R.AsType<TMyRecord>( SO(S) );

  R.Free;
end;

HTH, Clément

Clément
  • 91
  • 6