Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Zellinhalt eines Stringgrid (https://www.delphipraxis.net/213483-zellinhalt-eines-stringgrid.html)

H.Bothur 4. Aug 2023 15:41

Delphi-Version: 5

Zellinhalt eines Stringgrid
 
Moin,

ich habe hier ein kleines Testprogramm - ein Stringgrid mit 5 Reihen und 3 Spalten und einem Button. Und immer wenn ich mit dem Cursur in eine andere Zelle gehe sollte mir die Zeile und Spalte und der Zellinhalt angezeigt werden.

Das klappt auch im ersten Moment mit CirsorDown, nur sobald ich wider CursorUp mache stimmen die angezeigten Daten nicht mehr.

Was stimmt da mit mir nicht ??

Hans

Delphi-Quellcode:
unit TestUnit;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Grids;

type
  TForm1 = class(TForm)
    StringGrid1: TStringGrid;
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer;
      var CanSelect: Boolean);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

var
  XPos,
  YPos: Integer;
  ZellInhalt: String;

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  StringGrid1.Cells[0,0]:='Spalte 1';
  StringGrid1.Cells[1,0]:='Spalte 2';
  StringGrid1.Cells[2,0]:='Spalte 3';

  StringGrid1.Cells[0, 1] := 'Apfel';
  StringGrid1.Cells[1, 1] := 'Birne';
  StringGrid1.Cells[2, 1] := 'Pflaume';

  StringGrid1.Cells[0, 2] := 'Erbse';
  StringGrid1.Cells[1, 2] := 'Wurzeln';
  StringGrid1.Cells[2, 2] := 'Kartoffel';

  StringGrid1.Cells[0, 3] := 'Fleisch';
  StringGrid1.Cells[1, 3] := 'Fisch';
  StringGrid1.Cells[2, 3] := 'Wild';

  StringGrid1.Cells[0, 4] := 'Vorspeise';
  StringGrid1.Cells[1, 4] := 'Hauptspeise';
  StringGrid1.Cells[2, 4] := 'Nachtisch';
end;

procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean);
begin
  YPos := StringGrid1.Row +1; {+1 wegen der FixedRow}
  XPos := StringGrid1.Col;
  ZellInhalt := StringGrid1.Cells[XPos, YPos];
  Button1.Caption := IntToStr(YPos) + ' / ' +IntToStr(XPos) + ' / ' +ZellInhalt;
  Button1.Refresh;
end;

end.

Rolf Frei 4. Aug 2023 16:02

AW: Zellinhalt eines Stringgrid
 
So sollte es doch gehen oder nicht?

Delphi-Quellcode:
procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean);
begin
  YPos := ARow;
  XPos := ACol;
  ZellInhalt := StringGrid1.Cells[XPos, YPos];
  Button1.Caption := IntToStr(YPos) + ' / ' +IntToStr(XPos) + ' / ' +ZellInhalt;
  Button1.Refresh;
end;

H.Bothur 4. Aug 2023 16:55

AW: Zellinhalt eines Stringgrid
 
Zitat:

Zitat von Rolf Frei (Beitrag 1525302)
So sollte es doch gehen oder nicht?

Delphi-Quellcode:
procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean);
begin
  YPos := ARow;
  XPos := ACol;
  ZellInhalt := StringGrid1.Cells[XPos, YPos];
  Button1.Caption := IntToStr(YPos) + ' / ' +IntToStr(XPos) + ' / ' +ZellInhalt;
  Button1.Refresh;
end;

Danke - ich bin gerade unterwegs und teste das morgen mal.

Gruss
Hans

himitsu 4. Aug 2023 17:21

AW: Zellinhalt eines Stringgrid
 
Ja, wenn man schon die "richtigen" Werte als Parameter rein bekommt, dann könnte man sie auch benutzen,
vor allem, da OnSelectCell bestimmt vor der Select-Änderung aufgerufen wird (drum ist es hier auch möglich das noch zu verbieten
Delphi-Quellcode:
CanSelect := False;
)
und daher die Grid-Property noch die alten Werte haben dürften.

Zitat:

Delphi-Quellcode:
{+1 wegen der FixedRow}

Warum dann nicht direkt
Delphi-Quellcode:
... + StringGrid1.FixedRows;
und schon braucht es keinen unnötigen Kommentar mehr. :zwinker:

Wenn ich das FormCreate sehe und dort nichts im Code zu finden ist ... Im Designer wurde die Größe des Grids aber schon eingestellt?

PS: Für die globalen Variablen sollte jemand mindestens gevierteilt werden.


Info:
Delphi-Quellcode:
procedure TForm4.FormCreate(Sender: TObject);
begin
  for var i := StringGrid1.RowCount - 1 downto 0 do StringGrid1.Rows[i].StrictDelimiter := True; // wirst schon sehn was passiert, wenn du diese Zeile weg lässt (schade, dass Emba das nicht RICHTIG repariert hatte)
  StringGrid1.Rows[0].CommaText := 'Spalte 1,Spalte 2,Spalte 3';
  StringGrid1.Rows[1].CommaText := 'Apfel,Birne,Pflaume';
  ...
end;
Abgesehn von dem kleinen Delphi-Bug,
gibt es manchmal auch unterschiedliche Lösungen.

H.Bothur 5. Aug 2023 11:06

AW: Zellinhalt eines Stringgrid
 
Zitat:

Zitat von Rolf Frei (Beitrag 1525302)
So sollte es doch gehen oder nicht?

Delphi-Quellcode:
procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean);
begin
  YPos := ARow;
  XPos := ACol;
  ZellInhalt := StringGrid1.Cells[XPos, YPos];
  Button1.Caption := IntToStr(YPos) + ' / ' +IntToStr(XPos) + ' / ' +ZellInhalt;
  Button1.Refresh;
end;

Danke - so passt es :-)

Gruss und schönes Wochenende
Hans

H.Bothur 5. Aug 2023 11:18

AW: Zellinhalt eines Stringgrid
 
Zitat:

Zitat von himitsu (Beitrag 1525308)
Ja, wenn man schon die "richtigen" Werte als Parameter rein bekommt, dann könnte man sie auch benutzen,
vor allem, da OnSelectCell bestimmt vor der Select-Änderung aufgerufen wird (drum ist es hier auch möglich das noch zu verbieten
Delphi-Quellcode:
CanSelect := False;
)
und daher die Grid-Property noch die alten Werte haben dürften.

Ja - wobei das irgendwie nicht das verhalten "meiner" ersten Lösung erklärt - denn das Ereignis ist ja das gleiche.

Zitat:

Warum dann nicht direkt
Delphi-Quellcode:
... + StringGrid1.FixedRows;
und schon braucht es keinen unnötigen Kommentar mehr. :zwinker:
Das kannte ich noch nicht :-)

Zitat:

Wenn ich das FormCreate sehe und dort nichts im Code zu finden ist ... Im Designer wurde die Größe des Grids aber schon eingestellt?
Ja klar - da war aber nur FixedRow, ColCount und RowCount eingestellt.

Zitat:

Delphi-Quellcode:
procedure TForm4.FormCreate(Sender: TObject);
begin
  for var i := StringGrid1.RowCount - 1 downto 0 do StringGrid1.Rows[i].StrictDelimiter := True; // wirst schon sehn was passiert, wenn du diese Zeile weg lässt (schade, dass Emba das nicht RICHTIG repariert hatte)
  StringGrid1.Rows[0].CommaText := 'Spalte 1,Spalte 2,Spalte 3';
  StringGrid1.Rows[1].CommaText := 'Apfel,Birne,Pflaume';
  ...
end;

Sehr viel eleganter - Danke. Ich hoffe ich denke das nächste Mal dran wenn ich es brauche. ;-)

Aber ... eine Frage noch aus Interesse:

Zitat:

Delphi-Quellcode:
procedure TForm4.FormCreate(Sender: TObject);
begin
  for var i := StringGrid1.RowCount - 1 downto 0 do

Ich sehe das Du nicht extra
Delphi-Quellcode:
var
  i: integer
schreibst sondern das "var" mitten in die Schleife. Das mag kürzer sein aber ist das nicht unübersichtlicher ?

Gruss
Hans

himitsu 5. Aug 2023 11:40

AW: Zellinhalt eines Stringgrid
 
Zitat:

Zitat von H.Bothur (Beitrag 1525325)
Ja - wobei das irgendwie nicht das verhalten "meiner" ersten Lösung erklärt - denn das Ereignis ist ja das gleiche.

Es ist die Erklärung für die Lösung von Rolf.
Nur dass dabei nicht noch sinnlos in die anderen globalen Variablen umkopiert wird.
Delphi-Quellcode:
procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean);
begin
  Button1.Caption := IntToStr(ARow) + ' / ' + IntToStr(ACol) + ' / ' + StringGrid1.Cells[ACol, ARow];
  Button1.Refresh;
end;
Natürlich gibt es für alles gefühlt 2 Milliarden Lösungen
Delphi-Quellcode:
Button1.Caption := ARow.ToString + ' / ' + ACol.ToString + ' / ' + StringGrid1.Cells[ACol, ARow];

Delphi-Quellcode:
Button1.Caption := Format('%d / %d / %s', [ARow, ACol, StringGrid1.Cells[ACol, ARow]);


Zitat:

Zitat von H.Bothur (Beitrag 1525325)
Das kannte ich noch nicht :-)

Wollte erst sagen, doch, weil du hast ja .....

Aber nee, das FixedRows steht bereits initial auf 1 und mußte somit doch nicht vorher einstestellt werden, z.B. auch im Objekt-Inspektor.

Zitat:

Zitat von H.Bothur (Beitrag 1525325)
Aber ... eine Frage noch aus Interesse:
...
schreibst sondern das "var" mitten in die Schleife. Das mag kürzer sein aber ist das nicht unübersichtlicher ?

Inline-Variablen gibt es seit wenigen Jahren. (letzte 4-5 Delphi-Versionen, oder so)

Nja, das kann man so oder so sehn.
Persönlich sehe ich das grade für FOR-Schleifen einfach nur als genial an.
Es sind schon zu viele auf die blöde Idee gekommen, auf eine FOR-Variable außerhalb/nach der FOR-Schleife zuzugreifen, was man definitiv nicht tun sollte, weil gibt Probleme ... und was so nun auch garnicht mehr möglich ist. :D
https://docwiki.embarcadero.com/RADS...line-Variablen
https://www.delphipraxis.net/204421-...variablen.html
...

PS: In seinem Profil kann man seine Delphi-Version angeben (siehe links unter den Namen),
bzw. hier in diesem Unterforum war das beim Erstellen des Threads/ErsterPost auch möglich.
(
Delphi-Quellcode:
Delphi-Version: 5
steht da jetzt bei dir, siehe ganz oben, aber das ist auch die Standardangabe, wenn jemand es vergisst)

Uwe Raabe 5. Aug 2023 12:11

AW: Zellinhalt eines Stringgrid
 
Zitat:

Zitat von H.Bothur (Beitrag 1525325)
Ja - wobei das irgendwie nicht das verhalten "meiner" ersten Lösung erklärt - denn das Ereignis ist ja das gleiche.

Das klappt nur dann, wenn du im Grid mit Pfeil-Ab in die darunter liegenden Zelle wechselst. In dem Fall ist nämlich deine Berechnung
Delphi-Quellcode:
  YPos := StringGrid1.Row +1; {+1 wegen der FixedRow}
  XPos := StringGrid1.Col;
korrekt, aber nicht wegen FixedRow, sondern einfach weil die neue Zelle unter der aktuellen liegt.

H.Bothur 5. Aug 2023 13:24

AW: Zellinhalt eines Stringgrid
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1525329)
Zitat:

Zitat von H.Bothur (Beitrag 1525325)
Ja - wobei das irgendwie nicht das verhalten "meiner" ersten Lösung erklärt - denn das Ereignis ist ja das gleiche.

Das klappt nur dann, wenn du im Grid mit Pfeil-Ab in die darunter liegenden Zelle wechselst. In dem Fall ist nämlich deine Berechnung
Delphi-Quellcode:
  YPos := StringGrid1.Row +1; {+1 wegen der FixedRow}
  XPos := StringGrid1.Col;
korrekt, aber nicht wegen FixedRow, sondern einfach weil die neue Zelle unter der aktuellen liegt.

Dann habe ich bei StringGrid.Row einfach was falsches erwartet - ich dachte das da immer die aktuelle Spalte drin steht - das was ich bei ARow rausbekomme. Aber was steht denn dann in Row ? Ich habe eben mal ein paar Minuten gesucht aber so auf die schnelle nichts dazu gefunden :-(

Gruss
Hans

himitsu 5. Aug 2023 13:27

AW: Zellinhalt eines Stringgrid
 
Ist es auch, inkl. der FixedRow.

Wie schon gesagt, kann es sein, dass beim Click mit Maus/Tastatur das Selected-Event schon vor dem Ändern aufgerufen wird und dann in diesen Property das Alte noch drin steht,
aber in den Parametern steht immer das Richtige.


Kannst auch einfach mal mit einem Timer testen, dann ist die interne Reihenfolge hierbei egal.
Delphi-Quellcode:
procedure TForm4.Timer1Timer(Sender: TObject);
begin
  Caption := StringGrid1.Row.ToString + ' ' + StringGrid1.Col.ToString;
end;



Delphi-Quellcode:
... + 1; {+1 wegen der FixedRow}

versus
Delphi-Quellcode:
... + StringGrid1.FixedRows;

bezog sich auch nur auf den Code selber,
nicht auf dessen Funktion, bezüglich diesem Fall hier.


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:16 Uhr.
Seite 1 von 2  1 2      

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