Delphi-PRAXiS
Seite 1 von 3  1 23   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Auf Klassenvariablen indiziert zugreifen? (https://www.delphipraxis.net/177174-auf-klassenvariablen-indiziert-zugreifen.html)

Joerginger 22. Okt 2013 08:32

Delphi-Version: 2010

Auf Klassenvariablen indiziert zugreifen?
 
Hallo Delpi-Mitbrüder (und Schwestern),

ich habe eine von TRemotable abgeleitete Klasse Article

Code:
Article = class(TRemotable) //DURCH WSDL-IMPORT SO BENAMST...
  private
    FOXID: TXSString;
    FOXSHOPID: TXSString;
    FOXPARENTID: TXSString;
    FOXACTIVE: TXSBoolean;
    //geht natürlich elendslang weiter... alle Felder aus OXID Artikelstamm
Wie unschwer zu erkennen ist hat das Teil generell keine Variablen im Einsatz, sondern nur die Delphi-nilable-Variante, wiederum Klassen, im Einsatz.

Wenn ich jetzt einen Artikel in den Shop hochschiessen möchte mach ich:

Code:
  //ARRAY UM 1 SATZ VERGRÖSSERN
  setLength(aArt,iDX+1);
  aArt[iDX]:=Article.create; //ARTIKEL BASTELN
  aArt[iDX].OXID:=TXSstring.Create; //ERSTES FELD BASTELN
  aArt[iDX].OXID.XSToNative('05848170643ab0deb9914566391c0c63'); //WERT ZUWEISEN
  aArt[iDX].OXTitle:=TXSstring.Create; ...
  aArt[iDX].OXTitle.XSToNative('Tescht mit ÄÖÜäöüß uns allen Spielis by EJ...');
  aArt[iDX].OXActive:=TXSBoolean.Create;
  aArt[iDX].OXActive.asBoolean:=True;
  aArt[iDX].OXPRICE:=TXSDecimal.Create;
  aArt[iDX].OXPRICE.XSToNative(SoapFloatToStr(6.99));
  aArt[iDX].OXVAT:=TXSDecimal.Create;
  aArt[iDX].OXVAT.XSToNative(SoapFloatToStr(-1));
... iss natürlich möglich und funktioniert, ich würd mir aber gerne eine Procedure basteln (ungefähr so lautend)
Code:
//NUR ALS BEISPIEL! VARIABLE = ICH WEISS NICHT WAS ICH VERWENDEN SOLL...
procedure OXWriteField(Feldname:variable;iDX:integer;sStr:ansiString);
//iDX = INDEX IM ARRAY
//sStr = WERT ZU SCHREIBEN
die ich dann z.B. mit
Code:
OXWriteField('OXTITLE',1,'Des Artikels neue Bezeichnung');
aufrufen kann und die dann das jeweilige Feld instanziert und mit TX richtig befüllt. Im Endeffekt würd ich es dann noch 3 x overloaden, damit ich boolean, decimal, integer und string richtig abhandeln kann.
aArt ist Globales Array, von daher auch in der procedure im Zugriff...

Nur: ich kriegs nicht gebacken...

wenn ich aArt[iDX].sFN ansprechen will meckert D2010 berechtigterweise, dass es sFN nicht kennt. Mit (sFN) bzw. [sFN] tuts genausowenig. Gibts doch sicher einen ganz einfachen Weg dafür, der mit grad nicht einfällt...

Bin zur Zeit ohne :idea:

GLG,

Erwin J.

Aurelius 22. Okt 2013 08:41

AW: Auf Klassenvariablen indiziert zugreifen?
 
Hallo Joerginger,

das sollte mit Introspection funktionieren. Grob gesagt kannst du hiermit zur Laufzeit Informationen über den Aufbau von Objekten/Klassen abfragen (Variablen, Funktionen etc.). Mangels Delphi kann ich das nicht selbst testen, allerdings spuckt Google dazu einige Links aus.

http://www.buehling.org/?book=blog&d...-introspection
https://en.wikipedia.org/wiki/Type_i...#Object_Pascal

Ich hoffe das hilft dir weiter.

Lemmy 22. Okt 2013 08:49

AW: Auf Klassenvariablen indiziert zugreifen?
 
Tach,

wenn Du die 2010er Version gekauft hast, dann hast Du gewisse Chancen, dass du zusätzlich das Buch "Delphi 2010 Handbook" von Marco Cantu dazu erhalten hast - herunterzuladen bei Embarcadero bei deinen Downloads bzw in CodeCentral:
http://cc.embarcadero.com/Item/27613

Hier erklärt Marco u.a. die neue RTTI mit der Du auf die Properties zugreifen kannst. Du kannst auch die "alte" RTTI verwenden, dazu einfach mal die Unit TypeInfo einbinden und anschauen.

Grüße

himitsu 22. Okt 2013 09:10

AW: Auf Klassenvariablen indiziert zugreifen?
 
Auf Published-Property kann man auch schon mit der alten RTTI drauf zugreifen.

Man kann aber notfalls auch die Variablen als Array erstellen und dann über indizierte Property drauf zugreifen, hab aber auch den Vorteil alles über's Array ansprechen zu können.


Wenn du auf private Felder über die neue RTTI zugreifen willst, dann vergiß nciht, daß du dann etwas größere EXEn hast, da diese RTTI-Infos auch mit einkompilieren mußt. (deaktivieren der zugehörenden RTTI-Infos sollte man dann vermeiden, aber da hierdurch die Anwendungen nun einfacher gehackt werden können, ist sowieso egal)

Joerginger 22. Okt 2013 09:12

AW: Auf Klassenvariablen indiziert zugreifen?
 
Mal vorab Danke für die Wortspenden!

Introspection... gut zu wissen für weitere Projekte, aber einerseits weiss ich ja den Namen, den ich übergeben will, ich wills ja auch nicht durchiterieren, sondern einfach nur ein (bekanntes) Feld per Namen ansprechen (oder per Pointer oder what so ever). Und mit diesem Feld eben Sachen anstellen, wie z.B. ein := TXCreate oder einen Wert zuweisen. Und andererseits geht das so wie ich das verstehe nur bei public... Die Felder sind allerdings allesamt Private.

Wenn ichs direkt (siehe Beispiel) zuweise funktionierts ja ad hoc. Wenn ich aber diese Zuweisung aus Gründen der Lesbarkeit in eine eigene PROC packen will kann ich nicht auf das Feld zugreifen, weil ich eben nicht weiss WIE?

Was schon geklappt hat war, den ganzen String (aArt[iDX].OXID) als TXSString zu übergeben, in der Proc eine Variable TXSString zu basteln, die zu createn und mit dem Wert zu bestücken und hernach per := der übergebenen TXSString zuzuweisen. Halte ich aber für Grenzwertig und net sauber...

@Lemmy: Du setzt bei mir leider zuviel Wissen voraus :oops::shock: Ich bin noch nicht so weit das alles zu kapieren...

@Himitsu: danke, aber WIE greife ich zu darauf... Das ist das was mir fehlt :roll:

greetz, Joerginger (A.K.A. Erwin)

Joerginger 22. Okt 2013 09:48

AW: Auf Klassenvariablen indiziert zugreifen?
 
Vielleicht hab ich auch zu kompliziert gefragt, ist ja noch zeitig des Morgens für mich...

Wenn ich eine procedure TUWAS(sStr:string); habe, kann ich mit TUWAS('juhu'); drauf zugreifen und habe 'juhu' im Zugriff. Ich kann sStr:=''; sagen, ich kann sStr:=sStr+'di'; schreiben und erhalte 'Juhudi' etc.

Nun würde ich gern ein bekanntes Feld (z.B. 'OXID') einer bekannten Klasseninstanz (aArt[index]) einer Prozedur übergeben um ebendort in dieser Prozedur auf selbiges Feld zuzugreifen, so wie ich es auch im aufrufenden Code kann... Brauche ich dazu wirklich die RTTI?

Code:
    //Hier funktioniert das...
    aArt[iDX].OXID:=Article.create; //gar kein Problem
Ich will nur diesen Aufruf Create und die Wertzuweisung in eine extra Prozedur auslagern, damit ich nicht so eine große Aufrufende Prozedur habe... Und dazu müsste ich der aufgerufenen Prozedur doch sagen können, welches Feld ich beackern will???

greetz, Erwin J.

Lemmy 22. Okt 2013 09:54

AW: Auf Klassenvariablen indiziert zugreifen?
 
Zitat:

Zitat von Joerginger (Beitrag 1232705)
@Lemmy: Du setzt bei mir leider zuviel Wissen voraus :oops::shock: Ich bin noch nicht so weit das alles zu kapieren...

ich entschuldige mcih jetzt gleich mal vorab: Ich setze zu viel Wissen voraus um ein BUCH zu lesen? ;-) OK ist in englisch. aber selbst die "alte" RTTI kann das mit 2-3 Methodenaufrufen in 5 Zeilen Code.

