Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi TValue casten, kann es das von alleine ? (https://www.delphipraxis.net/193983-tvalue-casten-kann-es-das-von-alleine.html)

Mokus 2. Okt 2017 09:23

Delphi-Version: 10 Berlin

TValue casten, kann es das von alleine ?
 
Hallo zusammen,

seid neuesten bewege ich mich richtung RTTI und finde die möglichkeiten damit echt unglaublich.
Nun komme ich aber zu einem Punkt, wo ich eure hilfe brauche.

Durch TRttiInstanceType.getProperty(PropName);
bekomme ich ein TValue zurück.
Das habe ich nun immer stumpf als Value.AsVaraint zurück gegeben.
Jetzt habe ich ein TDateTime als Property und statt den erwartetetn Wert von now(), der kurz vorher reingeschrieben wurde, liefert asVaraint mir ein Wert zurück, der halt ohne Casten nicht als TDateTime interpritiert werden kann.
Daher meine Frage,

muss ich das wirklich nun von Hand machen, quasi* als

* nicht funktionierender Code
Delphi-Quellcode:
 case Value.type of
Datetime : result := Value.AsDatetime;
Integer : result := Value.AsInteger
{etc.}
oder geht das durch das TValue irgendwie schöner ... ?


( ist die Frage verständlich? ^^)

Gruß

Uwe Raabe 2. Okt 2017 09:35

AW: TValue casten, kann es das von alleine ?
 
Ich weiß jetzt nicht, was du genau vorhast, aber warum verwendest du TValue nicht solange wie möglich und wandelst erst dann um, wenn du den Wert wirklich brauchst?

Mokus 2. Okt 2017 09:48

AW: TValue casten, kann es das von alleine ?
 
ok war bisschen schwer beschrieben.

Hier nun ein bisschen Quellcode mit kommentaren.
Viel davon ist es, ein TcxVerticalGrid mit Daten aus einem Objekt zu füllen.
An dieser Stelle bräuchte ich halt den wirklichen Wert von TValue.



Delphi-Quellcode:
procedure TVerticalGridBinding.Load;
var
  value:   TcxCustomRow;
  i:       Integer;
  SetValue: TValue;
  name:    string;
  list:    TTempList;
  OBJ:     TTTRttiObject;

begin
  FVerticalGrid.BeginUpdate;
  SetValue := TValue.FromVariant(Null);
  try
    for i := 0 to FVerticalGrid.Rows.Count - 1 do
    begin
      value := FVerticalGrid.Rows[i];
      if value is TcxCategoryRow then
        Continue;
      name := value.name;
      if name = FOBJ_ID_NAME then
        Continue;
      self.ModifiziereName(name);
      if FID2OBJ.Count > 0 then
        FID2OBJ.TryGetValue(TcxEditorRow(FVerticalGrid.RowByName(FOBJ_ID_NAME)).Properties.value, list);

    // Bis hier eigentlich Code, der für das Problem unrelevant ist.

      for OBJ in list.Values do
      begin
        if OBJ.GetPropValue(name, SetValue) then // << hier wird sich der Wert Via TValue schon besorgt. Das heißt es wird so lange wie möglich schon mit TValue gearbeitet
          Break;
      end;

      TcxEditorRow(value).Properties.value := SetValue.AsVariant; // < diese Zeile gibt mir komische Werte bei TDateTime zurück. Dadruch kann die TcxEditorRow das nicht als Datum konvertieren.
      SetValue                            := SetValue.FromVariant(Null);
    end;
  finally
    FVerticalGrid.EndUpdate;
  end;
end;

Der schöne Günther 2. Okt 2017 09:50

AW: TValue casten, kann es das von alleine ?
 
TValue ist TValue. Du kannst implizit fast beliebigen Kram reinstecken, aber du musst explizit sagen was du rausholen möchtest, das ist beim (schrecklichen) Variant anders.
Delphi-Quellcode:
procedure printDateTime(timestamp: TDateTime);
begin
   WriteLn( DateTimeToStr(timestamp) );
end;

procedure p();
var
   asDateTime: TDateTime;
   asValue: TValue;
   asVariant: Variant;
begin
   asDateTime := Now();
   asValue := asDateTime;
   asVariant := asDateTime;
   printDateTime(asVariant);
   printDateTime(asValue.AsVariant);
   //acceptDateTime(asValue); // << Geht nicht
end;

Uwe Raabe 2. Okt 2017 10:04

AW: TValue casten, kann es das von alleine ?
 
Ich glaube, jetzt verstehe ich: Da
Delphi-Quellcode:
TcxEditorRow(value).Properties.value
selbst nicht vorgibt, was es für einen Typ erwartet, kannst du das nicht direkt auflösen. Da TTypeKind keinen Wert für TDateTime kennt, wird das intern als Float dargestellt, was dann hinterher wohl falsch interpretiert wird. In dem Fall wird dir auch ein
Delphi-Quellcode:
case Value.Kind of
nicht viel helfen, da wie gesagt TDateTime kein direkt unterstützter Typ ist.

Mokus 2. Okt 2017 10:16

AW: TValue casten, kann es das von alleine ?
 
@Uwe,
ja, du hast da Problem erfasst.
Nun brauch ich eine Lösung, im idealfall eine schöne mit dazu ;)

@Günther
und wie bekomme ich ein TDateTime raus ? Da bleibt mir ja bei deinem Beispiel nur das TDateTime(asValue.asVaraint) oder ?

Mokus 2. Okt 2017 10:22

AW: TValue casten, kann es das von alleine ?
 
Update: nicht schön aber geht.


Delphi-Quellcode:
   
// do Something
  for OBJ in list.Values do
      begin
        if OBJ.GetPropValue(name, SetValue) then
          Break;
      end;

      if TcxEditorRow(value).Properties.EditProperties is TcxDateEditProperties then
        TcxEditorRow(value).Properties.value := TDateTime(SetValue.AsVariant)
      else
        TcxEditorRow(value).Properties.value := SetValue.AsVariant;

      SetValue := TValue.From(null);
    end;
  finally
    FVerticalGrid.EndUpdate;
  end;
end;

Uwe Raabe 2. Okt 2017 10:25

AW: TValue casten, kann es das von alleine ?
 
Dann besser
Delphi-Quellcode:
        TcxEditorRow(value).Properties.value := SetValue.AsType<TDateTime>

Mokus 2. Okt 2017 10:30

AW: TValue casten, kann es das von alleine ?
 
ok, die Zeile wurde geändert!

Danke dafür, für mich nun gelöst.


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:26 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz