Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi StringGrid reihenweise füllen ? (https://www.delphipraxis.net/66656-stringgrid-reihenweise-fuellen.html)

RX3 2. Apr 2006 01:41


StringGrid reihenweise füllen ?
 
Hallo, ich habe folgendes Problem:

Ich versuche ein StringGrid reihenweise zu füllen, was ich mit 2 for-SChleifen realisieren möchte.
Klappt auch soweit ganz gut. ABER:
Wenn ich meinen Button klicke, wird die erste Zeile wunderbar gefüllt so wie es sein soll, aber beim nächsten Klick auf den Button kommt keine zweite Zeile.
Nun dachte ich in der For-SChleife wird ja nur die erste Anweisung ausgeführt wenn ich kein begin .. end da stehen habe, aber sobald ich begin .. end einsetze krieg ich folgenden Fehler:
[Fehler] Unithaupt.pas(102): Anweisung für FOR-Schleifenvariablen 'iRow'

So sieht mein Code bisher aus, is eigentlich ne Recht einfache Geschichte aber irgendwie bin ich doch mal wieder zu dumm dafür :-(
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var iCol,iRow : Integer;
    vPLanAnzahl : Integer;
begin
  Listbox1.Items.Add(EditName.Text + chr(vk_tab) + EditAlly.Text + chr(vk_Tab) + EditPlaneten.Text);
  vPlanAnzahl := StrToInt(EditPlaneten.Text);
  StringGrid1.ColCount := vPlanAnzahl + 1;
  StringGrid1.Cells[0,0] := 'Name';

  for iCol := 1 to StringGrid1.ColCount do
  StringGrid1.Cells[iCol,0] := 'Planet '+ IntToStr(iCol);
  inc(iCol);

  for iRow := 1 to StringGrid1.RowCount - 1 do
    for iCol:= 0 to StringGrid1.ColCount - 1 do
      StringGrid1.Cells[0,iRow] := EditName.Text + ' | ' + EditAlly.Text;
      inc(iRow);
//      StringGrid1.Row := StringGrid1.Row +1;
    StringGrid1.Cells[iCol,iRow]:= Edit5.Text;

end;

Hansa 2. Apr 2006 03:01

Re: StringGrid reihenweise füllen ?
 
Zitat:

Zitat von RX3
Delphi-Quellcode:
..
  for iCol := 1 to StringGrid1.ColCount do
  StringGrid1.Cells[iCol,0] := 'Planet '+ IntToStr(iCol);
  inc(iCol);

  for iRow := 1 to StringGrid1.RowCount - 1 do
    for iCol:= 0 to StringGrid1.ColCount - 1 do
      StringGrid1.Cells[0,iRow] := EditName.Text + ' | ' + EditAlly.Text;
      inc(iRow);
...

Als erstes sieht man mal nicht, wo (und ob überhaupt) RowCount erhöht wird. Folge : irgendwelche Fehler. :mrgreen: Das nächste ist das "Inc". Hättest Du stattdessen i := i + 1 geschrieben, dann würde so was eher auffallen. Ausnahme sind Nanosekunden-Testprogramme. Du veränderst die for-Variable innerhalb der Schleife und das ist meist tödlich. Dann wird noch einmal bei 0 und dann bei 1 in den FOR-Schleifen begonnen.

Hawkeye219 2. Apr 2006 09:31

Re: StringGrid reihenweise füllen ?
 
Hi RX3,

zu dumm bist Du sicher nicht, Du hast nur einige Dinge nicht beachtet.

1) Eine FOR-Schleife hat grundsätzlich nur eine abhängige Anweisung. Dies gilt übrigens auch für die WHILE-Schleife.
Benötigst Du mehrere abhängige Anweisungen, so muß Du diese mit BEGIN...END klammern.

2) Schreibzugriffe auf die Schleifenvariable sind im Anweisungsteil einer FOR-Schleife verboten (deshalb die Fehlermeldung des Compilers).
Das Inkrementieren/Dekrementieren der Schleifenvariable wird automatisch durchgeführt.

Der korrigierte Code sieht dann so aus:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var iCol,iRow : Integer;
    vPLanAnzahl : Integer;
begin
  Listbox1.Items.Add(EditName.Text + chr(vk_tab) + EditAlly.Text + chr(vk_Tab) + EditPlaneten.Text);
  vPlanAnzahl := StrToInt(EditPlaneten.Text);
  StringGrid1.ColCount := vPlanAnzahl + 1;
  StringGrid1.Cells[0,0] := 'Name';

  for iCol := 1 to StringGrid1.ColCount do
    StringGrid1.Cells[iCol,0] := 'Planet '+ IntToStr(iCol);

  for iRow := 1 to StringGrid1.RowCount - 1 do
  begin
    StringGrid1.Cells[0,iRow] := EditName.Text + ' | ' + EditAlly.Text;
    for iCol:= 0 to StringGrid1.ColCount - 1 do
      StringGrid1.Cells[iCol,iRow]:= Edit5.Text;
  end;
end;
Gruß Hawkeye

