Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Accessing a Record Structure Programatically (https://www.delphipraxis.net/113795-accessing-record-structure-programatically.html)

Pluto 14. Mai 2008 22:34


Accessing a Record Structure Programatically
 
I habe eine declaration einer record structure, etwa so:

Delphi-Quellcode:
TRec = record
              Datum: TDateTime;
              Art: Char;
              Info: string;          
           end;

MyRecord : TRec;

Ich kann MyRecord.Datum oder MyRecord.info ansprechen, aber ich möchte die record structure at runtime auslesen.

Etwa so wie man bei TTable mit FieldList und Fields Info auslesen kann.

Wie kann ich Ähnliches mit einer Record Structure tun, um die Anzahl der Felder, ihre Typen und Namen at runtime zu ermitteln?

Luckie 14. Mai 2008 22:48

Re: Accessing a Record Structure Programatically
 
Ich habe ehrlich gesagt keine Ahnung, aber mein erster Ansatzpunkt wäre RTTI.

sx2008 15. Mai 2008 00:24

Re: Accessing a Record Structure Programatically
 
Zitat:

Zitat von Pluto
Etwa so wie man bei TTable mit FieldList und Fields Info auslesen kann.
Wie kann ich Ähnliches mit einer Record Structure tun, um die Anzahl der Felder, ihre Typen und Namen at runtime zu ermitteln?

Wie wäre es mit einer Memory-Table ?
Verhält sich genau gleich wie TTable, nur dass alle Daten im Speicher sind. Bei Bedarf auch komprimiert.
Es entsteht natürlich ein gewisser Overhead, andererseits gibt es aber auch viele Vorteile.

Hansa 15. Mai 2008 01:23

Re: Accessing a Record Structure Programatically
 
Vorab :
Zitat:

Titel: Accessing a Record Structure Programatically
..
Wohnort: Dietzenbach
Das ist schon krass. :mrgreen: Soll ich auf englisch antworten, oder was ? :P Also, ein Record ist dumm. Du weißt offensichtlich nicht genau, was OOP ist, bzw. was das in der Praxis bedeutet. Du vermisst wohl die gewohnten Methoden. Aber irgendwoher müssen auch die kommen.

Pluto 17. Mai 2008 11:54

Re: Accessing a Record Structure Programatically
 
Die beste Antwort war von Luckie. Danke!
Daraufhin habe ich die Delphi unit Typinfo genau durchgesehen - aber leider geht es damit auch nicht.
Es gibt offensichtlich keine Möglichkeit.

Googlen brachte einen Eintrag von www.experts-exchange.com, der eine Lösung versprach.
Die sind recht teuer! Hab's doch mal mit einem Probeaccount versucht:
Die versprochene Lösung war: "Es gibt keine Möglichkeit". Das riecht stark nach Abzokke - da bleib ich
doch besser bei diesem Forum.

Hintergrund meiner Frage war:
Ich habe mehrere Arrays of Trec. Die sortiere ich mit QuickSort auf verschiedene Felder des TRec.
Faul, wie ich nun mal bin, wollte ich mir das Kodieren von speziellen QuickSort Routinen ersparen und
eine generische Routine für das Sortieren von Arrays mit Records erstellen, die die Felder der Records
selber ermittelt, also Sortieren auf Feld1 oder n-tes Feld ermöglicht.
Nun habe ich einen Kompromiss gebastelt: Eine QuickSort Routine für Arrays of TRec, der ich per
Parameter den Feldnamen übergeben muss.

Zu Hansa:
"Das ist schon krass. Soll ich auf englisch antworten, oder was ?"
Wir sprechen in der EDV doch alle nur noch gebrochen Deutsch. Auf englisch war der Titel kurz und verständlich.
Statt "Accessing a Record Structure Programatically" hätte ich auch deutsch folgendes schreiben können:
"Zurückgreifen auf einen Satzaufbau während das Programm läuft", wäre das besser?

Muetze1 17. Mai 2008 12:54

Re: Accessing a Record Structure Programatically
 
Zitat:

Zitat von Pluto
"Das ist schon krass. Soll ich auf englisch antworten, oder was ?"
Wir sprechen in der EDV doch alle nur noch gebrochen Deutsch. Auf englisch war der Titel kurz und verständlich.
Statt "Accessing a Record Structure Programatically" hätte ich auch deutsch folgendes schreiben können:
"Zurückgreifen auf einen Satzaufbau während das Programm läuft", wäre das besser?

Auch wenn es offtopic ist, solch ein denglish spricht kein Programmierer. Entweder deutsch oder english und ich habe bisher keine Probleme mich in programmiertechnischen Dingen auf deutsch auszudrücken (Ausnahme: Fachbegriffe). Dein deutscher Satz ist wohl doch mehr als überzogen, oder? Dein Erstbeitrag hatte mich abgeschreckt und ich wollte schon antworten, da ich eine englishsprechende Person vermutete, welche alles versucht sich im deutschen Forum nach Hilfe suchend auszudrücken, was sich mit dem Wohnort wieder zerstreute. Somit: Kein Beitrag.

Und zu deinem Beispiel: "Ich möchte dynamisch, zur Laufzeit, auf die einzelnen Strukturelemente zugreifen."

Und da das dein eigentliches Problem nicht eindeutig beschreibt, würde ich dann noch hinzufügen: "..., wobei ich die Elemente nicht kenne sondern zuvor ermitteln möchte (ähnlich/mit RTTI)."

Also ich habe mir keinen abgebrochen, den Satz habe ich so hingeschrieben und er ist bis auf Fachbegriffe deutsch.

Hansa 17. Mai 2008 14:30

Re: Accessing a Record Structure Programatically
 
Wie wärs denn mit einem Listen-Objekt ? In TObjectList kann man die Record-Struktur reinpacken und das Ding kennt die Methode Sort. Es müsste also nur eine Vergleichsroutine gebastelt werden. Ganz von alleine geht aber auch das nicht ! Ich würde mal nicht überall die Foren nach fertiger Lösung abgrasen, sondern mal F1 drücken und genau lesen. Also OOP lernen und auch Deutsch. :mrgreen: Denn das hier kann man so nicht hinnehmen :

Zitat:

Zitat von Pluto
Wir sprechen in der EDV doch alle nur noch gebrochen Deutsch...

Schlechter Witz oder was ? :lol: Mein Vorschlag für Titel : "Mit Programm auf Record-Struktur zugreifen". Da ist jetzt ein englisches Wort drin, weil ich das unter Fachbegriffe einordne (siehe Mütze). Dasselbe gilt für Array, Button usw. Also für alles, wofür das englische Wort eindeutiger ist. Für "Datensatz" oder "Datenbank" z.B. braucht man kein englisches Wort. Auch Fachbegriffe müssen also nicht zwangsläufig auf englisch geschrieben werden !! Übrigens, wenn mir ein Dietzenbach/Michigan o.ä. :mrgreen: bekannt wäre, dann würde ich jetzt englisch schreiben.

marabu 17. Mai 2008 15:21

Re: Accessing a Record Structure Programatically
 
Hallo Pluto,

Zitat:

Zitat von Pluto
... Googlen brachte einen Eintrag von www.experts-exchange.com, der eine Lösung versprach.
Die sind recht teuer! Hab's doch mal mit einem Probeaccount versucht:
Die versprochene Lösung war: "Es gibt keine Möglichkeit". Das riecht stark nach Abzokke - da bleib ich
doch besser bei diesem Forum. ...

ich kenne EE, weil mich Google da auch schon mal hingeschickt hat, aber einen Probeaccount zum Lesen von Beiträgen brauche ich da nicht. Während die Beiträge zuerst in chiffrierter Form gelistet werden, findest du am Seitenende dann die gleichen Beiträge im Klartext. Hat sich da etwas geändert?

Zu deinem Thema: Ein Feld im Record ist intern durch Offset und Typ beschrieben. Das sind die Informationen die du einer generischen Routine übergeben musst, aber wenn du da nicht fremdbestimmt bist, dann löst du das vielleicht doch besser mit Klassen und RTTI.

Grüße vom marabu

Die Muhkuh 17. Mai 2008 15:27

Re: Accessing a Record Structure Programatically
 
Zitat:

Zitat von marabu
Zitat:

Zitat von Pluto
... Googlen brachte einen Eintrag von www.experts-exchange.com, der eine Lösung versprach.
Die sind recht teuer! Hab's doch mal mit einem Probeaccount versucht:
Die versprochene Lösung war: "Es gibt keine Möglichkeit". Das riecht stark nach Abzokke - da bleib ich
doch besser bei diesem Forum. ...

ich kenne EE, weil mich Google da auch schon mal hingeschickt hat, aber einen Probeaccount zum Lesen von Beiträgen brauche ich da nicht. Während die Beiträge zuerst in chiffrierter Form gelistet werden, findest du am Seitenende dann die gleichen Beiträge im Klartext. Hat sich da etwas geändert

Nein, hat sich nichts geändert. Aber so dolle find ich die Antworten dort als auch nicht, um dafür wirklich Geld ausgeben zu müssen.

Pluto 17. Mai 2008 16:48

Re: Accessing a Record Structure Programatically
 
Dank an Marabu für die Antwort

An Hansa

Also erstmal: Entschuldigung für den englischen Titel.
Eigentlich ist es ja erfreulich, wenn man hier großen Wert auf gutes Deutsch legt, da unsere Sprache ja immer mehr mit Anglizisten verhunzt wird (Beispiel: Relaxen statt Erholen)

Warum ich kein Listobjekt nehme:
1. Es handelt sich um eine Erweiterung eines bestehenden Programmes, da müsste ich an vielen Stellen die bestehenden Arrays durch Listobjekte ersetzen.
2. Auch bei TListCompare benötige ich die Record Definitionen, das Problem bleibt also gleich
3. Die vorhandene Methode Sort ist allerdings ein kleiner Vorteil

Es ist nicht schwer, ein QuickSort für ein array zu schreiben. Ich habe die Vergleichsfunktion meiner QuickSort Routine mit überladenen Funktionen realisiert, somit brauche ich nur den Feldnamen des Records als Parameter übergeben, den Typ des Recordfeldes (char, integer, TDateTime) erkennt die Routine selber.

Noch ein Hinweis:
Nicht jeder, der hier eine Frage stellt, ist ein Anfänger. Bemerkungen wie "also OOP lernen" sollte man mit Vorsicht verwenden!
War hier unpassend, zumal die Frage sich auf Records bezog. Ein Record ist ein Typ aber kein Objekt. Den hat schon Prof. Wirth 1972 definiert, als noch niemand an Objekte dachte.

Grüße
Pluto

Hansa 18. Mai 2008 04:23

Re: Accessing a Record Structure Programatically
 
Zitat:

Zitat von Pluto
Noch ein Hinweis:
Nicht jeder, der hier eine Frage stellt, ist ein Anfänger. Bemerkungen wie "also OOP lernen" sollte man mit Vorsicht verwenden!..

Der Titel lässt aber andere Schlüsse in Richtung "Anfänger" zu !! Du willst zudem einem Record Intelligenz beibringen. Das ist aber OOP, ob es Dir passt oder nicht.

grenzgaenger 18. Mai 2008 08:06

Re: Accessing a Record Structure Programatically
 
Zitat:

Zitat von Pluto
War hier unpassend, zumal die Frage sich auf Records bezog. Ein Record ist ein Typ aber kein Objekt. Den hat schon Prof. Wirth 1972 definiert, als noch niemand an Objekte dachte.

ganz so ist es nicht. hier war schon der vertreter von objektorientierung schlechthin (Smalltalk lebendig. hatte damals aber die allgemeinen programmiersprachen noch nicht infiziert.

siehe hierzu auch:
PS: records und opp sind zwei welten. denn die idee von opp war ja gerade intelligente daten zu kreieren welche wissen wie sie verarbeitet werden können. daher wäre die recorderweiterung seit D2006 als mini-opp anzusehen :-)

toms 18. Mai 2008 08:13

Re: Accessing a Record Structure Programatically
 
Zitat:

Zitat von Pluto
Googlen brachte einen Eintrag von www.experts-exchange.com, der eine Lösung versprach.
Die sind recht teuer! Hab's doch mal mit einem Probeaccount versucht:

Ich habe noch einen Gratis Account von früher.
Du kannst den Direktlink angeben, dann kann ich schauen, ob dort etwas zutreffendes steht.

alzaimar 18. Mai 2008 10:02

Re: Accessing a Record Structure Programatically
 
Da Records statisch sind, ist es überflüssig, die RTTY-Information im Code verfügbar zu machen.

Du kannst aber einen Parser implementieren, der deine Recordstruktur einliest und die entsprechende Information zur Laufzeit generiert. :mrgreen:

sx2008 18. Mai 2008 13:14

Re: Accessing a Record Structure Programatically
 
Zum Thema OOP:
ein guter Programmierer muss merken, wenn ein Record für das gegebene Problem zu schwach ist
und aus dem Record eine Klasse machen.
Er wird dem Record auch nicht länger nachtrauern, sondern die Änderung wird durchgezogen
(je früher desto besser).
Und wenn es an vielen Stellen eine Umstellung gibt, zeigt das nur, wie bitter nötig dies war.

Zum Thema Array:
viele Programmierer greifen zum Array (meist zum dynamischen Array) obwohl eine TList-Klasse
wesentlich geeigneter für das Problem wäre.
Ein Array hat keine eigene Intelligenz, während TList, TObjectList, ... dem Programmierer viel Arbeit abnehmen!

Zum Thema Quicksort:
Beim Sortieren werden im Prinzip nur 2 Funktionen benötigt COMPARE und EXCHANGE.
Exchange, also das Vertauschen zweier Elemente, ist für TList völlig problemlos, ganz gleichgültig
welche Daten vertauscht werden. (beim Array geht das nicht)
Beim Compare, also das Vergleichen zweier Element wird Detailwissen über die Daten notwendig.
Hier kann eine Klasse gegenüber einem Record seinen Vorteil ausspielen, denn die Compare-Methode kann quasi automatisch bereitgestellt werden.

Zitat:

Zitat von Hansa
Wie wärs denn mit einem Listen-Objekt ? In TObjectList kann man die Record-Struktur reinpacken und das Ding kennt die Methode Sort. Es müsste also nur eine Vergleichsroutine gebastelt werden.

Genau das ist der richtige Weg!
Noch einfacher ist allerdings mein Vorschlag mit den MemoryDatasets. Da bekommst du suchen, sortieren, usw. auf dem Silbertablett geliefert.
Ein Memorydataset ist sozusagen eine TObjectList mit eingebauter RTTI und vielen zusätzlichen Funktionen.

himitsu 18. Mai 2008 13:54

Re: Accessing a Record Structure Programatically
 
Zitat:

Zitat von sx2008
Exchange, also das Vertauschen zweier Elemente, ist für TList völlig problemlos, ganz gleichgültig welche Daten vertauscht werden. (beim Array geht das nicht)

Also das Vertauschen zweier (gleich aufgebauter) Records ist auch ohne wissen des Recordaufbaus extrem einfach möglich ... muß ja nur der Speicherinhalt getauscht werden.

Zum Vergleichen hast'e aber recht, denn ohne Wissen über den Aufbau weiß man ja nicht wie man was vergleichen muß.


Aber ob man nun das Wissen über den Aufbau in der Programlogic versteckt, oder in einem Objekt einbaut ... irgendwo muß dieses wissen dennoch hin, also ist doch für so einen einfachen Aufbau kaum ein Unterschied (Record<>Object), nur daß man beim Objekt und wenn es an mehreren Stellen im Programm verwendet wird, alles etwas besser sortiert hat (direkt im Objekt).
nja, dafür haben Object/TList,TTMemoryTable und Co. wiederrum einen etwas/wesendlich größeren Overhead, als der pure Record.

Pluto 22. Mai 2008 19:24

Re: Accessing a Record Structure Programatically
 
Dank für alle Antworten!

an grenzgänger:

Du hast Recht: Ich muß mich korrigieren. Pascal war etwa zeitgleich zu Smalltalk.
Die Links waren sehr interessant. Da habe ich dann noch etwas tiefer gegraben:
Erste Gedanken und Entwicklungen zu OOP findet man in der Literatur bereits Anfang 1960 !

an toms:

Dank für Deinen Vorschlag - aber ich habe die unbrauchbaren Antworten bereits gelesen.

an alzaimar:

Das ist richtig, RTTI war ein Irrweg. Parsen ist möglich, die Exe wertet ja den Record aus,
also kennt sie auch die Struktur.
Das wäre hier aber overkill. Mein Programm läuft, auch wenn der Code etwas weniger
elegant ist, als ursprünglich gedacht.

an sx2008:

zu Quicksort:
Auch bei Arrays kann ich zwei Elemente vertauschen, meine Quicksort Routine für
Arrays läuft einwandfrei.
zu MemoryDataset:
Mir ist nicht klar, was Du mit "MemoryDataset" meinst. In der Delphi-Hlfe taucht dieser Begriff nicht auf.
Meinst Du etwa TClientDataset?
Das verwende ich in Datenbankprogrammen nahezu überall. Es ist blitzschnell, hat viele Vorzüge, wie
Filtern und Clonen, auch kann man kleinere Tabellen einfach als XML abspeichern und laden.

Allerdings werde ich bei begrenzten kleineren Strukturen auch weiterhin Arrays benutzen.
So z.B. für Matritzenberechnungen. Da bleibt der Code einfach und übersichtlich.
OOP kann manchmal auch overkill sein. Man sollte der Aufgabe angepasst pragmatisch, nicht dogmatisch programmieren.

Grüße,
Pluto


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:15 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