Recent

Author Topic: [SOLVED] RTTI getValue of TDateTime Property  (Read 1605 times)

StraightFree

  • New Member
  • *
  • Posts: 23
[SOLVED] RTTI getValue of TDateTime Property
« on: January 23, 2020, 04:53:30 pm »
Hi everyone,

I'm having trouble getting a TDateTime property to be read via RTTI.

I can retrieve the string and integer property value.
I use the following code for string:

"Prop.GetValue(TObject(Obj)).AsString;"

And this one for integer:

"Prop.GetValue(TObject(Obj)).AsInteger;"

However, for TDateTime properties there is no adequate return. I tried to recover as an integer, but, it gives the following error:

"Invalid class typecast"

Does anyone know any way to retrieve the value of TDateTime properties?

Any help is most welcome.

Thanks for listening.
« Last Edit: January 24, 2020, 07:33:24 pm by StraightFree »

howardpc

  • Hero Member
  • *****
  • Posts: 3310
Re: RTTI getValue of TDateTime Property
« Reply #1 on: January 23, 2020, 05:29:51 pm »
Try
Prop.GetValue(TObject(Obj)).AsDouble
then use DecodeDate()

StraightFree

  • New Member
  • *
  • Posts: 23
Re: RTTI getValue of TDateTime Property
« Reply #2 on: January 23, 2020, 07:11:18 pm »
howardpc,

Thanks for your reply.

The AsDouble type does not appear in my lazarus, is it necessary to add some uses?

I tried the AsCurrency type, which are compatible, but give the same error:

"Invalid class type cast"

Do you have any other suggestions?

StraightFree

  • New Member
  • *
  • Posts: 23
Re: RTTI getValue of TDateTime Property
« Reply #3 on: January 23, 2020, 09:30:55 pm »
I realized that I have the same problem for float properties.

It seems that lazarus' rtti is only able to read the properties of integer and string types.

Does anyone know anything about it?

howardpc

  • Hero Member
  • *****
  • Posts: 3310
Re: RTTI getValue of TDateTime Property
« Reply #4 on: January 23, 2020, 09:56:50 pm »
I assumed there was an .AsDouble without checking.
TValue has AsExtended. You could try that.



StraightFree

  • New Member
  • *
  • Posts: 23
Re: RTTI getValue of TDateTime Property
« Reply #5 on: January 23, 2020, 10:22:00 pm »
Thanks for your reply howardpc.

I tried AsExtended, but it don’t worked. Returns the same error.

Do you have other suggestion?

howardpc

  • Hero Member
  • *****
  • Posts: 3310
Re: RTTI getValue of TDateTime Property
« Reply #6 on: January 23, 2020, 10:27:22 pm »
Can you show the full compilable code you have, so it is clearer what you are trying to achieve?

StraightFree

  • New Member
  • *
  • Posts: 23
Re: RTTI getValue of TDateTime Property
« Reply #7 on: January 23, 2020, 10:53:25 pm »
Of course.

I am creating an ORM to automate the creation of class based queries.
In this function I receive an object with its properties filled in.
With RTTI I retrieve the TCustomAttribute that represents the name of the field in the database table and the value filled in the property.
Note that when the property is integer or string I can retrieve the value, however, when not of both, I cannot retrieve it and the error occurs.


Code: Pascal  [Select]
  1. var
  2.   Contexto: TRttiContext;
  3.   TypObj: TRttiType;
  4.   Prop: TRttiProperty;
  5.   strInsert, strFields, strValues: String;
  6.   Atributo: TCustomAttribute;
  7.  
  8. begin
  9.   strInsert := '';
  10.   strFields := '';
  11.   strValues := '';
  12.  
  13.   strInsert := 'INSERT INTO ' + getTableNameRTTI(Obj.ClassType);
  14.  
  15.   Contexto := TRttiContext.Create;
  16.   TypObj := Contexto.GetType(TObject(Obj).ClassInfo);
  17.  
  18.   for Prop in TypObj.GetProperties do begin
  19.     for Atributo in Prop.GetAttributes do begin
  20.         if Atributo is TIntegerCampo then
  21.         begin
  22.           strFields := strFields + TIntegerCampo(Atributo).NomeCampo + ',';
  23.           strValues := strValues + IntToStr(Prop.GetValue(TObject(Obj)).AsInteger) + ',';
  24.         end;
  25.  
  26.         if Atributo is TOutroCampo then
  27.         begin
  28.          case TOutroCampo(Atributo).TipoCampo of
  29.            ftBlob, ftString:
  30.              begin
  31.              strFields := strFields + TOutroCampo(Atributo).NomeCampo + ',';
  32.              strValues := strValues + QuotedStr(Prop.GetValue(TObject(Obj)).AsString) + ',';
  33.              end;
  34.            ftFloat, ftCurrency:
  35.              begin
  36.              strFields := strFields + TOutroCampo(Atributo).NomeCampo + ',';
  37.              strValues := strValues + QuotedStr(FloatToStr(Prop.GetValue(TObject(Obj)).AsExtended)) + ',';
  38.              end;
  39.            ftDate:
  40.              begin
  41.              strFields := strFields + TOutroCampo(Atributo).NomeCampo + ',';
  42.              strValues := strValues + QuotedStr(FloatToStr(Prop.GetValue(TObject(Obj)).AsExtended)) + ',';
  43.              end;
  44.            ftTime:
  45.              begin
  46.              strFields := strFields + TOutroCampo(Atributo).NomeCampo + ',';
  47.              strValues := strValues + QuotedStr(Prop.GetValue(TObject(Obj)).ToString) + ',';
  48.              end;
  49.          end;
  50.         end;
  51.     end;
  52.   end;
  53.  
  54.   strFields := Copy(strFields, 1, Length(strFields) - 1);
  55.   strValues := Copy(strValues, 1, Length(strValues) - 1);
  56.   strInsert := strInsert + ' ( ' + strFields +
  57.   ' ) VALUES ( ' + strValues + ')';
  58.  
  59.   showmessage(strInsert);
  60.   result := strInsert;  