marabu 2. Apr 2006 09:55

Re: StringGrid reihenweise füllen ?
 
Guten Morgen, RX3.

Hawkeye hat ja schon einiges klar gestellt, aber funktionieren wird auch der korrigierte Code nicht - und selbst wenn man ihn so ändert, dass keine Laufzeitfehler auftreten, wird er wohl kein befriedigendes Ergebnis produzieren.

Die erste Zeile in deinem Code deutet darauf hin, dass du eine einzige neue Zeile hinzufügen willst. Der Rest deines Codes baut das StringGrid trotzdem immer wieder vollständig auf - aber nicht korrekt, da du für den Eintrag in der ersten Spalte stets die Informationen benutzt, die als letzte hinzugefügt wurden. Alle anderen Zellen füllst du mit dem gleichen Wert - Edit5.Text. Ob das sinnvoll ist?

Deine Spaltenüberschriften kannst du übrigens auch so eintragen:
Delphi-Quellcode:
  // Spaltenüberschriften eintragen
  with StringGrid1 do
    for iCol := 0 to ColCount - 1 do
      if iCol = 0
        then Cells[iCol, 0] := 'Name'
        else Cells[iCol, 0] := 'Planet '+ IntToStr(iCol);
Dabei habe ich auch gleich den Laufbereich deiner Variable iCol korrigiert - der höchste Wert ist ColCount - 1.

Grüße vom marabu

RX3 2. Apr 2006 10:54

Re: StringGrid reihenweise füllen ?
 
GUten Morgen zusammen,

1. Vielen Dank für Eure Hilfe!
2. @marabu, ich bin kein Profi und und habe nur sehr wenige Grundkenntnisse, hab zwar auch mit "with StringGrid1 do" probiert aber nich hingekriegt, deshalb danke erstmal für deine Lösung ;-)

3. Mein eigentliches Problem ist aber immernoch nicht gelöst!
Die erste Zeile wird (wie marabu richtigerweise sagte) immer mit den Spaltenüberschriften gefüllt, die zweite Zeile füllt sich dann mit dem Text der Editfelder, wenn ich die Editfelder jetz aber andere Namen eintrage und wieder den Button klicke, dann wird zwar eine weitere dritte Zeile unten angefügt mit den entsprechenden neuen Daten aus den Editfeldern, aber die komplette zweite Zeile erhält ebenfalls dieselben Werte wie Zeile 3...

Der aktuelle Code sieht nun so aus:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var iCol,iRow : Integer;
    vPLanAnzahl : Integer;
begin
  Listbox1.Items.Add(EditName.Text + chr(vk_tab) + EditAlly.Text + chr(vk_Tab) + EditPlaneten.Text);
  vPlanAnzahl := StrToInt(EditPlaneten.Text);
  StringGrid1.ColCount := vPlanAnzahl + 1;

// Spaltenüberschriften eintragen
  with StringGrid1 do
    for iCol := 0 to ColCount - 1 do
      if iCol = 0
        then Cells[iCol, 0] := 'Name'
        else Cells[iCol, 0] := 'Planet '+ IntToStr(iCol);

  for iRow := 1 to StringGrid1.RowCount - 1 do
  begin
    StringGrid1.Cells[0,iRow] := EditName.Text + ' | ' + EditAlly.Text;
    for iCol:= 1 to StringGrid1.ColCount - 1 do
      StringGrid1.Cells[iCol,iRow]:= Edit5.Text;
  end;
  StringGrid1.RowCount := StringGrid1.RowCount + 1;
end;

RX3 3. Apr 2006 20:31

Re: StringGrid reihenweise füllen ?
 
Hallo Leute ich habe zwar schon weitergemacht mit dem Programm aber mit dem StringGrid hab ich immernoch Probleme.
Ich kriegs immernoch nich hin dass jede Zeile enstprechend gefüllt wird. Würde mich über Hilfe freuen.


Ich beschreib mein Problem noch mal:

Ich habe diverse Editfelder, wenn ich nen Button klicke sollen alle Einträge der Editfelder ins StringGrid geschrieben werden und zwar in Zeile 1 (Zeile 0 sind schon die Überschriften der Spalten drin!)
die Editfelder sollen dann automatisch geleert werden und wenn ich neue Daten eingebe und denn Button erneut klicke sollen die neuen Daten in Zeile 2 geschrieben werden etc...

Bisher schreibt er zwar in jede nächste Zeile, aber die vorherigen Zeilen werden immer überschrieben mit dem aktuellen Text aus den Editfeldern ...

marabu 3. Apr 2006 21:49

Re: StringGrid reihenweise füllen ?
 
Hallo RX3,

wenn Button1 bei dir eine neue Zeile an das StringGrid anfügen soll, dann solltest du ihn vielleicht AppendButton nennen. Auch Form1 ist kein besonders sprechender Name, MainForm oder GridForm würden mir besser gefallen. Das soll dich auf die Tugend der Programmdokumentation durch geeignete Namensgebung hinweisen - mehr nicht.