http://delphitutorials.de/node/20

ein Tutorial, das sich damit beschäftigt - hat zwar ein etwas anderes Ziel, aber die Vorgehensweise sollte damit eigentlich klar werden:

Properties als published deklarieren und mit dem Compilerschalter M+ arbeiten oder die Klassen von TPersistend ableiten und nicht von TObject
dann "einfach" auslesen:

Delphi-Quellcode:
  iCount:=GetPropList(oAdresse,PropertyList);
  for idxIndex := 0 to iCount - 1 do begin
  PropInfo:=PropertyList^[iIndex];
  if PropInfo<>nil then begin
    aValue:=GetPropValue(oAdresse,PropInfo^.Name);
    aLabelText:=aLabelText+' '+aValue;
  end;
dito für das schreiben.

DeddyH 22. Okt 2013 09:55

AW: Auf Klassenvariablen indiziert zugreifen?
 
Sicher geht das, Du musst halt die Werte als Parameter übergeben, das ganze SetLength()-, Create()- und Zuweisungs-Gedöns geschieht dann eben in dieser Prozedur.

Joerginger 22. Okt 2013 10:10

AW: Auf Klassenvariablen indiziert zugreifen?
 
@DeddyH: ja, genau das ist es, ich will Parameter übergeben... Aber WIE?