PascalDragon

  • Hero Member
  • *****
  • Posts: 963
  • Compiler Developer
Re: RTTI getValue of TDateTime Property
« Reply #8 on: January 24, 2020, 04:16:41 pm »
The following snippet should explain how you work with TValue and TDateTime. You could also move this into a type helper for TValue.

Code: Pascal  [Select]
  1. uses
  2.   SysUtils, TypInfo, Rtti;
  3.  
  4. var
  5.   t: TValue;
  6.   dt, dt2: TDateTime;
  7. begin
  8.   dt := Now;
  9.   TValue.Make(@dt, PTypeInfo(TypeInfo(TDateTime)), t);
  10.   dt2 := TDateTime(t.AsExtended);
  11.  
  12.   Writeln(FormatDateTime('dd.mm.yyyy hh:nn:ss.zzz', dt));
  13.   Writeln(FormatDateTime('dd.mm.yyyy hh:nn:ss.zzz', dt2));
  14. end.

StraightFree

  • New Member
  • *
  • Posts: 23
Re: RTTI getValue of TDateTime Property
« Reply #9 on: January 24, 2020, 07:32:20 pm »
PascalDragon and howardpc,

Thanks for your reply.

It was using a version downloaded in December 2019.
Check the contents of the RTTI unit's getValue function. I realized that the tkFloat types were not implemented.

I noticed that in the source available on git, I already implemented the tkFloat types.
I just downloaded the new version of FCP and Lazarus and everything worked perfectly.

Thank you all for the attention.

PascalDragon

  • Hero Member
  • *****
  • Posts: 963
  • Compiler Developer
Re: RTTI getValue of TDateTime Property
« Reply #10 on: January 25, 2020, 11:35:15 am »
It was using a version downloaded in December 2019.
Check the contents of the RTTI unit's getValue function. I realized that the tkFloat types were not implemented.

I noticed that in the source available on git, I already implemented the tkFloat types.
I just downloaded the new version of FCP and Lazarus and everything worked perfectly.

Yes, the Rtti unit is a work in progress (that's why it still has the experimental directive). However all these changes have been merged to 3.2 so they will be part of that release.

Thaddy

  • Hero Member
  • *****
  • Posts: 9637
Re: [SOLVED] RTTI getValue of TDateTime Property
« Reply #11 on: January 25, 2020, 11:47:30 am »
The full example on the wiki that I added a couple of months ago also handles TDateTime.....Actually it only handles TDateTime... %)
I am more like donkey than shrek

PascalDragon

  • Hero Member
  • *****
  • Posts: 963
  • Compiler Developer
Re: [SOLVED] RTTI getValue of TDateTime Property
« Reply #12 on: January 25, 2020, 11:52:47 am »
Your example does not show how to retrieve a TDateTime value from a TValue, so it's completely irrelevant to the topic.

StraightFree

  • New Member
  • *
  • Posts: 23
Re: [SOLVED] RTTI getValue of TDateTime Property
« Reply #13 on: January 25, 2020, 08:09:27 pm »
PascalDragon,Thaddy and howardpc,

Thanks for your help.

Now I have a problem using the RTTI function setValue.

If you can take a look at the problem and give a hand, I would be very grateful.

Follow the post link:

https://forum.lazarus.freepascal.org/index.php?topic=48261.msg347463#msg347463

Thank you again for your help.