Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Variable aus anderer Unit kann nicht richtig ausgelesen werd (https://www.delphipraxis.net/136436-variable-aus-anderer-unit-kann-nicht-richtig-ausgelesen-werd.html)

JBJHJM 30. Jun 2009 13:12


Variable aus anderer Unit kann nicht richtig ausgelesen werd
 
Tut mir ja Leid, aber alle schon bestehenden Themen haben mir nicht weitergeholfen.

Ziel: Ich will auf eine Variable einer anderen Unit zugreifen, der Einfachheit halber erstmal mit showmessage(Form1.variable).
Problem: Der genannte Befehl erzeugt einfach nur eine leere Meldung.

Die auszulesende Variable hat bereits einen Wert erhalten, im Editor wird kein Verbindungsproblem gezeigt, also die Variable scheint korrekt deklariert zu sein. Eine Fehlermeldung kommt auch nicht, weder beim compilieren, noch beim ausführen des Befehls.

Was habe ich übersehen?!?


ERGÄNZUNG:
Habe es bis jetzt nur mit Strings ausprobiert. Jetzt auch mit Integer, zeigt einfach nur 0 an.
Also scheinen die Strings geleert zu werden. Wie kann ich bestimmen, dass diese bis zum schließen des Programms dauerhaft zugewiesen bleiben, statt geleert zu werden.

Die Muhkuh 30. Jun 2009 13:14

Re: schon wieder ein Problem mit globale Variablen...
 
Zitat:

Zitat von JBJHJM
Was habe ich übersehen?!?

Uns den Code zu zeigen ;)

Bernhard Geyer 30. Jun 2009 13:20

Re: schon wieder ein Problem mit globale Variablen...
 
Zitat:

Zitat von JBJHJM
Ziel: Ich will auf eine Variable einer anderen Unit zugreifen, der Einfachheit halber erstmal mit showmessage(Form1.variable).
Problem: Der genannte Befehl erzeugt einfach nur eine leere Meldung.

Bist du sicher das dein Formular auf das du zugreifen willst wirklich hinter der Variable "Form1" steckt?

Sharky 30. Jun 2009 13:30

Re: schon wieder ein Problem mit globale Variablen...
 
Zitat:

Zitat von JBJHJM
...Was habe ich übersehen?!? ...

Deinem Thread eine aussagekräftigen Titel zu geben der etwas mit der Frage zu tun hat ;-)

Bitte - Danke

jaenicke 30. Jun 2009 13:33

Re: schon wieder ein Problem mit globale Variablen...
 
Jedenfalls lass die globalen Variablen am besten weg und nimm den normalen Weg über Eigenschaften oder Felder der Formulare, dann gibt es da auch keine Probleme.

Popov 30. Jun 2009 13:36

Re: schon wieder ein Problem mit globale Variablen...
 
Zuerst die zweite Unit mit der globalen Variable. Der einfachheitshalber habe ich sie bereits in der initialization (also beim Programmstart) zugewiesen. Du kannst es auch anders machen.

Delphi-Quellcode:
unit Unit2;

interface

var
  GlobaleVariable: String;

implementation

initialization
  GlobaleVariable := 'Hallo Welt!';

end.
Wichtig in Unit2: die globale Variable muß im interface-Teil deklariert sein, nicht in implementation.

Nun die Unit1:
Delphi-Quellcode:
implementation

{$R *.dfm}

uses
  Unit2;

procedure TForm1.Button1Click(Sender: TObject);
begin
  ShowMessage(GlobaleVariable);
end;
Nicht vergessen die Unit2 unter uses einzutragen.

Natürlich kannst du auch aus Unit1 einen Wert zuweisen:

Delphi-Quellcode:
implementation

{$R *.dfm}

uses
  Unit2;

procedure TForm1.Button1Click(Sender: TObject);
begin
  ShowMessage(GlobaleVariable);

  GlobaleVariable := 'Nun die Fortsetzung: Hallo Welt 2.0!';

  ShowMessage(GlobaleVariable);
end;

Die Muhkuh 30. Jun 2009 13:41

Re: schon wieder ein Problem mit globale Variablen...
 
Zitat:

Zitat von jaenicke
Jedenfalls lass die globalen Variablen am besten weg und nimm den normalen Weg über Eigenschaften oder Felder der Formulare, dann gibt es da auch keine Probleme.

Wenn Du richtig gelesen hättest, versucht er mit Form1.Variable drauf zu zu greifen, also scheint es sich nicht um eine globale Variable im klassischen Sinn zu halten.

jaenicke 30. Jun 2009 13:42

