Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Feldwerte eines Records über den Feldindex abrufen (https://www.delphipraxis.net/213698-feldwerte-eines-records-ueber-den-feldindex-abrufen.html)

Kostas 11. Sep 2023 15:16

Delphi-Version: 5

Feldwerte eines Records über den Feldindex abrufen
 
Hallo Zusammen,

ich habe ein Record aus mehreren String-Feldern. Diese möchte ich gerne über eine Schleife durchgehen. Gibt es eine RTTI Methode um dessen Wert über seinen Feldindex abzurufen?
Delphi-Quellcode:
type
  TMyRecord = Record
    FeldA,
    FeldB,
    FeldC: String;

var MyRecord: TMyRecord;
begin
  //wie kann ich bitte auf das FeldC über seinen Index=2 zugreifen?
  //in etwa so: MyRecord[2]
end;

hoika 11. Sep 2023 15:37

AW: Feldwerte eines Records über den Feldindex abrufen
 
Hallo,
so etwa?

https://stackoverflow.com/questions/...ord-using-rtti

Andreas13 11. Sep 2023 16:01

AW: Feldwerte eines Records über den Feldindex abrufen
 
Hallo,
das funktioniert auch ohne RTTI:
Delphi-Quellcode:
type
  TMyRecord = packed Record
    FeldA,
    FeldB,
    FeldC: String;
  End;

var
  MyRecord: TMyRecord;

VAR
//  MyArray: Array[1..3] of String ABSOLUTE MyRecord; // oder so:
 MyArray: Array[1..3] of String ABSOLUTE MyRecord.FeldA;

Begin
  MyRecord.FeldA:= 'AAAAAAAAAAAA';
  MyRecord.FeldB:= 'BBBBBBBBBBBB';
  MyRecord.FeldC:= 'CCCCCCCCCCCC';

  WriteLn('MyArray[1] = ', MyArray[1]);
  WriteLn('MyArray[2] = ', MyArray[2]);
  WriteLn('MyArray[3] = ', MyArray[3]);
     
  ReadLn;

End.

mytbo 11. Sep 2023 16:12

AW: Feldwerte eines Records über den Feldindex abrufen
 
Zitat:

Zitat von Kostas (Beitrag 1526748)
Gibt es eine RTTI Methode um dessen Wert über seinen Feldindex abzurufen?

Delphi-Quellcode:
function GetFieldValue(pmTypeInfo: Pointer; pmInstance: Pointer; pmFieldIdx: Integer): TValue;
begin
  if (pmTypeInfo <> Nil)
    and (pmInstance <> Nil)
    and (pmFieldIdx >= 0) then
  begin
    var rttiType: TRttiType := TRttiContext.Create.GetType(pmTypeInfo);
    if rttiType <> Nil then
    begin
      var rttiFields: TArray<TRttiField> := rttiType.GetFields;
      if Length(rttiFields) > pmFieldIdx then
        Exit(rttiFields[pmFieldIdx].GetValue(pmInstance));
    end;
  end;
  Result := TValue.Empty;
end;

var
  rec: TMyRecord;
begin
  rec.FeldC := 'Test';
  ShowMessage(GetFieldValue(TypeInfo(TMyRecord), @rec, 2).ToString);
Bis bald...
Thomas

Uwe Raabe 11. Sep 2023 16:18

AW: Feldwerte eines Records über den Feldindex abrufen
 
Das kann man auch mit einem Record-Helper realisieren:
Delphi-Quellcode:
type
  TMyRecord = record
    FeldA,
    FeldB,
    FeldC: String;
  end;

type
  TMyRecordHelper = record helper for TMyRecord
  private type
    TMockArray = array[0..0] of string;
  private
    function GetItems(Index: Integer): string;
    procedure SetItems(Index: Integer; const Value: string);
  public
    property Items[Index: Integer]: string read GetItems write SetItems; default;
  end;

function TMyRecordHelper.GetItems(Index: Integer): string;
begin
  {$R-}
  Result := TMockArray(FeldA)[Index - 1];
  {$R+}
end;

procedure TMyRecordHelper.SetItems(Index: Integer; const Value: string);
begin
  {$R-}
  TMockArray(FeldA)[Index - 1] := Value;
  {$R+}
end;
Der Aufruf gestaltet sich dann in etwa so:
Delphi-Quellcode:
  var Tmp: TMyRecord;
  Tmp.FeldA := 'Hallo';
  Tmp.FeldB := 'Delphi';
  Tmp.FeldC := 'Welt';
  var Satz: string;
  for var I := 1 to 3 do
    Satz := Satz + ' ' + Tmp[I];
  Writeln(Satz.TrimLeft);
  Readln;

himitsu 11. Sep 2023 16:22

AW: Feldwerte eines Records über den Feldindex abrufen
 
oder manuell

Delphi-Quellcode:
type
  TMyRecord = packed record
  private
    function GetFeld(idx: Integer): string;
    procedure SetFeld(idx: Integer; const Value: string);
  public
    FeldA, FeldB, FeldC: string;
    property Feld[idx: Integer]: string read GetFeld write SetFeld;
  end;

  // oder

  TMyRecord = packed record
  private
    FFeld: array[0..2] of string;
    function GetFeld(idx: Integer): string;
    procedure SetFeld(idx: Integer; const Value: string);
  public
    property FeldA: string index 0 read GetFeld write SetFeld;
    property FeldB: string index 1 read GetFeld write SetFeld;
    property FeldC: string index 2 read GetFeld write SetFeld;
    property Feld[idx: Integer]: string read GetFeld write SetFeld;
  end;

  // oder (wobei, neeeeeee)

  TMyRecord = packed record
  private
    function GetFeld(idx: Integer): string;
    procedure SetFeld(idx: Integer; const Value: string);
  public
    Feld: array[0..2] of string;
    property FeldA: string index 0 read GetFeld write SetFeld;
    property FeldB: string index 1 read GetFeld write SetFeld;
    property FeldC: string index 2 read GetFeld write SetFeld;
  end;

  // oder ....

Kostas 11. Sep 2023 16:40

AW: Feldwerte eines Records über den Feldindex abrufen
 
Hallo Zusammen,

oh, so viele Variante, vielen lieben Dank.

Ich benötige über den Index den Namen und Feldwert. Deshalb versucht ich die Varianten von @mytbo

Delphi-Quellcode:
function GetFieldValue(pmTypeInfo: Pointer; pmInstance: Pointer; pmFieldIdx: Integer): TValue;
begin
  if (pmTypeInfo <> Nil)
    and (pmInstance <> Nil)
    and (pmFieldIdx >= 0) then
  begin
    var rttiType: TRttiType := TRttiContext.Create.GetType(pmTypeInfo);
    if rttiType <> Nil then
    begin
      var rttiFields: TArray<TRttiField> := rttiType.GetFields;
      if Length(rttiFields) > pmFieldIdx then
        Exit(rttiFields[pmFieldIdx].GetValue(pmInstance));
    end;
  end;
  Result := TValue.Empty;
end;

var
  rec: TMyRecord;
begin
  rec.FeldC := 'Test';
  ShowMessage(GetFieldValue(TypeInfo(TMyRecord), @rec, 2).ToString);

Delphi-Quellcode:
var rttiFields: TArray<TRttiField> := rttiType.GetFields;
//das TArray<TRttiField> hier bekomme ich einen Fehler angezeigt E2010 Inkompatible Typen 'String' und 'TValue'
Hat jemand eine Idee?

Uwe Raabe 11. Sep 2023 16:47

AW: Feldwerte eines Records über den Feldindex abrufen
 
Zitat:

Zitat von Kostas (Beitrag 1526760)
Ich benötige über den Index den Namen und Feldwert.

Das ist aber schon eine nicht ganz unerhebliche Information...

Kostas 11. Sep 2023 17:11

AW: Feldwerte eines Records über den Feldindex abrufen
 
Sorry Uwe,

das war mir nicht klar.

mytbo 11. Sep 2023 21:33

AW: Feldwerte eines Records über den Feldindex abrufen
 
Zitat:

Zitat von Kostas (Beitrag 1526760)
Ich benötige über den Index den Namen und Feldwert.

Delphi-Quellcode:
function GetFieldNameAndValue(pmTypeInfo: Pointer; pmInstance: Pointer; pmFieldIdx: Integer; out pmoFieldName: String; out pmoFieldValue: TValue): Boolean;
var
  rttiType: TRttiType;
  rttiFields: TArray<TRttiField>;
begin
  if (pmTypeInfo <> Nil)
    and (pmInstance <> Nil)
    and (pmFieldIdx >= 0) then
  begin
    rttiType := TRttiContext.Create.GetType(pmTypeInfo);
    if rttiType <> Nil then
    begin
      rttiFields := rttiType.GetFields;
      if Length(rttiFields) > pmFieldIdx then
      begin
        pmoFieldName := rttiFields[pmFieldIdx].Name;
        pmoFieldValue := rttiFields[pmFieldIdx].GetValue(pmInstance);
        Exit(True);
      end;
    end;
  end;
  Result := False;
end;

var
  rec: TMyRecord;
  fieldName: String;
  fieldValue: TValue;
begin
  rec.FeldC := 'Test';
  if GetFieldNameAndValue(TypeInfo(TMyRecord), @rec, 2, fieldName, fieldValue) then
    ShowMessage(Format('Name: %s, Value: %s', [fieldName, fieldValue.ToString]));
end;
Bis bald...
Thomas


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:00 Uhr.
Seite 1 von 2  1 2      

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