RTC Forums
May 05, 2024, 12:09:05 PM *
Welcome, Guest. Please login or register.

Login with username, password and session length
 
   Home   Help Login Register  
Pages: [1]
  Print  
Author Topic: ObjectFromVariant  (Read 3416 times)
vkorshun
Newbie
*
Posts: 2


« on: October 17, 2011, 01:55:31 PM »

Hi Danijel,

I had some problems with (class function TRtcValueObject.ObjectFromVariant).
My client dataset has TBCDfield. When it was changing I had an error -'Unsupported Variant type.'
I resolved my problem by adding next code 

     if (TVarData(V).VType = varSQLTimeStamp) or
       ( TVarData(V).VType = varSQLTimeStampOffset) or
       ( TVarData(V).VType = varFMTBcd )  then
     begin
       Result:=TRtcTextValue.Create;
       TRtcTextValue(Result).SetText(v);
     end
    else
       raise EConvertError.Create('Unsupported Variant type.');
    end;

What is your opinion about this?

Best regards,
Victor Korshun
Logged
D.Tkalcec (RTC)
Administrator
*****
Posts: 1881


« Reply #1 on: October 17, 2011, 05:30:05 PM »

The exception message you are getting is correct, because there is no TRtcValueObject descendant which can hold these data types natively and I wouldn't convert all these types to Text silently either, because these conversions need to be known on both sides (sender and receiver).

But ... since you have mentioned a dataset and the BCDField, I think your problem is in the "rtcDB.pas" unit and can be solved by extending the "RtcDataSetRowsToDelphi", "DelphiDataSetToRtc" and "DelphiRowToRtc" procedures to handle unsupported types. Please locate the "RtcDataSetRowsToDelphi" procedure in the "rtcDB.pas" unit and replace it, as well as the following 3 procedures, with the code below:

Code:
procedure RtcDataSetRowsToDelphi(rtcDS:TRtcDataSet; DelphiDS:TDataSet);
  var
    flds:integer;
    fldname:string;
    field:TField;
    fstream:TStream;
  begin
  DelphiDS.Active:=True;
  rtcDS.First;
  while not rtcDS.EOF do
    begin
    DelphiDS.Append;
    for flds:=0 to rtcDS.FieldCount-1 do
      begin
      fldname:=rtcDS.FieldName[flds];
      field:=DelphiDS.FindField(fldname);
      if assigned(field) then
        if not rtcDS.isNull[fldname] then
          if field.isBlob then
            begin
            fstream:=DelphiDS.CreateBlobStream(field,bmWrite);
            try
              fstream.CopyFrom(rtcDS.asByteStream[fldname], rtcDS.asByteStream[fldname].Size);
            finally
              fstream.Free;
              end;
            end
          else
            case RTC_FIELD2VALUE_TYPES[rtcDS.FieldType[fldname]] of
              rtc_Currency: field.AsCurrency:=rtcDS.asCurrency[fldname];
              rtc_DateTime: field.AsDateTime:=rtcDS.asDateTime[fldname];
              rtc_String: field.AsString:=rtcDS.asString[fldname];
              else field.Value:=rtcDS.Value[fldname];
              end;
      end;
    DelphiDS.Post;
    rtcDS.Next;
    end;
  end;

procedure DelphiDataSetToRtc(DelphiDS:TDataSet; rtcDS:TRtcDataSet; ClearFieldDefs:boolean=True);
  var
    fdef:TFieldDef;
    flds:integer;
    fldname:string;
    field:TField;
    fstream:TStream;
  begin
  if ClearFieldDefs then
    begin
    rtcDS.Clear;
    for flds:=0 to DelphiDS.FieldDefs.Count-1 do
      begin
      fdef:=DelphiDS.FieldDefs.Items[flds];
      fldname:=fdef.Name;

      field:=DelphiDS.FindField(fldname);
      if assigned(field) then
        if field.FieldKind=fkData then
          rtcDS.SetField(fldname,
                         RTC_DB2FIELD_TYPE(fdef.DataType),
                         fdef.Size,
                         fdef.Required);
      end;
    end;

  DelphiDS.First;
  while not DelphiDS.EOF do
    begin
    rtcDS.Append;
    for flds:=0 to rtcDS.FieldCount-1 do
      begin
      fldname:=rtcDS.FieldName[flds];
      field:=DelphiDS.FindField(fldname);
      if assigned(field) then
        if (field.FieldKind=fkData) and not field.IsNull then
          if field.isBlob then
            begin
            fstream:=DelphiDS.CreateBlobStream(field,bmRead);
            try
              if {$IFNDEF FPC} TBlobField(field).GraphicHeader and {$ENDIF}
                ( (field.DataType = ftGraphic) or
                  (field.DataType = ftTypedBinary) ) then
                RtcSkipGraphicFieldHeader(fstream);
              rtcDS.NewByteStream(fldname).CopyFrom(fstream,fstream.Size-fstream.Position);
            finally
              fstream.Free;
              end;
            end
          else
            case RTC_FIELD2VALUE_TYPES[rtcDS.FieldType[fldname]] of
              rtc_Currency: rtcDS.asCurrency[fldname]:=field.AsCurrency;
              rtc_DateTime: rtcDS.asDateTime[fldname]:=field.AsDateTime;
              rtc_String: rtcDS.asString[fldname]:=field.AsString;
              else rtcDS.Value[fldname]:=field.Value;
              end;
      end;
    DelphiDS.Next;
    end;
  end;

procedure DelphiFieldsToRtc(const DelphiDS:TDataSet; const rtcDS:TRtcDataSet);
  var
    fdef:TFieldDef;
    flds:integer;
    fldname:string;
    field:TField;
  begin
  for flds:=0 to DelphiDS.FieldDefs.Count-1 do
    begin
    fdef:=DelphiDS.FieldDefs.Items[flds];
    fldname:=fdef.Name;

    field:=DelphiDS.FindField(fldname);
    if assigned(field) then
      if field.FieldKind=fkData then
        rtcDS.SetField(fldname,
                       RTC_DB2FIELD_TYPE(fdef.DataType),
                       fdef.Size,
                       fdef.Required);
    end;
  end;

procedure DelphiRowToRtc(const DelphiDS:TDataSet; const rtcDS:TRtcDataSet);
  var
    flds:integer;
    fldname:string;
    field:TField;
    fstream:TStream;
  begin
  rtcDS.Append;
  for flds:=0 to rtcDS.FieldCount-1 do
    begin
    fldname:=rtcDS.FieldName[flds];
    field:=DelphiDS.FindField(fldname);
    if assigned(field) then
      if (field.FieldKind=fkData) and not field.IsNull then
        if field.isBlob then
          begin
          fstream:=DelphiDS.CreateBlobStream(field,bmRead);
          try
            if {$IFNDEF FPC} TBlobField(field).GraphicHeader and {$ENDIF}
              ( (field.DataType = ftGraphic) or
                (field.DataType = ftTypedBinary) ) then
              RtcSkipGraphicFieldHeader(fstream);
            rtcDS.NewByteStream(fldname).CopyFrom(fstream,fstream.Size-fstream.Position);
          finally
            fstream.Free;
            end;
          end
        else
          case RTC_FIELD2VALUE_TYPES[rtcDS.FieldType[fldname]] of
            rtc_Currency: rtcDS.asCurrency[fldname]:=field.AsCurrency;
            rtc_DateTime: rtcDS.asDateTime[fldname]:=field.AsDateTime;
            rtc_String: rtcDS.asString[fldname]:=field.AsString;
            else rtcDS.Value[fldname]:=field.Value;
            end;
    end;
  end;

That should solve your problem. Naturally, you should also remove your changes/additions from the "rtcInfo.pas" unit in order to test if the above changes work for you. If it works, then I will release the same changes in the next RTC SDK update (v4.50).

Best Regards,
Danijel Tkalcec
Logged
vkorshun
Newbie
*
Posts: 2


« Reply #2 on: October 17, 2011, 07:23:01 PM »

Many thanks.
It works.

Best regards,
Victor Korshun
Logged
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2015, Simple Machines Valid XHTML 1.0! Valid CSS!
Page created in 0.024 seconds with 17 queries.