Re: schon wieder ein Problem mit globale Variablen...
 
Das habe ich für einen Schreibfehler gehalten, wenn er globale Variable sagt. ;-)

DeddyH 30. Jun 2009 13:43

Re: schon wieder ein Problem mit globale Variablen...
 
Ohne Codeschnippsel tappen wir hier nur im Dunkeln :glaskugel:

R2009 30. Jun 2009 13:49

Re: schon wieder ein Problem mit globale Variablen...
 
Hi,

wieder einmal! Zum xten Mal:
Es gibt unter Delphi keine "globalen Variablen". Es gibt nur "Unit-globale" Variablen.
Das fatale daran ist: Der Variablenname kann in einer anderen Unit nochmal vorkommen.
Es hängt dann nur von der Reihenfolge in der Uses Zeile ab welche Variable du wo erreichst.
Also FINGER WEG!
Besser ist es eine Variable in eine Klasse zu verpacken!

Beispiel:
Delphi-Quellcode:
Unit1
Interface
var1:integer;

Unit2
Interface
var1:integer;

Unit3
uses unit1,unit2;

var1 kriegst du jetzt von unit1

Unit3
uses unit2,unit1;

var1 kriegst du jetzt von unit2
Viele Grüsse

Popov 30. Jun 2009 14:31

Re: schon wieder ein Problem mit globale Variablen...
 
Zitat:

Zitat von JBJHJM
Ziel: Ich will auf eine Variable einer anderen Unit zugreifen, der Einfachheit halber erstmal mit showmessage(Form1.variable).
Problem: Der genannte Befehl erzeugt einfach nur eine leere Meldung.

Da du mit Form1.variable kommst und man deshalb nicht weiß wo du deine Variable deklariert hast, hier ein kleines 1 x 1 der Variablen. Ich habe 10 Variablen in verschiedenen Bereichen deklariert. Fünf in Unit2, fünf in Unit1. Je nachdem von wo man sie abrufen will, klappt es entweder nicht oder man muß etwas beachten. Zuerst Unit1 mit der Abfrage, dann Unit2:

Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
    Variable1a: String;
  public
    { Public-Deklarationen }
    Variable2a: String;
  end;


var
  Form1: TForm1;
  Variable3a: String;

implementation

{$R *.dfm}

uses
  Unit2;

var
  Variable4a: String;

procedure TForm1.FormCreate(Sender: TObject);
var
  Variable5a: String;
begin
  Variable1a := 'Hallo Welt 1 A!';
  Variable2a := 'Hallo Welt 2 A!';
  Variable3a := 'Hallo Welt 3 A!';
  Variable4a := 'Hallo Welt 4 A!';
  Variable5a := 'Hallo Welt 5 A!';
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Variable6a: String;
begin
  Variable6a := 'Hallo Welt 6 A!';

  //## Fremde Unit ##
  //ShowMessage(Variable1b); //klappt nicht - privat und andere Unit
  //ShowMessage(Variable2b); //klappt so nicht, trotz public
    ShowMessage(Form2.Variable2b); //klappt, aber nur mit Form2 davor
  ShowMessage(Variable3b); //klappt, wenn Unit eingetragen. Globale Variable
  //ShowMessage(Variable4b); //klappt nicht, global nur innerhalb der eigenen Unit
  //ShowMessage(Variable5b); //klappt nicht, lokale Variable

  //## Eigene Unit ##
  ShowMessage(Variable1a); //klappt, so aber nur in Form1-Prozeduren
    ShowMessage(Form1.Variable1a); //in normalen Prozeduren Form1 davor setzten
  ShowMessage(Variable2a); //klappt, so aber nur in Form1-Prozeduren
    ShowMessage(Form1.Variable2a); //in normalen Prozeduren Form1 davor setzten
  ShowMessage(Variable3a); //klappt überall in der eigenen Unit und in fremden Units
  ShowMessage(Variable4a); //klappt überall in der eigenen Unit
  //ShowMessage(Variable5a); //klappt nicht in fremder Prozedur, lokale Variable
  ShowMessage(Variable6a); //klappt, lokale Variable
end;

