Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Variableninhalt ist "weg"
D. Annies - Mi 04.03.09 19:15
Titel: Variableninhalt ist "weg"
Hi, Delpher,
ich habe das folgende Problem:
In Form1 bestimme ich in einer Schleife die Größe eines Arrays.
In Form2 rufe ich diese Proc auf.
Der Wert von Anz_Kla ist dann aber leider 0 und nicht 34, wie vorher bestimmt.
CodeSchnipsel:
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:
| .......
Var Form1 : TForm1; Anz_Kla : integer; .....
procedure TForm1.machwas(sender:tobject); begin Anz_Kla := 0; setlength(Kla_Bez, Anz_Kla +1); Kla_Bez[Anz_Kla] := TbAusleihsatz.fieldbyname('KLASSE').asstring; setLength(Kla_Bez_Anz, Anz_Kla +1); QSchueler.first; while not QSchueler.eof do begin if (QSchueler.fieldbyname('KLASSE').asstring <> '') and (QSchueler.fieldbyname('KLASSE').asstring = Kla_Bez[Anz_Kla]) then inc(Kla_Bez_Anz[Anz_Kla]); QSchueler.next; end; showmessage(inttostr(Anz_Kla)); end;
.....
form1.machwas(self); showmessage(inttostr(Kla_Anz)); for n := 0 to Kla_Anz do ... |
Wer hat da eine Idee??
Danke, Detlef
Delete - Mi 04.03.09 19:24
Du änderst den Wert von Anz_Kla ja auch nirgends.
jaenicke - Mi 04.03.09 19:28
Doch, das schon, aber:
D. Annies hat folgendes geschrieben : |
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| Var Form1 : TForm1; Anz_Kla : integer; .....
procedure TForm1.machwas(sender:tobject); begin ... showmessage(inttostr(Anz_Kla)); end;
.....
form1.machwas(self); showmessage(inttostr(Kla_Anz)); for n := 0 to Kla_Anz do ... | |
War das jetzt ein Schreibfehler oder hast du tatsächlich eine zweite Variable Kla_Anz irgendwo...
Und zum Zugriff solltest du wenn dann Unit1.Anz_Kla benutzen, am besten deklarierst du die Variable aber in TForm1.
Delete - Mi 04.03.09 19:33
Das ist die einzige Zuweisung von Anz_Kla, die ich entdeckt habe, oder bin ich erblindet?
D. Annies - Mi 04.03.09 19:33
Hi, Sebastian,
leider tatsächlich ein Schreibfehler!
Im Code steht also auch in Form2 richtigerweise: showmessage(inttostr(Anz_Kla));
jaenicke - Mi 04.03.09 19:39
DeddyH hat folgendes geschrieben : |
Das ist die einzige Zuweisung von Anz_Kla, die ich entdeckt habe, oder bin ich erblindet? |
Stimmt, da habe ich gar nicht weiter nachgeschaut, ich hatte mich auf den Kommentar verlassen, dass das da richtig ausgegeben wird...
Delphi-Quelltext
1:
| showmessage(inttostr(Anz_Kla)); |
D. Annies - Mi 04.03.09 19:48
Hi, Deddy und Sebastian,
nein, keiner ist erblindet - mein Fehler, ich habe oben vergessen, eine Schleife anzugeben, aber diese Schleife wird durchlaufen, so dass Anz_Kla (!) den Wert 34 hat.
Delete - Mi 04.03.09 19:54
Dann zeig doch am Besten nochmal den ganzen Code. Unabhängig davon würde ich Dir aber trotzdem empfehlen, keine globale Variable, sondern ein Feld oder gleich eine Property von Form1 zu deklarieren.
D. Annies - Mi 04.03.09 20:08
Hi,
der Code:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22:
| procedure TForm1.machwas(sender:tobject); begin Anz_Kla := 0; setlength(Kla_Bez, Anz_Kla +1); TbAusleihsatz.first; while not eof(TbAusleihsatz do begin Kla_Bez[Anz_Kla] := TbAusleihsatz.fieldbyname('KLASSE').asstring; setLength(Kla_Bez_Anz, Anz_Kla +1); QSchueler.first; while not QSchueler.eof do begin if (QSchueler.fieldbyname('KLASSE').asstring <> '') and (QSchueler.fieldbyname('KLASSE').asstring = Kla_Bez[Anz_Kla]) then inc(Kla_Bez_Anz[Anz_Kla]); QSchueler.next; end; TbAusleihsatz.next; inc(Anz_Kla); end; showmessage('Form1: ' + inttostr(Anz_Kla)); end; |
man beachte die showmessage! Und wenn ich die Proc dann in Form2 aufrufe, steht da:
Form1: 0
Detlef :gruebel:
Delete - Mi 04.03.09 20:17
Da habe ich im Moment auch keine Erklärung dafür. Du hast nicht zufällig Anz_Kla noch einmal als lokale Variable definiert?
jaenicke - Mi 04.03.09 20:21
Deshalb sagte ich ja:
jaenicke hat folgendes geschrieben : |
| Und zum Zugriff solltest du wenn dann Unit1.Anz_Kla benutzen |
Dann lässt sich das ausschließen.
Trotzdem verursachen globale Variablen eben oft Unklarheiten, und in diesem Fall frage ich mich, warum das überhaupt nicht einfach eine Funktion ist...
Deren Rückgabewert könntest du dann direkt nutzen.
Ansonsten mach doch einfach was
DeddyH (und ich ganz oben) geschrieben hatte: Deklariere Anz_Kla innerhalb von TForm1, entweder als Feld oder als Property.
D. Annies - Mi 04.03.09 20:24
Ich danke euch beiden sehr, aber wie geht euer Vorschlag?
Danke für Erleuchtung, Detlef
Delete - Mi 04.03.09 20:30
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| type TForm1 = class(TForm) ... private FAnz: integer; ... public property Anzahl: integer read FAnz; end; |
jaenicke - Mi 04.03.09 20:31
Zunächst mal vorneweg:
Es ist in Delphi absolut nicht üblich Unterstriche für Bezeichner zu verwenden...
Halte dich besser an den Styleguide, dann ist der Code auch lesbarer.
http://dn.codegear.com/article/10280 (englisch)
http://www.delphi-treff.de/delphi-styleguide/ (deutsch)
Dann zum Thema:
Delphi-Quelltext
1: 2: 3: 4:
| TForm1 = class(TForm) public AnzKla: Integer; end; |
Innerhalb von Form1 immer nur AnzKla, außerhalb Form1.AnzKla zur Benutzung verwenden.
Oder eine richtige property:
Delphi-Quelltext
1: 2: 3: 4: 5: 6:
| TForm1 = class(TForm) private FAnzKla: Integer; public property AnzKla: Integer read FAnzKla write FAnzKla; end; |
Wobei man hier dann auch einen Setter schreiben kann, der statt das direkt an FAnzKla weiterzuleiten den Wert vorher prüft oder eine Aktion daraufhin durchführt, dass der Wert geändert wurde:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| TForm1 = class(TForm) private FAnzKla: Integer; procedure SetAnzKla(Value: Integer); public property AnzKla: Integer read FAnzKla write SetAnzKla; end;
...
procedure TForm1.SetAnzKla(Value: Integer); begin FAnzKla := Value; ShowMessage('Neuer Wert gesetzt!'); end; |
D. Annies - Mi 04.03.09 20:39
Danke, da hab ich was zum Nachdenken!
(Aufruf in Form2?)
Melde mich wieder, Gruß, Detlef
jaenicke - Mi 04.03.09 20:44
Außerhalb von TForm1 mit Form1.AnzKla, innerhalb von TForm1 entweder FAnzKla oder AnzKla, je nach Variante.
D. Annies - Do 05.03.09 18:25
Hi, Sebastian,
ich habe den Schnipsel "oder eine richtige Property" eingearbeitet, aber leider ist der Variableninhalt immer noch 0.
>Witzigerweise< funktionierte inc(AnzKla) nicht,ich musste Anzkla := anzkla + 1 schreiben. (nur so nebenbei)
Hängt es vielleicht irgendwie mit dem dynamischen Array zusammen??
Gruß, Detlef
Delete - Do 05.03.09 19:31
Kannst Du mal beide Units anhängen?
D. Annies - Do 05.03.09 20:51
Gute Idee, aber die Unit1 ist zu groß (ca 6000 Zeilen) - das kann ich keinem zumuten!
Nun, ich denke, das ist hier wohl ein Seiteneffekt, (nicht zum ersten Mal) da muss ich wohl wieder ein bisschen allein beißen - ich melde mich dann wieder.
Vielen Dank für deine (eure) Tipps,
Detlef :mrgreen: :lupe: :evil: :nixweiss: :hair: :eyecrazy: :les: :oops: :D
jaenicke - Do 05.03.09 21:12
D. Annies hat folgendes geschrieben : |
>Witzigerweise< funktionierte inc(AnzKla) nicht,ich musste Anzkla := anzkla + 1 schreiben. (nur so nebenbei)
Hängt es vielleicht irgendwie mit dem dynamischen Array zusammen?? |
Das hört sich dann allerdings wieder mal nach einem Speicherproblem an, ich glaube das Thema war bei dir schonmal gewesen, oder?
Denn Inc muss funktionieren, außer beim Debuggen, wo das schlicht eine Compileroptimierung sein kann, wenn es direkt bei der Auswertung in Delphi falsch angezeigt wird.
Zum Debuggen schalte am besten die Optimierung aus und die Bereichsprüfung an. ;-)
Delete - Do 05.03.09 21:16
Eine Integer-Property kann man nicht mit Inc erhöhen. Dazu müsste man direkt auf die private Variable zugreifen, da geht das dann wieder.
jaenicke - Do 05.03.09 21:21
Wenn AnzKla die Property ist, klar. Daran habe ich gar nicht mehr gedacht. Innerhalb der Klasse sollte man aber eher direkt auf die Variable (dann wohl FAnzKla?) zugreifen, weil die Property eigentlich Zugriffe von außen ggf. überwacht.
Delete - Do 05.03.09 21:24
Nur, sofern eine Setter-Methode implementiert wurde, ansonsten ist das Wumpe.
jaenicke - Do 05.03.09 22:09
Bis man einen Getter und Setter schreibt und sich über die seltsamen Ergebnisse in der Klasse wundert... :roll:
D. Annies - Fr 06.03.09 08:46
So, das Problem ist behoben, es war wohl ein Seiteneffekt, also ein Programmierfehler. Ich habe nur die Reihenfolge etwas verändert und jetzt geht es.
Also wohl kein Speicherleck (richtig, :zustimm: dass ich das schon mal hatte)
Nun ist meine Proggerwelt (erstmal) wieder in Ordnung ...
Danke für euer Interesse und eure Hilfe,
Detlef
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!