Lass uns ein paar vorsichtige Änderungen an deinem Code vornehmen. Es ist sicher nicht nötig bei jedem Hinzufügen einer neuen Zeile die Spaltenüberschriften neu einzutragen. Vielleicht solltest du einen InitButton spendieren um das Grid einzustellen:

Delphi-Quellcode:
procedure TForm1.InitButtonClick(Sender: TObject);
var
  iCol: Integer;
begin
  // Spaltenüberschriften eintragen
  with StringGrid1 do
  begin
    Tag := 0;
    RowCount := 2;
    ColCount := StrToInt(EditPlaneten.Text) + 1;
    for iCol := 0 to ColCount - 1 do
      if iCol = 0
        then Cells[iCol, 0] := 'Name'
        else Cells[iCol, 0] := 'Planet '+ IntToStr(iCol);
  end;
end;

procedure TForm1.AppendButtonClick(Sender: TObject);
var
  iCol, iRow: Integer;
begin
  with StringGrid1 do
  begin
    Tag := Tag + 1; // Anzahl der Datenzeilen
    if Tag > 1 then
      RowCount := RowCount + 1;
    iRow := RowCount - 1;
    Cells[0, iRow] := EditName.Text + ' | ' + EditAlly.Text;
    for iCol := 1 to ColCount - 1 do
      Cells[iCol, iRow] := Edit5.Text;
  end;
end;
Ich habe den Code nicht getestet und hoffentlich nicht zuviele Fehler eingebaut, aber du solltest erkennen, wie das Hinzufügen einer einzelnen Zeile funktioniert.

Grüße vom marabu

RX3 5. Apr 2006 15:45

Re: StringGrid reihenweise füllen ?
 
Hi marabu, habe eben mal versucht deinen Code zu einzubauen und Delphi is beim Ausführen direkt abgeschmiert...

Was ich an deinem Code nicht verstehe:
Was ist "Tag"? Welche Funktion hat es? Zählt es die Anzahl der Bittonklicks und erhöht es bei jedem Klick um 1 ?

Wenn ich in der Hilfe nachgucke bringt mich das auch nich besonders weiter...
Zitat:

Beschreibung

Tag hat keine vordefinierte Bedeutung. Sie können in dieser Eigenschaft zusätzliche Informationen über die Komponente in Form einer Ganzzahl speichern oder die Eigenschaft in einen 32-Bit-Wert, wie z.B. in eine Komponentenreferenz oder einen Zeiger, umgewandelt werden.
Und Append- & InitButton hab ich bisher auch noch nie was von gehört? Gibts da nichts simpleres für n00bs? Es muss doch irgendwelchen stupiden primitiven Code geben der mir einfach das RowCount bei jedem Buttonklick um 1 erhöht und dann die nächste Zeile füllt !?


P.s:
Sorry dass ich immer erst so lange zum Antworten brauche aber ich bn zur Zeit auf Montage und versuche ab und zu mal ein wenig was mit Delphi zu machen um meine Kenntnisse aufzufrischen bzw zu ein wenig zu erweitern...

marabu 5. Apr 2006 18:32

Re: StringGrid reihenweise füllen ?
 
Hi RX3,

es ist tatsächlich so wie du vermutest - ich verwende das tag property vom StringGrid um mir die echte Anzahl der Datenzeilen zu merken. Das mache ich, weil ich bei einem leeren Grid mit einer Kopfzeile den RowCount auf 2 setzen möchte. Du kannst durch probeweises Setzen auf 1 im Object Inspector feststellen, warum ich das tun möchte. Also trage ich die erste Datenzeile in eine leere Gridzeile ein, für alle folgenden Datenzeilen muss ich aber erst eine neue Gridzeile hinzufügen. Das steuere ich über das tag property - andere Lösungen sind denkbar.

AppendButton und InitButton sind die von mir im Beispielcode gewählten Namen für zwei TButton-Komponenten.

Zitat:

Zitat von RX3
Es muss doch irgendwelchen stupiden primitiven Code geben der mir einfach das RowCount bei jedem Buttonklick um 1 erhöht und dann die nächste Zeile füllt !?

Der Beispielcode hat genau diese Eigenschaften - sobald du etwas mehr Erfahrung mit Delphi und der Programmierung hast, wirst du mir zustimmen.

Zitat:

Zitat von RX3
Sorry dass ich immer erst so lange zum Antworten brauche aber ich bn zur Zeit auf Montage und versuche ab und zu mal ein wenig was mit Delphi zu machen um meine Kenntnisse aufzufrischen bzw zu ein wenig zu erweitern...

Kein Problem von mir - du stellst die Fragen.

Freundliche Grüße vom marabu

RX3 13. Apr 2006 22:53

Re: StringGrid reihenweise füllen ?
 
Hi marabu, danke für deine Geduld und Hilfe, aber ich komme da leider immernoch nicht weiter und habe das jetzt erstmal ein wenig zurückgestellt und werde mich später wieder damit befassen.

Habe aber seit heute ein neues Problem...
http://www.delphipraxis.net/internal...577&highlight=


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:51 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