procedure Test; // normale Prozedur
begin
  //## Fremde Unit ##
  //ShowMessage(Variable1b); //klappt nicht - privat und andere Unit
  //ShowMessage(Variable2b); //klappt so nicht, trotz public
    ShowMessage(Form2.Variable2b); //klappt, aber nur mit Form2 davor
  ShowMessage(Variable3b); //klappt, wenn Unit eingetragen. Globale Variable
  //ShowMessage(Variable4b); //klappt nicht, global nur innerhalb der eigenen Unit
  //ShowMessage(Variable5b); //klappt nicht, lokale Variable

  //## Eigene Unit ##
  //ShowMessage(Variable1a); //klappt nicht so...
    ShowMessage(Form1.Variable1a); //...in normalen Prozeduren Form1 davor setzten
  //ShowMessage(Variable2a); //klappt nicht so...
    ShowMessage(Form1.Variable2a); //in normalen Prozeduren Form1 davor setzten
  ShowMessage(Variable3a); //klappt überall in der eigenen Unit und in fremden Units
  ShowMessage(Variable4a); //klappt überall in der eigenen Unit
  //ShowMessage(Variable5a); //klappt nicht in fremder Prozedur, lokale Variable
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  Test;
end;

end.
Unit2

Delphi-Quellcode:
unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TForm2 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private-Deklarationen }
    Variable1b: String;
  public
    { Public-Deklarationen }
    Variable2b: String;
  end;

var
  Form2: TForm2;
  Variable3b: String;

implementation

{$R *.dfm}

var
  Variable4b: String;

procedure TForm2.FormCreate(Sender: TObject);
var
  Variable5b: String;
begin
  Variable1b := 'Hallo Welt 1 B!';
  Variable2b := 'Hallo Welt 2 B!';
  Variable3b := 'Hallo Welt 3 B!';
  Variable4b := 'Hallo Welt 4 B!';
end;

end.

Popov 30. Jun 2009 14:33

Re: schon wieder ein Problem mit globale Variablen...
 
Zitat:

Zitat von R2009
Es gibt unter Delphi keine "globalen Variablen". Es gibt nur "Unit-globale" Variablen.

Naja, man sagt es aber so.

Die Muhkuh 30. Jun 2009 14:49

Re: schon wieder ein Problem mit globale Variablen...
 
Anstatt hier alle ins Blaue hinein raten, wartet doch einfach, bis der TE sich wieder meldet?! :gruebel:

samso 30. Jun 2009 15:30

Re: schon wieder ein Problem mit globale Variablen...
 
Zitat:

R2009 hat folgendes geschrieben:
Es gibt unter Delphi keine "globalen Variablen". Es gibt nur "Unit-globale" Variablen.
Was ist z.B. "ExitCode" denn dann für eine Variable? Ich hatte das bisher immer so verstanden: "Eine Variable, die im ganzen Programm für alle Blöcke zur Verfügung steht, heißt globale Variable"

Tyrael Y. 30. Jun 2009 15:35

Re: schon wieder ein Problem mit globale Variablen...
 
Man braucht hier nicht über Wörter zu streiten global oder unit global - beide meinen das Selbe.

Selbstverständlich wird auch in Delphi auf globale Variablen zugegriffen. Wäre es ein Teufelswerk, wäre eine
Implementierung solch einer Variable gar nicht erst möglich.

Der Rat im eigenen Code keine globalen Variablen zu nutzen, sollte man trotzdem beherzigen.
Umso umfangreicher der Code wird umso gefährlicher wird die Benutzung solcher globalen Variablen.

JBJHJM 30. Jun 2009 16:55

Re: Variable aus anderer Unit kann nicht richtig ausgelesen
 
Ich habe oben noch mal etwas ergänzt, die Variable wird doch richtig ausgelesen, aber sie scheint einfach leer zu sein - obwohl sie vorher zugewiesen wurde.

@ Popov: Vielen Dank! Das solltest du vielleicht Mal allgemein irgendwo reinstellen, ist besser als die ganzen anderen Hilfe-Threads zu dem Thema.

Ich probiere nochmal eben was aus...

Ansonsten nehme ich mir mal ein paar von den Räten hier zu Herzen und verzichte auf "globale Variablen" - habe es halt so gelernt, stehe noch ziemlich am Anfang.

DeddyH 30. Jun 2009 17:18

Re: Variable aus anderer Unit kann nicht richtig ausgelesen
 
Wenn Du keine Dinge wie Referenzzählung brauchst, solltest Du wie bereits angesprochen lieber Properties verwenden. Das klingt kompliziert, ist aber im Grunde ganz einfach:
Delphi-Quellcode:
type
  TForm1 = class(TForm)
  ...
  private
    //eine private Variable vom gewünschten Datentyp definieren
    FVariable: Datentyp;
    ...
  public
    //und über eine Property indirekten Zugriff auf obige Variable gestatten
    property Variable: Datentyp read FVariable write FVariable;
    ...
  end;
