Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Variable, die in einer Unit deklariert nutzen
luxoar - So 18.01.09 13:43
Titel: Variable, die in einer Unit deklariert nutzen
Guten Tag,
ich habe mal wieder ein Problem. Ich möchte eine Variable einer Prozedur aus einer zweiten Unit in ein Label der ersten Unit(mit Form1) übergeben. Allerdings zeigt er die Variable in der ersten unit als nich deklariert an. Ich suche den Fehler leider bisher vergeblich :(. Könntet ihr mir bei diesem kleinen Problem helfen? Danke schon einmal im Vorraus :)
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44:
| unit u_bedienung;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, u_bankomat, StdCtrls;
type tform1 = class(TForm) Label1: TLabel; Label2: TLabel; Edit1: TEdit; Button1: TButton; Button2: TButton; GroupBox1: TGroupBox; ListBox1: TListBox; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); private public end;
var form1: tform1; banko: Bankomat; implementation
{$R *.dfm}
procedure tform1.Button1Click(Sender: TObject); begin Bankomat.getkontostand(stand); [b]--> [DCC Fehler] u_bedienung.pas(35): E2003 Undefinierter Bezeichner: 'stand'[/b] label1.caption:=floattostr(stand); end;
procedure tform1.FormCreate(Sender: TObject); begin banko:=Bankomat.create; end;
end. |
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28:
| unit u_Bankomat;
interface
type Bankomat = class (tobject) public constructor create; procedure getkontostand(var stand:single);
end;
implementation
constructor Bankomat.create; begin inherited create; end;
procedure Bankomat.getkontostand(var stand:single); begin randomize; stand:=random(200)+100; end;
end. |
Moderiert von
Narses: Delphi-Tags hinzugefügt
Delete - So 18.01.09 13:51
Du hast die Variable stand ja auch nirgends deklariert. Versuch es mal so:
Delphi-Quelltext
1: 2: 3: 4: 5: 6:
| procedure tform1.Button1Click(Sender: TObject); var stand: single; begin Banko.getkontostand(stand); label1.caption:=floattostr(stand); end; |
Yogu - So 18.01.09 14:04
Hallo,
bitte benutze für deinen Quelltext die Delphi-Tags
<span class="inlineSyntax"><span class="codecomment">{PROTECTTAGd9b754d46fc1a62d5e1533823def0247}</span></span>, damit wir ihn besser lesen können. Klicke dazu in deinem Beitrag einfach auf

