Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - List index out of bound (6)


FTT78 - Do 27.09.18 08:44
Titel: List index out of bound (6)
Hallo,
ich erzeuge zur Laufzeit 1 Button und 5 Groupboxen mit mehreren Labeln .
Alles funktionierte bis ich diese Procedure schrieb.
Der Fehler scheint in dieser Zeile auf zu treten

Delphi-Quelltext
1:
if form1.Controls[x].Name = 'Ziehung' then //Ist der Name der Gruppbox der Bereich wo geklickt wurde                    

Kann mir da jemand helfen?


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:
68:
69:
70:
Procedure Tform1.ZSTART(Sender: TObject);   //Ziehung starten
var zahl : integer;
    ziehung: array [1..6of integer;
    x: Integer;
    i : integer;
    zanzahl: Integer;
    gleichheit : integer;
    tklabel : TLabel;
    test : integer;
begin
randomize;
gleichheit := 0;
zanzahl := 1//Menge an zufallszahlen auf 0 setzen
for x := 1 to 6 do //alle arrays mit 0 füllen
begin
  ziehung[x]:=0//alle Arrays mit 0 füllen
end;

while zanzahl<6 do
begin
    zahl := trunc(random(48)+1);
  for x := 1 to 6 do
  begin
    if ziehung[x] = zahl then
    begin
      gleichheit := 1//wenn zufallszahl schon gezogen wurde gleicheit auf 1 setzen
    end;
  end;
  if gleichheit = 0 then //wenn gleicheit 0 ist
  begin
    ziehung[zanzahl] := zahl; //aktuelles Array mit zufallszahl füllen
    gleichheit := 0// gleicheit wieder auf 0 setzen
    zanzahl := zanzahl + 1//um 1 erhöhen, damit das nächste Array dran ist
    zahl := 0//auf 0 setzen
  end
  else // ansonsten alles auf 0 setzen und nächste zufallszahl erzeugen und durchlauf wiederholen
  begin
    gleichheit := 0;
    zahl := 0;
  end;
end;
//6 Zufallszahlen stehen nun im Array
//Panel in "gezogene Zahlen" mit den werten aus dem Array füllen
    test:=form1.ControlCount-1;
    showmessage(inttostr(test));
for x := 0 to form1.ControlCount-1 do //geht alle Elemente in der Form1 durch
zanzahl := 1;
begin
  if form1.Controls[x] is tgroupbox then // ist das Element ein Groubox
  begin
    if form1.Controls[x].Name = 'Ziehung' then //Ist der Name der Gruppbox der Bereich wo geklickt wurde
    begin

      for i := 0 to form1.Controls[x].ComponentCount-1 do // alle elemente der Groupbox durchgehen
      begin
        if form1.Controls[x].Components[i] is tlabel then //ist das Element ein Label
        begin
          tklabel := form1.Controls[x].Components[i] as tlabel;
        end;
        if tklabel.Name = 'gezzahl' + inttostr(zanzahl) then //ist der name des Labels richtig
        begin
          tklabel.caption := inttostr(ziehung[zanzahl]);
          zanzahl := zanzahl + 1;
        end;
            end;
          end;
    end;
  end;
  //showmessage(inttostr(zahl));
end;


Moderiert von user profile iconNarses: Code- durch Delphi-Tags ersetzt


Narses - Do 27.09.18 09:35

Moin und :welcome: in der EE!

Was machst du da eigentlich? :lupe: Ich gebe zu, dein Code ist für "mal schnell drüber kucken" etwas ... komplex. :les: :? Das sieht so nach Lottozahlen-Ziehung aus oder sowas... ? :nixweiss:

cu
Narses


jasocul - Do 27.09.18 09:38

Wäre gut gewesen, wenn du geschrieben hättest, welchen Fehler du hast.
Ups, steht in der Überschrift. Sorry :wink:

Mein Glaskugel sagt, dass der Fehler in den Zeilen 46 bis 48 ist.
Ich vermute, dass du die Zeilen 46 und 47 vertauschen musst.


FTT78 - Do 27.09.18 09:42

Ja das soll eine Lotto ziehung darstellen.
Ich habe seit 12 Jahren nicht mehr Delphi Programmiert, und das merke ich auch.
Siehe fehler. Ich hänge mal den Kompletten Code an.

Moderiert von user profile iconNarses: Komplettzitat des ersten Beitrags entfernt.


jasocul - Do 27.09.18 10:09

user profile iconFTT78 hat folgendes geschrieben Zum zitierten Posting springen:
Ich hänge mal den Kompletten Code an.

Nee, lass mal.
Dein Fehler ist nur ein Folge-Fehler aus meinem vermuteten Fehler.

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
//for x := 0 to form1.ControlCount-1 do //geht alle Elemente in der Form1 durch
for x := 0 to ControlCount-1 do //Innerhalb der Klasse nie(!) die Instanz-Variable verwenden!
begin // Das begin stand eine Zeile zu tief
  zanzahl := 1;
...
end;

Das List-Index out of bound kommt, weil die For-Schleife sich nicht auf das begin bezieht. Dadurch hat die Zähl-Variable (x) keinen definierten Wert mehr. Da sollte eigentlich auch vom Compiler eine Warnung oder ein Hinweis kommen.
Da du mit dem undefinierten Zustand auf den Index der Controlliste zugreifst, geht das in die Hose, weil x in deinem Fall 6 ist und es nicht so viele Controls gibt.
Im schlimmsten Fall hätte er auf irgendein Control zugegriffen und du hättest dich gewundert, warum du immer andere Werte bekommst, als du erwartet hättest.


FTT78 - Do 27.09.18 10:19

Wie kann ich das abändern?
In anderen proceduren funktioniert es ja auch.

Moderiert von user profile iconNarses: Komplettzitat des ersten Beitrags entfernt.


jasocul - Do 27.09.18 10:40

user profile iconFTT78 hat folgendes geschrieben Zum zitierten Posting springen:
Wie kann ich das abändern?

Indem du den Source so änderst, wie ich es beschrieben habe.
user profile iconFTT78 hat folgendes geschrieben Zum zitierten Posting springen:
In anderen proceduren funktioniert es ja auch.

Meinst du das mit der Instanz-Variablen?
Ja, das funktioniert ... aber nur solange, wie du nur diese eine Instanz hast. Sobald du eine zweite Instanz verwendest, bekommst du das reinste Chaos.
Man müsste jetzt auf die Grundlagen der Objekt-Orientierten Programmierung eingehen, damit klar wird, warum man das ein No-Go ist (auch, wenn es funktioniert). Dafür fehlt mir an dieser Stelle aber die Zeit.

Falls du das mit dem "for .. begin" meinst:
Sorry, aber das funktioniert auch in anderen Prozeduren nicht, wenn du es falsch machst.

[EDIT]
Habe deine Unit grob überarbeitet.


FTT78 - Do 27.09.18 17:19

Danke für die Hilfe.
Habe meinen Fehler gefunden.
Ich habe in der Groupbox nach Label gesucht, da sind aber keine. Ich habe nur Panel in der Groubox.
Alles schnell umgeschrieben und es funktioniert.

Danke nochmal.

Moderiert von user profile iconNarses: Komplettzitat des ersten Beitrags entfernt.


Delphi-Laie - Mo 01.10.18 12:34

user profile iconFTT78 hat folgendes geschrieben Zum zitierten Posting springen:
Ich habe seit 12 Jahren nicht mehr Delphi Programmiert, und das merke ich auch.


Och, Pascal ist wie Fahrradfahren, das verlernt man nicht. Schrieb mir ein emeritierter Informatikprofessor. Recht hat er!

Nichtdestoweniger halte auch ich Zeile 47 und 48 für vertauscht. Falls doch nicht, ist jedenfalls die Schleife


Delphi-Quelltext
1:
2:
for x := 0 to form1.ControlCount-1 do //geht alle Elemente in der Form1 durch
zanzahl := 1


Unsinn. Mehrmalige identische Wertzuweisung an dieselbe Variable, was auch ohne die Schleife davor nur einmal funktioniert.