Nun hat jede Instanz, die Du von Deiner Klasse anlegst, eine eigene Property "Variable" und kommt sich garantiert nicht mit anderen Instanzen ins Gehege. Außerdem kannst Du Properties auch ReadOnly/WriteOnly definieren oder über die sog. Getter- und Settermethoden z.B. Fehleingaben abfangen.

Popov 30. Jun 2009 17:37

Re: Variable aus anderer Unit kann nicht richtig ausgelesen
 
Zitat:

Zitat von JBJHJM
habe es halt so gelernt, stehe noch ziemlich am Anfang.

Ich kann mich daran erinnern wo ich mal mit VB Programmierern zu tun hatte und mir einige deren Programme angucken mußte. Dabei ist mir aufgefallen, daß es bei denen nicht unüblich war eine eigene Unit (in VB heißt das anders) nur für globale Variablen zu haben. Da waren Listen von zig Variablen die überall galten. Ich hab es zur Kenntnis genommen und dachte mir, daß es in VB so üblich ist.

JBJHJM 30. Jun 2009 18:43

Re: Variable aus anderer Unit kann nicht richtig ausgelesen
 
@ Popov - Ja, mein Lehrer hat das auch ganz selbstverständlich so erklärt...

@ DeddyH - Danke, ich probiers mal aus!

JBJHJM 1. Jul 2009 15:17

Re: Variable aus anderer Unit kann nicht richtig ausgelesen
 
Habe jetzt 'property' benutzt, aber das Problem besteht weiterhin. Wenn ich in der 2. Unit versuche "Instanz" auszulesen, findet er sie zwar, zeigt aber an, dass sie leer ist.

Habe noch zwei Fragen (mit den Fragezeichen im Quelltext markiert):
1. Muss ich die Variable hier deklarieren - ansonsten zeigt Delphi an, es gäbe keine Variable 'WichtigerString'.
2. Greife ich so richtig auf 'Instanz' zu?

3. Wieso funktioniert das nicht :roll: *nein Scherzfrage...*

Delphi-Quellcode:
unit ErsteUnit
type
  TForm1 = class(TForm)
 ...
  private
    WichtigerString: String;
  public
    property Instanz: string read WichtigerString write WichtigerString;
  end;

var
  Form1: TForm1;
  WichtigerString: string; // ?????????   1.
   
implementation
...
begin
  WichtigerString:= 'A1CW5d3f';
end.
Delphi-Quellcode:
unit ZweiteUnit;
...
type
  TForm2 = class(TForm)
 ...

var
    Form2: TForm2;

implementation

uses ErsteUnit;
...
begin
showmessage(form1.instanz); //????????   2.
end;

DeddyH 1. Jul 2009 15:30

Re: Variable aus anderer Unit kann nicht richtig ausgelesen
 
Zitat:

Delphi-Quellcode:
unit ErsteUnit
type
  TForm1 = class(TForm)
...
  private
    WichtigerString: String;
  public
    property Instanz: string read WichtigerString write WichtigerString;
  end;

var
  Form1: TForm1;
  //WichtigerString: string; Weg damit
   
implementation

procedure TForm1.FormCreate(Sender: TObject);
begin
  WichtigerString:= 'A1CW5d3f';
end;

Zugreifen kannst Du dann über Form1.Instanz. Wobei es sich eingebürgert hat, die privaten Variablen wie die Property zu nennen, nur mit einem "F" (für Feld) davor.

himitsu 1. Jul 2009 15:30

Re: Variable aus anderer Unit kann nicht richtig ausgelesen
 
Delphi-Quellcode:
type
  TForm1 = class(TForm)
  private
    WichtigerString: String;
  public
    property Instanz: string read WichtigerString write WichtigerString;
  end;

var
  Form1: TForm1;
  WichtigerString: string;

begin
  WichtigerString:= 'A1CW5d3f';
end.
Delphi-Quellcode:
showmessage(form1.instanz);
form1.instanz greift auf ErsteUnit.Form1.WichtigerString aka TForm1.WichtigerString zu, wärend
WichtigerString:='A1CW5d3f'; auf ErsteUnit.WichtigerString zugreift ...
es sind also unterschiedliche Variablen und demnach auch unterschiedliche Inhalte.

also ersrmal entferne eine der beiden Variablen.

1: entweder die in TForm1 entfernen, einen Getter/Setter für .Instanz erstellen und die globlae Variable auslesen/beschreiben

2: siehe mein Vorredner

oder 3: eine Klassen-Variable erstellen
Delphi-Quellcode:
unit ErsteUnit

type
  TForm1 = class(TForm)
...
  private
    class var WichtigerString: String;
  public
    class property Instanz: string read WichtigerString write WichtigerString;
  end;

var
  Form1: TForm1;
   
