Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Record-Feld über Variable ansprechen (https://www.delphipraxis.net/97742-record-feld-ueber-variable-ansprechen.html)

Berserker 15. Aug 2007 11:38


Record-Feld über Variable ansprechen
 
Servus.

Ich will ein Feld in einem Record mit über eine Variable ansprechen.

Angenommen das Record sieht wie folgt aus:

Delphi-Quellcode:
type TTestRecord = record
    Test1: integer;
    Test2: integer;
    Test3: integer;
    Test4: integer;
end;
nun will ich mittels einer Funktion einen Wert auslesen:

z.B.
Delphi-Quellcode:
function getValueFromRecord(fieldname: string): integer;
also

Delphi-Quellcode:
i := getValueFromRecord('Test1');
Wie ist das zu bewerkstelligen?
Da ich bisher nur mit Datenbanken hantiere ist das neu für mich.

Bei einer DBTable kann ich den Wert vom aktuellen Datensatz mit

FieldByName(varibale).AsInteger; holen.

MfG, Ronny

mkinzler 15. Aug 2007 11:50

Re: Record-Feld über Variable ansprechen
 
einfach
Delphi-Quellcode:
<Recordvariable>.<Feldname>

z.b.
Delphi-Quellcode:
    TestRecord: TTestRecord;
...
    TestRecord.Test1

jim_raynor 15. Aug 2007 12:12

Re: Record-Feld über Variable ansprechen
 
Man kann nicht über den Namen als String direkt auf ein Feld zugreifen, da dazu ganz einfach, die Informationen zur Laufzeit fehlen. Man könnte es über Objekte mit published-Properties machen. Diese kann man dann über die Hier im Forum suchenRTTI abfragen. Aber mit Records würde nur eine feste "Verdrahtung" funktionieren. Also:

Delphi-Quellcode:
function getValueFromRecord(fieldname: string): integer;
begin
  if fieldname='Test1' then
    result:=myRec.Test1
  else if fieldname='Test2' then
    result:=myRec.Test2
  ...
end;

3_of_8 15. Aug 2007 12:20

Re: Record-Feld über Variable ansprechen
 
Was natürlich auch gehen würde:

Delphi-Quellcode:
function getValueFromRecord(fieldname: string; rec: TTestRecord): integer;
var index: Integer;
begin
  if TryStrToInt(copy(fieldname, 5, length(fieldname)-4), index) then
    Result:=PInteger(Cardinal(@rec)+(index-1)*4)^
  else
    Result:=0;
end;
Müsste gehen. Aber natürlich nur, wenn die Zahl drinsteht. ;)

Ansonsten könntest du dir einfach eine Funktion basteln, die per if den Parameter fieldname auf bestimmte Werte überprüft und dann das richtige zurückgibt.

RavenIV 15. Aug 2007 12:32

Re: Record-Feld über Variable ansprechen
 
Zitat:

Zitat von jim_raynor
Man kann nicht über den Namen als String direkt auf ein Feld zugreifen, da dazu ganz einfach, die Informationen zur Laufzeit fehlen

Warum sollte dies nicht gehen?

/edit:
Aus der Delphi7-Hilfe:
Zitat:

Ein Record (in einigen Programmiersprachen auch als Struktur bezeichnet) stellt eine heterogene Menge von Elementen dar. Die Elemente werden Felder genannt. In der Deklaration eines Record-Typs wird für jedes Feld ein Name und ein Typ festgelegt. Die Syntax für die Deklaration eines Record-Typs lautet

type RecordTypName = record
Felderliste1: Typ1;
...
Felderlisten: Typn;
end

Recordtypname ist ein gültiger Bezeichner, Typ gibt einen Typ an, und Feldliste ist ein gültiger Bezeichner oder eine Liste von Bezeichnern, die durch Kommas voneinander getrennt sind. Der letzte Strichpunkt ist optional.

Die folgende Deklaration legt einen Record-Typ namens TDateRec an:

type
TDateRec = record
Year: Integer;
Month: (Jan, Feb, Mar, Apr, May, Jun,
Jul, Aug, Sep, Oct, Nov, Dec);
Day: 1..31;
end;

Jeder TDateRec-Record enthält drei Felder: einen Integer-Wert namens Year, einen Aufzählungswert namens Month und einen weiteren Integer-Wert zwischen 1 und 31 namens Day. Die Bezeichner Year, Month und Day sind Feldbezeichner für TDateRec und verhalten sich wie Variablen. Die Typdeklaration für TDateRec weist den Feldern Year, Month und Day aber keinen Speicherplatz zu. Die Reservierung des Speichers erfolgt erst, wenn der Record instantiiert wird:

var Card1, Card2: TDateRec;

Diese Variablendeklaration erzeugt zwei Instanzen von TDateRec namens Record1 und Record2.

Sie können auf die Felder eines Records zugreifen, indem Sie die Feldbezeichner mit dem Record-Namen qualifizieren:

Record1.Year := 1904;
Record1.Month := Jun;
Record1.Day := 16;

Alternativ dazu ist auch die Verwendung einer with-Anweisung möglich:

with Record1 do
begin
Year := 1904;
Month := Jun;
Day := 16;
end;

Nun können die Werte der Felder von Record1 nach Record2 kopiert werden:

Record2 := Record1;

Da der Gültigkeitsbereich eines Feldbezeichners auf den Record beschränkt ist, in dem er sich befindet, brauchen Sie nicht auf eventuelle Namenskonflikte zwischen Feldbezeichnern und anderen Variablen zu achten.

3_of_8 15. Aug 2007 13:06

Re: Record-Feld über Variable ansprechen
 
Also: Du hast jetzt einen Record. Und du hast einen String. In dem String steht der Name irgendeines Feldes des Records. Wie willst du jetzt von dem Feld direkt auf das Record-Feld zugreifen?

jim_raynor 15. Aug 2007 13:10

Re: Record-Feld über Variable ansprechen
 
Zitat:

Zitat von RavenIV
Zitat:

Zitat von jim_raynor
Man kann nicht über den Namen als String direkt auf ein Feld zugreifen, da dazu ganz einfach, die Informationen zur Laufzeit fehlen

Warum sollte dies nicht gehen?

Ähh. Vielleicht hast du es nicht mitbekommen, aber er möchte anhand des Names zur Laufzeit auf ein Feld zugreifen. Also in einer String-Variable steht 'Test1' und dann möchte er über eine Funktion auf das Feld Test1 des Records zu greifen.

Khabarakh 15. Aug 2007 13:10

Re: Record-Feld über Variable ansprechen
 
Zitat:

Zitat von RavenIV
Zitat:

Zitat von jim_raynor
Man kann nicht über den Namen als String direkt auf ein Feld zugreifen, da dazu ganz einfach, die Informationen zur Laufzeit fehlen

Warum sollte dies nicht gehen?

Weil dazu ganz einfach die Informationen zur Laufzeit fehlen :stupid: :mrgreen: ? Die Beziehung zwischen Namen und Offset eines Recordfeldes ist nur zur Compilezeit bekannt und wird nicht in der Exe gespeichert. Hat man also zur Laufzeit nur einen String des Feldnamens (und auf nichts anderes hat sich jim_raynor bezogen), kommt man nur über Umwege wie der von 3_of_8, der ja auch wieder auf Informationen zur Compilezeit basiert, an den entsprechenden Wert.

[edit]....[/edit]


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:06 Uhr.

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