| Autor |
Beitrag |
luxoar
Hält's aus hier
Beiträge: 6
|
Verfasst: So 18.01.09 13:43
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
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
|
|
DeddyH
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: 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
      
Beiträge: 2598
Erhaltene Danke: 156
Ubuntu 13.04, Win 7
C# (VS 2013)
|
Verfasst: 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 
Hält's aus hier
Beiträge: 6
|
Verfasst: 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
      
Beiträge: 19345
Erhaltene Danke: 1753
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: 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:  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 
Hält's aus hier
Beiträge: 6
|
Verfasst: 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. 
|
|
DeddyH
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: So 18.01.09 17:35
Wobei die meisten von jaenicke angesprochenen "Fehler" eher Stilfragen sind  .
|
|
luxoar 
Hält's aus hier
Beiträge: 6
|
Verfasst: 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.
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. |
----------------------------------------------------------------------------------------------------------------------------
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
      
Beiträge: 19345
Erhaltene Danke: 1753
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: 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 ... |
Zuletzt bearbeitet von jaenicke am So 18.01.09 18:05, insgesamt 3-mal bearbeitet
|
|
DeddyH
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: 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
      
Beiträge: 2598
Erhaltene Danke: 156
Ubuntu 13.04, Win 7
C# (VS 2013)
|
Verfasst: 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.
|
|
DeddyH
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: So 18.01.09 21:24
Die Kommentare hast Du aber gelesen, oder?
|
|
Yogu
      
Beiträge: 2598
Erhaltene Danke: 156
Ubuntu 13.04, Win 7
C# (VS 2013)
|
Verfasst: 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.
|
|
DeddyH
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: 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.
|
|