![]() |
Variablen in Variablen packen
Hi
Noch eine Anfängerfrage, die wahrscheinlich auch schon ein paar mal beantwortet wurde, aber mir fallen leider keine Suchbegriffe ein um eine passende Antwort zu finden. Gibt es eine Möglichkeit, eine Variable in eine andere Variable zu schreiben (bzw. gibt es dazu einen eigenen Variablentyp)? Der Zweck der Übung ist, mit einem einzelnen Knopf je nach Situation eine andere Variable belegen: Sagen wir ich habe 5 Knöpfe Button1 bis Button5, die alle ein und das selbe Formular Form2 aufrufen. In Form2 gibt es jetzt Knopf ButtonB, der je nachdem welcher Knopf zum aufrufen von Form2 benutzt wurde einer anderen Variable ein Wert zugewiesen wird. Drücke ich also Button1 und dann ButtonB, wird der Wert Variable 1 zugewiesen. Drücke ich Button2 und dann ButtonB, wird der Wert Variable 2 zugewiesen usw. Ich dachte mir das so:
Delphi-Quellcode:
und dann in Form2
procedure TForm1.Button1Click(Sender: TObject);
begin VarB := Var1; Form2.Visible := True; end;
Delphi-Quellcode:
So dass also VarB die Variable Var1 zugewiesen wird, nicht ihr Wert.
procedure TForm2.ButtonBClick(Sender: TObject);
begin VarB := Memo1.Lines; Form2.Visible := False; end; Im zweiten Teil wird dann der Variable in VarB der Wert von Memo1.Lines zugewiesen. Sorry wenn das jetzt etwas verwirrend war :) Vielen Dank nochmal. |
Re: Variablen in Variablen packen
Stellen wir uns vor, du hast zwei Integer-Variablen X und Y. Jetzt willst du eine Variable B, die von Button1 mit f(X) und von Button2 mit f(Y) belegt wird. ButtonB soll dann f(B) auf 2 setzen, sodass, wenn vorher Button1 gedrückt wurde, in X 2 steht, bei Button2 entsprechend in Y 2. Ist das richtig? Wenn ja, geht das so:
Delphi-Quellcode:
Das ist das Konzept der "Zeiger". Statt eine Variable mit dem Wert einer anderen zu belegen, wird ihre Adresse gespeichert (das macht das @, es berechnet die Adresse einer Variable). Mit der Adresse selbst arbeitet man beim speichern in das Ziel (hier X) nicht, man dereferenziert und sagt damit: hier hin bitte. Das macht das ^ (es "wandelt den Zeiger in eine Variable um"). Zeiger brauchst du nur für simple Datentypen (Zahlen, Shortstrings, statische Arrays, Records), bei Typen, die an sich schon Zeiger sind (dynamische Arrays, normale Strings und Objekte (auch TStrings!)) musst du das nicht tun - da reicht das, was du schon geschrieben hast. VarB wäre eben vom Typ TStrings.
type PInteger = ^Integer;
var B: PInteger; X, Y: Integer; procedure TForm1.Button1Click(Sender: TObject); begin B := @X; Form2.Visible := True; end; procedure TForm2.ButtonBClick(Sender: TObject); begin B^ := 2; Form2.Visible := False; end; |
Re: Variablen in Variablen packen
In der Annahme, dass du Form2 von Form1 aus aufrufst:
Delphi-Quellcode:
public
strgs: TStrings; // muss noch irgendwo created werden {...} procedure TForm1.Button1Click(Sender: TObject); begin Form2.Show2(strgs); end;
Delphi-Quellcode:
Ist nicht getestet aber müsst gehn.
public
strgs: TStrings; procedure Show2(v: TStrings); {...} procedure TForm2.Show2(v: TStrings); begin strgs := v; Show; end; procedure TForm2.ButtonBClick(Sender: TObject); begin strgs.Asign(Memo1.Lines); Hide; end; Du kannst auch mit ShowModal arbeiten, dann kommt man zwar während Form2 offen ist nicht an Form1 heran, kann aber nach dem Schliessen noch in der procedure zum Öffnen direkt auf Form2.Memo1.Lines zugreifen |
Re: Variablen in Variablen packen
Erstmal danke für die schnellen Antworten!
Dax: Ich glaube du hast mein Problem genau erkannt und die Zeiger waren genau das was ich eigentlich gesucht habe. Der Einfachheit halber habe ich das mal in einem Extraprogramm getestet. Mit Integer und String Variablen hat das auch genau den gewünschten Effekt erzielt, bei TStrings gab es einige Probleme. Das Programm sollte einer Variable X und Y jeweils einen unterschiedlichen Text zuweisen, der in eine Memobox eingegeben wurde. Gebe ich jetzt nur für X oder nur für Y einen Wert an, und lasse ihn dann ausgeben, funktioniert es noch. Will ich den jeweils anderen anzeigen lassen, bekomme ich eine Fehlermeldung von wegen 'nil' Wert, wie sich das ja auch gehört. Gebe ich aber für beide Werte einen Wert ein, bekomme ich immer nur den letzten den ich eingegeben habe ausgegeben, egal welche Variable ich ausgeben will. Ich füge mal den ganzen Code an, der lässt sich ja zum Glück zusammenklappen :)
Delphi-Quellcode:
var
Form1: TForm1; B :PTStrings; X, Y :TStrings; implementation uses SetB, ShowScreen; {$R *.dfm} procedure TForm1.btSetXClick(Sender: TObject); begin Form2.Visible := True; B := @X; end; procedure TForm1.btSetYClick(Sender: TObject); begin Form2.Visible := True; B := @Y end; procedure TForm1.btShowXClick(Sender: TObject); begin Form3.Memo1.Lines := X; Form3.ShowModal; end; procedure TForm1.btShowYClick(Sender: TObject); begin Form3.Memo1.Lines := Y; Form3.ShowModal; end; end.
Delphi-Quellcode:
Form3 ist nur das Ausgabefenster mit einem Memo-Element.
procedure TForm2.btSetBClick(Sender: TObject);
var temp :TStrings; begin temp := Memo1.Lines; B^ := Temp; end; end. cruiser: Ich glaube ich verstehe (einigermaßen, und nach Lektüre von ein paar Hilfen, weil ich wirklich ziemlicher Anfänger bin) deinen Ansatz jetzt. Was ich nicht verstehe ist warum in beiden Forms (Ich nehme mal an der erste Abschnitt ist für Form1, der zweite für Form2) die Variable strgs auftaucht. Wenn ich das richtig verstehe, wird durch Klick auf Button1 in Form1 die Procedure TForm2.Show2 ausgeführt, wobei v mit der in Form1 definierten Variable, hier also strgs, belegt wird. In TForm2.Show2 setzt du dann strgs gleich v, also effektiv strgs gleich strgs. Hier komme ich dann nicht mehr mit. Ich habe mir dann gedacht dass strgs aus Form1 nicht die gleiche Variable wie strgs aus Form2 ist und habe es in Form1 durch X ersetzt. Dann würde, wenn ich noch richtig mitkomme, in strgs die Variable X eingesetzt. Bei dem nächsten Befehl unter TForm2.ButtonBClick komme ich dann wieder mit glaube ich. Hier wird der Variablen in strgs der Wert aus Memo1.Lines zugewiesen. In meinem Fall würde man dann also X den Wert aus Memo1.Lines zuweisen, was ja genau der Zweck der Übung ist. Würde ich in Form1 den Befehl
Delphi-Quellcode:
ausführen, würde also Y der Wert in Memo1.Lines zugewiesen.
Form2.Show2(Y);
Wenn ich das jetzt alles richting interpretiert habe, dann sollte das ja genau das sein was ich machen will. Trotzdem bekomme ich jedes mal eine Fehlermeldung. Die würde ich dem Assign zuschreiben, weil ich das selbe Problem bei einem anderen Versuch mit Assign auch hatte. Die Fehlermeldung: Im Projekt Zeiger.exe ist eine Exception der Klasse EAccessViolation mit der Meldung 'Zugriffsverletzung bei Adresse 00454F9D in Modul 'Zeiger.exe'. Lesen von Adresse 00000000' aufgetreten. Möglicherweise auch wichtig könnte die Fehlermeldung sein, die ich immer beim Starten eines Projekts bekomme, unabhängig vom Inhalt desselben: Zugriffsverletzung bei Adresse 006B4F48 in Modul 'coreide90.bpl'. Lesen von Adresse blablabla (unterschiedlich). Auch hierzu kurz der Code:
Delphi-Quellcode:
var
Form1: TForm1; B :TStrings; X, Y, F :TStrings; implementation uses SetB, ShowScreen; {$R *.dfm} procedure TForm1.btSetXClick(Sender: TObject); begin Form2.Show2(X); end; procedure TForm1.btSetYClick(Sender: TObject); begin Form2.Show2 (Y) end; procedure TForm1.btShowXClick(Sender: TObject); begin Form3.Memo1.Lines := X; Form3.ShowModal; end; procedure TForm1.btShowYClick(Sender: TObject); begin Form3.Memo1.Lines := Y; Form3.ShowModal; end; end.
Delphi-Quellcode:
Sorry für die Textwand und vielen Dank für die Hilfe!
public
{ Public-Deklarationen } strgs: TStrings; procedure Show2(B: TStrings); {...} procedure TForm2.Show2(B: TStrings); begin strgs := B; ShowModal; end; procedure TForm2.btSetBClick(Sender: TObject); begin strgs.Assign(Memo1.Lines); Hide; end; end. |
Re: Variablen in Variablen packen
Ich übergeb nur die Pointer-Adressen und halte die in strg.
1.) strgs(Form1) wird als meinetwegen TStringlist initiiert. 2.) strgs(Form1) wird an die Aufrufmethode Form2.Show2 weitergegeben und ist dort jetzt als v bekannt 3.) v (die Adresse unserer Stringlist von Form1) wird jetzt in strgs(Form2) hinterlegt, weil v beim verlassen der Methode aufgelöst ist. 4.) Die daten werden an strgs(Form2) Assigned strgs(Form2) zeigt aber immer noch auf die selbe Stringlist wie stgrs(Form1) Ergebnis ist, da es alles Pointer waren, das strgs(Form1) (unsere Stringlist) jetzt die Lines des Memos enthält. ein wenig confusing, ich weiss.. :zwinker: Man könnt es auch noch anders machen: Form1:
Delphi-Quellcode:
Form2:
public
memlines: TStrings; {...} procedure {...}; begin Form2.Show2(memlines); end;
Delphi-Quellcode:
Das ist ein wenig einfacher... hier hälst du dir einen Pointer auf TStrings in Form1 und setzt beim Aufruf von Form2 diesen auf Memo1.Lines. Damit greifst du über memlines in Form1 auf Memo1.Lines von Form2 zu, nachdem die Aufruf-Methode durchgelaufen ist.
public
procedure Show2(var strings: TStrings); {...} procedure TForm2.Show2(var strings: TStrings); begin strings := memo1.Lines; Show{modal}; end; Ah ja... der Zugriffsfehler kommt daher, dass du die TStrings nicht initialisiert hast z.B. so:
Delphi-Quellcode:
Bei meinem Ansatz mit Memlines aber DARFST du nicht initialisieren.
aTStringsVar := TStringlist.Create;
|
Re: Variablen in Variablen packen
Ich glaub ich blicke da jetzt durch, hinkriegen tu ich's aber trotzdem nicht. Dein zweiter Ansatz bringt mich leider nicht weiter, weil da gleich beim Öffnen der Form der Text übernommen wird. Das was ich machen will ist mit verschiedenen Knöpfen jeweils das selbe Eingabefeld zu öffnen, und dann die Eingabe jeweils in verschiedene Variablen zu packen. Ich habe versucht das einzubauen indem ich beim öffnen einfüge
Delphi-Quellcode:
und für den Knopf nach der Eingabe
procedure TForm2.Show2(B: TStrings);
begin strgs := B; Show; end;
Delphi-Quellcode:
in der Annahme dass B nur für Show2 mit der jeweiligen Variablen belegt wird und ich sie deshalb in strgs zwischen-ablege. Das gibt mir für X und Y (die Variablen für Show2, ausgelöst durch zwei unterschiedliche Knöpfe in Form1) aber eine nil-value wenn ich versuche sie auszugeben. Ich könnte mir vorstellen dass ich in TForm2.Show2 die Adresse VON B in strgs gespeichert wird, anstatt die Adresse IN B (also nicht X bzw Y). Dann schreibe ich Memo1.Lines in B anstatt von X bzw. Y. Ist das soweit richtig?
procedure TForm2.btSetBClick(Sender: TObject);
begin strgs := Memo1.Lines; Hide; end; Mein zweiter Ansatz war dann in TForm2.btSetBClick strgs durch B direkt zu ersetzten, gibt aber wieder nil-value für X und Y.
Delphi-Quellcode:
Zur Referenz nochmal den Code aus Form1:
procedure TForm2.btSetBClick(Sender: TObject);
begin B := Memo1.Lines; Hide; end;
Delphi-Quellcode:
Und die Public-Deklarationen in Form2:
var
Form1: TForm1; B :TStrings; X, Y, F :TStrings; implementation uses SetB, ShowScreen; {$R *.dfm} procedure TForm1.btSetXClick(Sender: TObject); begin Form2.Show2(X); end; procedure TForm1.btSetYClick(Sender: TObject); begin Form2.Show2 (Y) end; procedure TForm1.btShowXClick(Sender: TObject); begin Form3.Memo1.Lines := X; Form3.ShowModal; end; procedure TForm1.btShowYClick(Sender: TObject); begin Form3.Memo1.Lines := Y; Form3.ShowModal; end; end.
Delphi-Quellcode:
Und nochmal danke für deine Mühe!
public
{ Public-Deklarationen } strgs: TStrings; procedure Show2(B: TStrings); end; |
Re: Variablen in Variablen packen
Liste der Anhänge anzeigen (Anzahl: 2)
Wenn es ein Eingabefeld ist sollte doch ShowModal passen, oder?
Du ersetzt auch dauernd nur die Pointer, was du aber willst ist doch die Daten weiter zu geben, oder? Einmal von Form1 zum editieren nach form2 und dann wieder zurück. und einmal von form1 zum Anzeigen nach Form3. Schau dir mal den Anhang an... ist vollkommen unoptimiert aber als Anschauung evtl. brauchbar. EDIT: Ein zweiter Anhang. Genauso einfach gestrickt aber mit TStrings... |
Re: Variablen in Variablen packen
Ich bin auf Show zurückgefallen weil mit ShowModal und dann Hide das ursprungsfenster nicht benutzbar ist. Wahrscheinlich müsste ich close benutzen, bin da grad erst drauf gekommen :P
Die Projekte schau ich mir morgen mal an, ist heut schon etwas spät. |
Re: Variablen in Variablen packen
Bin erst heute dazu gekommen es mal auszuprobieren, zeigt sehr gut wie's geht, nochmal vielen Dank.
Blöderweise klappt es in der Praxis in meinem Projekt immer noch nicht, ich kriege immer noch die Zugriffsverletzung beim Assignen bei GetText, und auch wenn ich versuche manuell eine von meinen 'Ziel-Variablen' (X und Y in deinem Beispiel) zu assignen. Ich dachte eigentlich ich hätte auch alles richtig deklariert und initiiert:
Delphi-Quellcode:
public
{ Public-Deklarationen } noteArmory, noteGear, noteAlts, noteAttunement, noteContacts :TStrings; noteHours, noteMotivation, noteGearing, noteRole, noteHistory :TStrings; noteComputer, noteContactInfo, varNote :TStrings; procedure SetNote (Place: string; varNote :TStrings); end;
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin // Objekte initiieren ist wichtig!!! noteArmory := TStringList.Create; noteGear := TStringList.Create; noteAlts := TStringList.Create; noteAttunement := TStringList.Create; noteContacts := TStringList.Create; noteHours := TStringList.Create; noteMotivation := TStringList.Create; noteGearing := TStringList.Create; noteRole := TStringList.Create; noteHistory := TStringList.Create; noteComputer := TStringList.Create; noteContactInfo := TStringList.Create; end;
Delphi-Quellcode:
procedure TForm1.SetNote (Place: string; varNote :TStrings);
begin // formNoteWindow.Caption := Place; // Text in den Editor schieben if VarNote <> nil then formNoteWindow.SetText(varNote); // nur wenn OK gedrückt wurde (siehe Modal-Result der beiden // Buttons nei der Editor-Form) if formNoteWindow.ShowModal = mrOK then // Hole den text zurück formNoteWindow.GetText(varNote); // säubere Editor formNoteWindow.ClearText; end;
Delphi-Quellcode:
Nachdem ich jetzt stundenlang ergebnislos auf den code gestarrt habe ohne den Fehler zu finden muss ich dich leider nochmal damit belästigen :?
procedure TformNoteWindow.GetText(varNote: TStrings);
begin // den übergeben Strings die DATEN des Memos setzen varNote.Assign(memoNoteWindow.Lines); end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:43 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