implementation
...
begin
  TForm1.WichtigerString:= 'A1CW5d3f';
end.

JBJHJM 1. Jul 2009 18:48

Re: Variable aus anderer Unit kann nicht richtig ausgelesen
 
Ok, habe jetzt Klassenvariablen verwendet, funktioniert.
Hätte mir doch bloss einer *z.B. mein Lehrer :shock: * den Unterschied zwischen Unit.Form1.variable und Unit.variable erklärt...

Vielen Dank, von meiner Seite wars das dann mit Fragen!

himitsu 1. Jul 2009 19:26

Re: Variable aus anderer Unit kann nicht richtig ausgelesen
 
Zitat:

Hätte mir doch bloss einer *z.B. mein Lehrer Shocked * den Unterschied zwischen Unit.Form1.variable und Unit.variable erklärt...
der Unterschied ist erstmal egal ... du hattest 2 Variablen mit dem selben Namen, also jede Variable hatte ihren eigenen Inhalt.


bei den Klassen-Variablen gibt es aber Einiges zu beachten
Delphi-Quellcode:
type
  TMyClass = class(...)
    abc: Integer;
    var def: Integer;
    class var xyz: Integer;
  end;

var a, b: TMyClass;
abc und def stellen erstmal grundsätzlich das Gleiche dar
> Variablen innerhalb einer Klasseninstanz (nur daß man innerhalb einer Klasse das VAR nicht unbedingt angeben muß)

xyz ist eine Variable innerhalb der Klasse (Achtung: nicht Klasseninstanz)

also
Delphi-Quellcode:
a.abc <> b.abc  {TMyClass.abc ist nicht möglich}

a.xyz = b.xyz = TMyClass.xyz
heißt also, xyz ist bei allen Instanzen einer Klasse genau das Selbe,
es ist also überall genau der gleiche Inhalt drin und man kann auch ohne eine vorhandene Instanz der Klasse drauf zugreifen.

Popov 1. Jul 2009 19:31

Re: Variable aus anderer Unit kann nicht richtig ausgelesen
 
JBJHJM, unabhängig davon ob globale Variablen nun schön sind oder nicht, das klappt auf jeden Fall:

Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  WichtigerString: string;

implementation

uses Unit2;

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  WichtigerString := 'A1CW5d3f';
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  // oder auch hier: WichtigerString := 'A1CW5d3f';
  Form2.ShowModal;
end;

end.
Delphi-Quellcode:
unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm2 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

uses
  Unit1;

procedure TForm2.Button1Click(Sender: TObject);
begin
  showmessage(WichtigerString);
end;

end.
Du kannst durchaus die zuletzt genannten Lösungen mit property nehmen - wenn du es willst - du kannst es aber auch normal wie oben lösen. Beides funktioniert.

DeddyH 1. Jul 2009 19:38

Re: Variable aus anderer Unit kann nicht richtig ausgelesen
 
Damit verzichtest Du allerdings auf die u.a. in #17 genannten Vorteile.

Popov 1. Jul 2009 19:40

Re: Variable aus anderer Unit kann nicht richtig ausgelesen
 
Zitat:

Zitat von JBJHJM
Hätte mir doch bloss einer *z.B. mein Lehrer :shock: * den Unterschied zwischen Unit.Form1.variable und Unit.variable erklärt...

Ist aber nicht unbedingt nötig, denn das eine ist das normale Pascal, das andere schon objektorientierte Programmierung.

Popov 1. Jul 2009 19:45

Re: Variable aus anderer Unit kann nicht richtig ausgelesen
 
Zitat:

Zitat von DeddyH
Damit verzichtest Du allerdings auf die u.a. in #17 genannten Vorteile.

Ich sag ja auch nicht, daß es schlecht oder Unsinn ist, sondern, daß bevor man bei a, b und c, zuerst b verstehen sollte bevor man sich c zuwendet.

DeddyH 1. Jul 2009 19:46

Re: Variable aus anderer Unit kann nicht richtig ausgelesen
 
Wir haben die Unterschiede ja nun lang und breit erläutert, der TE muss nur noch die für ihn beste Möglichkeit umsetzen ;)

JBJHJM 1. Jul 2009 21:02

Re: Variable aus anderer Unit kann nicht richtig ausgelesen
 
Naja hab mich etwas ungenau ausgedrückt - ich hätte sagen sollen "... dass es da überhaupt einen Unterschied gibt..."
Das erklärt doch einiges über das ich mich wunderte, und nicht wirklich eine Antwort bekam - naja halt ein normaler Informatiklehrer.


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:32 Uhr.

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