Das habe ich, das funktioniert. Es wird in der Klasse Artikel (die wegen SOAP-Zugriff TRemotable sein muss!!! das "FELD" bzw. die Subklasse "OXID" kreiert und mit einem Wert befüllt...
Code:
  aArt[iDX].OXID:=TXSstring.Create;
  aArt[iDX].OXID.XSToNative('05848170643ab0deb9914566391c0c63');
und damit's lesbarer wird möchte ich gerne
Code:
  OXWrite('OXID',iDX,'05848170643ab0deb9914566391c0c63');
aufrufen können, wobei die Procedure OXWrite ja nix anderes machen soll als die 2 Zeilen oben zu ersetzen, und zu wissen, dass jetzt
aArt[iDX].OXID angesprochen werden soll.... Nur das krieg ich irgendwie nicht hin.

Ich würde einfach nur gerne den Feldnamen übergeben, den Index des Array und den Wert. Und nur daran scheiterts, da ich nicht weiss WIE ich den Feldnamen so übergeben kann, dass ich ihn mit dem (globalen) Array verbinden kann...

Wenn ich aArt{[DX].OXID als ganzes übergebe (nämlich gleich als TXSString definiert) kann ich zwar zugreifen, aber es erstellt mir die Subklasse irgendwo, aber nicht in meinem Array...

@Lenny: oja, lesen können wir voraussetzen, sogar Englisch. Aber wie Du richtig vermutet hast hab ich das Buch nicht, da ich mit einem gratis D7 programmiere und dieses Projekt für einen Bekannten auf seinem D2010 erstelle.

greetz, Erwin J.

DeddyH 22. Okt 2013 10:22

AW: Auf Klassenvariablen indiziert zugreifen?
 
Kurzes Beispiel: gegeben sei die Klasse TPerson mit den Feldern Name und Vorname und ein dynamisches Array davon. Ursprungscode:
Delphi-Quellcode:
SetLength(Personen, Length(Personen) + 1);
Personen[High(Personen)] := TPerson.Create;
Personen[High(Personen)].Vorname := 'Hans';
Personen[High(Personen)].Name := 'Wurst';
SetLength(Personen, Length(Personen) + 1);
Personen[High(Personen)] := TPerson.Create;
Personen[High(Personen)].Vorname := 'Reiner';
Personen[High(Personen)].Name := 'Zufall';
SetLength(Personen, Length(Personen) + 1);
Personen[High(Personen)] := TPerson.Create;
Personen[High(Personen)].Vorname := 'Machmal';
Personen[High(Personen)].Name := 'Dietürzu';
Dann kann man das kürzen zu:
Delphi-Quellcode:
procedure AddPerson(const AVorname, AName: string);
begin
  SetLength(Personen, Length(Personen) + 1);
  Personen[High(Personen)] := TPerson.Create;
  Personen[High(Personen)].Vorname := AVorname;
  Personen[High(Personen)].Name := AName;
end;

...

AddPerson('Hans', 'Wurst');
AddPerson('Reiner', 'Zufall');
AddPerson('Machmal', 'Dietürzu');


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:50 Uhr.
Seite 1 von 3  1 23   

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