, und füge die Tags hinzu. Danke!
Zu deiner Frage: Du kannst nicht einfach auf Parameter (so heißen die Variablen, die Prozeduren und Funktionen übergeben wurden), von außerhalb zugreifen. Aber das ist in deinem Fall auch gar nicht notwendig. Die Lösung ist eine lokale Variable in der Prozedur
Button1Click, wie
DeddyH schon schrieb.
Grüße,
Yogu
luxoar - So 18.01.09 15:05
Ahhh vielen dank. Ich hatte diese Quelltext-Bearbeitungsmethode schon gesucht ich merke es mir. Und natürlich vielen Dank für die schnelle hilfreiche antwort. Das mit der Deklaration der Variable in Button_click1 hatte ich dann auch gesehen. Allerdings bin ich nicht auf die Zeile: Banko.getkontostand(stand); gekommen. Noch einmal vielen dank :)
jaenicke - So 18.01.09 15:13
Du machst mehrere Fehler.
Delphi-Quelltext
1:
| Bankomat.getkontostand |
Bankomat ist dein Typ, nicht dein erzeugtes Objekt. Banko musst du benutzen.
Nenne Typen am besten wie es Konvention ist mit einem T am Anfang: TBankomat.
Du vergisst dein Objekt wieder freizugeben! In FormDestroy gehört
Banko.Free; !
Randomize gehört nur einmal aufgerufen, nicht jedesmal vor Random. Es initialisiert den Zufallsgenerator, und das sollte nur einmal passieren.
Alles klein schreiben ist auch keine gute Idee, bei zusammengesetzten Befehlen weiß keiner was gemeint ist.
Und wenn du einen Wert zurückbekommen willst, dann kannst du auch eine Funktion verwenden. Die ist dafür gedacht.
Hier einmal mein Vorschlag: ;-)
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51:
| unit u_bedienung;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, u_bankomat, StdCtrls;
type TForm1 = class(TForm) Label1: TLabel; Label2: TLabel; Edit1: TEdit; Button1: TButton; Button2: TButton; GroupBox1: TGroupBox; ListBox1: TListBox; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure Button1Click(Sender: TObject); private Banko: TBankomat; public end;
var Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject); begin Label1.Caption := FloatToStr(Banko.GetKontostand()); end;
procedure TForm1.FormCreate(Sender: TObject); begin Randomize; Banko := TBankomat.Create; end;
procedure TForm1.FormDestroy(Sender: TObject); begin Banko.Free; end;
end. |
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27:
| unit u_Bankomat;
interface
type TBankomat = class(TObject) public function GetKontostand: Single; end;
implementation
function TBankomat.GetKontostand: Single; begin Result := Random(200) + 100; end;
end. |
luxoar - So 18.01.09 17:02
Wow das macht ja richtig spaß hier etwas zu fragen. Mit so viel tollen Tipps hätte ich gar nicht gerechnet. Wirklich vielen vielen Dank dafür. :)
Delete - So 18.01.09 17:35
Wobei die meisten von
jaenicke angesprochenen "Fehler" eher Stilfragen sind :mrgreen:.
luxoar - So 18.01.09 17:52
Titel: Das ganze anders herum
So danke euch bin ich schon einen Schritt weiter.
Allerdings bekomme ich nun den umgekehrten Weg auch wieder nicht hin. :(
Ich möchte den Betrag aus edit1.text gerne in der u_bankomat benutzen. Allerdings bekomme ich den Wert nicht darüber. Wie kann man das am gescheitesten machen? Vielen dank schon einmal im Vorraus.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67:
| unit u_bedienung;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, u_bankomat, StdCtrls;
type tform1 = class(TForm) Label1: TLabel; Label2: TLabel; Edit1: TEdit; Button1: TButton; Button2: TButton; GroupBox1: TGroupBox; ListBox1: TListBox; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure einlesen(betrag:integer); procedure FormDestroy(Sender: TObject); private public end;
var form1: tform1; Bankomat: TBankomat; implementation
{$R *.dfm}
procedure tform1.Button1Click(Sender: TObject); var stand:single; begin Bankomat.getkontostand(stand); label1.caption:=floattostr(stand); end;
procedure tform1.Button2Click(Sender: TObject); var ks:single; betrag:integer; begin einlesen(betrag); Bankomat.konto_aendern(ks); label2.caption:=floattostr(ks); end;
procedure tform1.FormCreate(Sender: TObject); begin Bankomat:=TBankomat.create; Randomize; end;
procedure tform1.FormDestroy(Sender: TObject); begin Bankomat.free; end;
procedure tform1.einlesen(betrag: Integer); begin betrag:=strtoint(edit1.text); end; end. |
----------------------------------------------------------------------------------------------------------------------------
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34:
| unit u_Bankomat;
interface
type TBankomat = class (tobject) public procedure getkontostand(var stand:single); function init:single; procedure konto_aendern(var ks:single); end;
implementation
function TBankomat.init:single; begin init:=random(200)+100; end;
procedure TBankomat.getkontostand(var stand:single); begin stand:=init; end;
procedure TBankomat.konto_aendern(var ks: Single); var Betrag:integer; begin ks:=Betrag; end;
end. |
jaenicke - So 18.01.09 18:02
Überlege einmal was du machst: In einlesen weist du betrag einen Wert zu. Dieser ist aber kein variabler Wert, du änderst also nicht den Wert in Button2Click damit.
Es sollte auch eine entsprechende Warnung / Hinweis vom Compiler kommen, dass der an betrag zugewiesene Wert nie benutzt wird, oder?
Warum benutzt du denn keine Funktion? Schließlich willst du ja einen Wert zurückbekommen. ;-)
In konto_aendern dann überschreibst du den in ks übergebenene Wert mit dem (uninitialisierten) Wert der lokalen Variablen Betrag. Auch dort sollte eine Warnung kommen, nämlich dass Betrag nicht initialisiert wurde.
// EDIT:
Du müsstest den Kontostand schon irgendwo speichern. Im Moment benutzt du ja jedesmal einen anderen zufälligen Wert.
Delphi-Quelltext
1: 2: 3: 4: 5:
| TBankomat = ... private Kontostand: Single; public ... |
Delete - So 18.01.09 18:02
Der beste Weg (und auch im Sinne der OOP) für so etwas ist in meinen Augen die Verwendung von Properties mit entsprechenden Getter-/Settermethoden.
Beispiel:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22:
| type TMyClass = class private FBetrag: single; function GetBetrag: single; procedure SetBetrag(const value: single); public property Betrag: single read GetBetrag write SetBetrag; end; ... implementation
function TMyClass.GetBetrag: single; begin Result := FBetrag; end;
procedure TMyClass.SetBetrag(const value: single); begin FBetrag := value; end; |
Verwendung:
Delphi-Quelltext
1: 2: 3: 4: 5:
| procedure TForm1.Button1Click(Sender: TObject); begin if MyClass.Betrag < 6.5 then MyClass.Betrag := 10.5; end; |
Yogu - So 18.01.09 20:50
DeddyH:
Get- und
Set-Methoden braucht man nur, wenn mehr als eine einfache Wertzuweisung stattfinden soll. Ok, vielleicht muss die
set-Prozedur noch eine Aktualisierungsmethode aufrufen, aber der Getter wird wohl nicht mehr machen müssen, als den Wert zurückzuliefern.
Delete - So 18.01.09 21:24
Die Kommentare hast Du aber gelesen, oder?
Yogu - So 18.01.09 22:23
DeddyH hat folgendes geschrieben : |
| Die Kommentare hast Du aber gelesen, oder? |
Ja, hab ich. Ich wollte nur noch ergänzen, dass Eigenschaften auch ohne Methoden möglich sind, da das in sehr vielen Fällen sinnvoller ist. Für Berechnungen etc. ist deine Variante natürlich unabdingbar.
Delete - So 18.01.09 22:26
Dann hatte ich Dich falsch verstanden. In meinem Minimalbeispielen könnte man natürlich über die Property direkt auf die private Variable zugreifen, das würde da keinen Unterschied machen, stimmt natürlich. Aber Getter- und Settermethoden sind durchaus sinnvoll einzusetzen, das wollte ich nur betonen.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!