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?

1
  • 1
    You can omit the loop with SetLength(T.Values, 2, 2); No idea about your question though. Commented Jun 2, 2013 at 1:23

1 Answer 1

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

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.