Autor Beitrag
luxoar
Hält's aus hier
Beiträge: 6



BeitragVerfasst: 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 :)

ausblenden volle Höhe 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
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  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.
ausblenden 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 user profile iconNarses: Delphi-Tags hinzugefügt
DeddyH
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: So 18.01.09 13:51 
Du hast die Variable stand ja auch nirgends deklariert. Versuch es mal so:
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2598
Erhaltene Danke: 156

Ubuntu 13.04, Win 7
C# (VS 2013)
BeitragVerfasst: 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 user defined image, 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 user profile iconDeddyH schon schrieb.

Grüße,
Yogu
luxoar Threadstarter
Hält's aus hier
Beiträge: 6



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19345
Erhaltene Danke: 1753

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 18.01.09 15:13 
Du machst mehrere Fehler.
ausblenden 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: ;-)
ausblenden volle Höhe 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); // Das musst du natürlich auch bei OnDestroy eintragen
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
    Banko: TBankomat;
  public
    { Public-Deklarationen }
  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.
ausblenden 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
    // constructor Create;
    function GetKontostand: Single;
  end;


implementation

// Wenn der Konstruktor leer ist, wird er auch erst einmal nicht gebraucht
//constructor TBankomat.Create;
//begin
//  inherited Create;
//end;

function TBankomat.GetKontostand: Single;
begin
  // Randomize; // Das sollte nur einmal in FormCreate z.B. stehen
  Result := Random(200) + 100;
end;

end.
luxoar Threadstarter
Hält's aus hier
Beiträge: 6



BeitragVerfasst: 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



BeitragVerfasst: So 18.01.09 17:35 
Wobei die meisten von user profile iconjaenicke angesprochenen "Fehler" eher Stilfragen sind :mrgreen:.
luxoar Threadstarter
Hält's aus hier
Beiträge: 6



BeitragVerfasst: 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.

ausblenden volle Höhe 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
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  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); //--> den Betrag in u_bankomat in der Prozedur bankomat.konto_aendern(ks) verwenden
end;
end.


----------------------------------------------------------------------------------------------------------------------------
ausblenden volle Höhe 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; //hier kommt er nicht an
end;

end.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19345
Erhaltene Danke: 1753

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: 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.
ausblenden 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



BeitragVerfasst: 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:
ausblenden 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
  //einfache Variante, könnte auch das Ergebnis einer Berechnung sein
  Result := FBetrag; 
end;

procedure TMyClass.SetBetrag(const value: single);
begin
  //wieder die einfache Variante, man könnte auch zunächst value abprüfen und ggf. verwerfen
  FBetrag := value;
end;

Verwendung:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
procedure TForm1.Button1Click(Sender: TObject);
begin
  if MyClass.Betrag < 6.5 then //Abfrage des Getters
    MyClass.Betrag := 10.5//Aufruf des Setters
end;
Yogu
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2598
Erhaltene Danke: 156

Ubuntu 13.04, Win 7
C# (VS 2013)
BeitragVerfasst: So 18.01.09 20:50 
user profile iconDeddyH: 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



BeitragVerfasst: So 18.01.09 21:24 
Die Kommentare hast Du aber gelesen, oder?
Yogu
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2598
Erhaltene Danke: 156

Ubuntu 13.04, Win 7
C# (VS 2013)
BeitragVerfasst: So 18.01.09 22:23 
user profile iconDeddyH hat folgendes geschrieben Zum zitierten Posting springen:
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



BeitragVerfasst: 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.