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 Daten anzeigen in StringGrid und TEdit (https://www.delphipraxis.net/92688-daten-anzeigen-stringgrid-und-tedit.html)

LOMBI 24. Mai 2007 12:12


Daten anzeigen in StringGrid und TEdit
 
Hallo,

auf einer Form habe ich unter ein StringGrid einige TEdits platziert.
Zu einer markierten Adresse im Grid sollen darin weitere Informationen
z.B. die Tel-Nr. angezeigt werden. Diese Daten stehen bereits in der
DB.

Folgender Code hat leider nicht funktioniert:

Delphi-Quellcode:
 procedure TDemoForm.FormShow(Sender: TObject);
begin
  EdTelefon.Text := QueryAdr.FieldByName('Telefon').AsString;
end;
Vielen Dank für Hilfe!

Gruß
Lombi

Hansa 24. Mai 2007 12:29

Re: Daten anzeigen in StringGrid und TEdit
 
Das FormShow wird lediglich einmal aufgerufen. Und wohl sowieso zu früh. Baue die Zeile mal ins OnSelectCell des Grids rein.

Sharky 24. Mai 2007 12:59

Re: Daten anzeigen in StringGrid und TEdit
 
Zitat:

Zitat von LOMBI
....StringGrid einige TEdits platziert. ...

Hai Lombi,

wenn Du die Daten aus der Datenbank in ein StringGrid holst kommst Du mit dem Query auch nicht einfach so weiter.
Der Datensatz bleibt ja immer auf dem selben Datensatz der Tabelle stehen.

LOMBI 24. Mai 2007 13:59

Re: Daten anzeigen in StringGrid und TEdit
 
Delphi-Quellcode:
procedure TDemoForm.StringGridSelectCell(Sender: TObject; ACol, ARow: Integer;
  var CanSelect: Boolean);
begin
  QueryAdr.RecNo := StringGrid.Row;             // Codezeile ergänzt!
  EdTelefon.Text := QueryAdr.FieldByName('Telefon').AsString;
end;
Guter Vorschlag!

Eines stört aber:

Im Grid muß ich jetzt auf eine markierte Zeile doppelt klicken, damit die
passende Tel-Nr. im Edit erscheint.

Wie bitte kann ich das abstellen?

Sharky 25. Mai 2007 05:49

Re: Daten anzeigen in StringGrid und TEdit
 
Hai LOMBI,

dieses Verfahren hat einen großen Nachteil. Wenn Du die Daten im StringGrid umsortierst stimmen die Nummern der Zeilen nicht mehr mit den RecNo der Datensätze überein.

Ich speichere mir Zusatzinfos immer in der Delphi-Referenz durchsuchenObjects Eigenschaft.

Hier einmal ein Beispiel:
Delphi-Quellcode:
type
  TExtraData = class(TObject)
    FID: Integer;
    FTelefon: string;
  public
    property ID: Integer read FID write FID;
    property Telefonnummer: string read FTelefon write FTelefon;
  end;

procedure TDemo_Form.FormCreate(Sender: TObject);
var
  MyData: TExtraData;
  ndx: Integer;
begin
  for ndx := StringGrid1.FixedRows to StringGrid1.RowCount do
  begin
    MyData := TExtraData.Create; // Objekt erzeugen
    MyData.ID := ndx; // Objekt mit Daten füllen
    MyData.Telefonnummer := Format('Telefonnummer %d', [ndx]);
    StringGrid1.Cells[1, ndx] := Format('Zeile %d', [ndx]);
    StringGrid1.Objects[0, ndx] := MyData; // Das Objekt an eine Zeile des SG binden
  end;
end;

procedure TDemo_Form.FormDestroy(Sender: TObject);
var
  ndx: Integer;
begin
  // Beim beenden des Programmes den Speicher für die Objekte freigeben
  for ndx := StringGrid1.FixedRows to StringGrid1.RowCount do
  begin
    if Assigned(StringGrid1.Objects[0, ndx]) then
    begin
      StringGrid1.Objects[0, ndx].Free;
    end;
  end;
end;

procedure TDemo_Form.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer;
  var CanSelect: Boolean);
var
  MyData: TExtraData;
begin
  MyData := Pointer((Sender as TStringGrid).Objects[0, ARow]); // Objekt der Zeile auslesen
  Label1.Caption := MyData.Telefonnummer; // Daten anzeigen
  Label2.Caption := format('Datensatz-ID %D', [MyData.ID]);
end;

LOMBI 26. Mai 2007 12:15

Re: Daten anzeigen in StringGrid und TEdit
 
Hallo Sharky,

mit Deinem Code kommt es leider zu einer 'Zugriffsverletzung'!

scrat1979 28. Mai 2007 09:52

Re: Daten anzeigen in StringGrid und TEdit
 
Zitat:

Zitat von LOMBI
Hallo Sharky,

mit Deinem Code kommt es leider zu einer 'Zugriffsverletzung'!

An welcher STelle wird die Zugriffsverletzung ausgelöst?

SCRaT

LOMBI 29. Mai 2007 11:21

Re: Daten anzeigen in StringGrid und TEdit
 
Zugriffsverletzung bei:

Delphi-Quellcode:
EdTelefon.Text := MyData.Telefonnummer; // Daten anzeigen
Statt dem Label verwende ich ein TEdit!

Wozu wird übrigens nachstehende Codezeile benötigt? Die Datensatz-ID muß nicht sichtbar
gemacht werden.

Delphi-Quellcode:
Label2.Caption := format('Datensatz-ID %D', [MyData.ID]);

marabu 29. Mai 2007 12:05

Re: Daten anzeigen in StringGrid und TEdit
 
Hallo Lombi,

setze einfach einen Haltepunkt auf die fragliche Zeile und inspiziere mal die Variable MyData. Wenn diese nil ist, dann hast du den Auslöser für die Zugriffsverletzung gefunden und kannst gezielt nach der Ursache forschen.

Sharky konnte nicht wissen welche Felder du anzeigen möchtest und welche nicht. Lasse die Zeile mit der Zuweisung von ID an Label2 einfach weg.

Freundliche Grüße

scrat1979 29. Mai 2007 12:33

Re: Daten anzeigen in StringGrid und TEdit
 
Zitat:

Zitat von LOMBI

Wozu wird übrigens nachstehende Codezeile benötigt? Die Datensatz-ID muß nicht sichtbar
gemacht werden.

Delphi-Quellcode:
Label2.Caption := format('Datensatz-ID %D', [MyData.ID]);

Die Zeile ist die einfachere Lösung für folgenden Syntax (gleichwertig):

Delphi-Quellcode:
Label2.Caption := 'Datensatz-ID ' + IntToStr(MyData.ID);
Diese Schreibweise ist besonders hilfreich wenn viele Variablen mittels '+' zu einem String zusammengeführt werden sollen. Hier ist die "format"-Schreibweise wesentlich kürzer. Im Internet (google) gibts einige Seiten, in denen der format-Befehl gut beschrieben ist. Sollte man sich mal zu Gemüte führen wenn man es öfters brauchen könnte!


SCRaT

LOMBI 31. Mai 2007 14:33

Re: Daten anzeigen in StringGrid und TEdit
 
Ja, die Variable MyData ist nil.
Im Debug-Inspektor steht:
FTelefon : Nicht verfügbarer Wert
Aber das kann nicht sein, weil das Feld "Telefon" in der DB vorhanden ist!

Gruß
Lombi

DeddyH 31. Mai 2007 14:42

Re: Daten anzeigen in StringGrid und TEdit
 
Zitat:

Zitat von Sharky
Delphi-Quellcode:
for ndx := StringGrid1.FixedRows to StringGrid1.RowCount do

Muss es nicht heißen
Delphi-Quellcode:
for ndx := StringGrid1.FixedRows to StringGrid1.RowCount - 1 do
?

Sharky 31. Mai 2007 15:59

Re: Daten anzeigen in StringGrid und TEdit
 
Zitat:

Zitat von LOMBI
Ja, die Variable MyData ist nil.
Im Debug-Inspektor steht:
FTelefon : Nicht verfügbarer Wert
Aber das kann nicht sein, weil das Feld "Telefon" in der DB vorhanden ist!...

Hai LOMBI,

nur weil das Feld in der DB vorhanden ist bedeutet es ja noch nicht das Du die Zusatzdaten auch richtig an das StringGrid bindest.

Zeige doch einmal den Code mit dem Du das StringGrid mit Daten füllst.

Zitat:

Zitat von DeddyH
Muss es nicht heißenDelphi-Quellcode: markieren
for ndx := StringGrid1.FixedRows to StringGrid1.RowCount - 1 do

Eigentlich nicht. Warum sollte die letzte Zeile des StringGrids nicht berücksichtigt werden? :stupid:

shmia 31. Mai 2007 16:43

Re: Daten anzeigen in StringGrid und TEdit
 
Zitat:

Zitat von LOMBI
auf einer Form habe ich unter ein StringGrid einige TEdits platziert.
...Diese Daten stehen bereits in der DB

Warum dann nicht einfach ein TDBGrid und einige TDBEdits verwenden ?

DeddyH 31. Mai 2007 16:49

Re: Daten anzeigen in StringGrid und TEdit
 
Zitat:

Zitat von Sharky
Eigentlich nicht. Warum sollte die letzte Zeile des StringGrids nicht berücksichtigt werden?

Weil die letzte Zeile den Index RowCount - 1 hat? :stupid:

LOMBI 1. Jun 2007 09:28

Re: Daten anzeigen in StringGrid und TEdit
 
Guten Morgen

und danke für die rege Beteiligung!

Delphi-Quellcode:
procedure TDemoForm.FormCreate(Sender: TObject);
var
  MyData: TExtraData;
  ndx: Integer;
begin
  config := TMemIniFile.Create(ChangeFileExt(ParamStr(0), '.ini'));
...
  with StringGrid do
  begin
    if goRowSelect in Options
      then Row := Pred(RowCount)
      else Selection := TGridRect(Rect(FixedCols, Pred(RowCount), Pred(ColCount), Pred(RowCount)));
    if VisibleRowCount < (RowCount - FixedRows)
      then TopRow := Succ(RowCount - FixedRows - VisibleRowCount)
      else TopRow := FixedRows;
Natürlich wäre das Ganze mit DBGrid und DBEdits einfacher zu lösen, aber darauf möchte ich ungern
zurückgreifen.

Gruß
Lombi

Sharky 3. Jun 2007 05:53

Re: Daten anzeigen in StringGrid und TEdit
 
Hai LOMBI,

zeige doch einmal den Code in dem Du das StringGrid mit Daten füllst! In dem Codeausschnitt machst Du das ja nicht.

shmia 4. Jun 2007 10:41

Re: Daten anzeigen in StringGrid und TEdit
 
Zitat:

Zitat von LOMBI
Natürlich wäre das Ganze mit DBGrid und DBEdits einfacher zu lösen, aber darauf möchte ich ungern
zurückgreifen.

Warum einfach, wenn's auch kompliziert geht ??
Eine Grundregel des Extreme Programming lautet:
Es soll die einfachste Lösung, die genau das Gewünschte erreicht, angestrebt werden.

LOMBI 5. Jun 2007 11:24

Re: Daten anzeigen in StringGrid und TEdit
 
Delphi-Quellcode:
procedure TDemoForm.cmdItemAddExecute(Sender: TObject);
begin
  with DatModul, ItemDlg do
  begin
    ...
    if ShowModal = mrOK then
      begin
        QueryAdr.Append;
        QueryAdr.FieldByName('Name1').AsString := EdName1.Text;
        ...
        QueryAdr.Post;
        if QueryAdr.Locate('name1', EdName1.Text, []) then
          StringGrid.Row := QueryAdr.RecNo;
     end;

procedure TDemoForm.DataSetChanged(DataSet: TDataSet);
begin
  if DataSet.Active
    then StringGrid.RowCount := Max(Succ(DataSet.RecordCount), 2)
    else StringGrid.RowCount := 2;
         StringGrid.Invalidate;
end;

procedure TFDemoForm.DataSourceDemoDataChange(Sender: TObject; Field: TField);
begin
   if not Assigned(Field) then
     with Sender as TDataSource do
       if DataSet.Tag = 0 then
         DataSetChanged(DataSet);
end;

marabu 5. Jun 2007 20:19

Re: Daten anzeigen in StringGrid und TEdit
 
Hallo Lombi,

Zitat:

Zitat von LOMBI
... Im Grid muß ich jetzt auf eine markierte Zeile doppelt klicken, damit die passende Tel-Nr. im Edit erscheint. ...

dieses Verhalten kann ich in meinem Test-Projekt nicht beobachten. Es könnte sich um einen Nebeneffekt deines Codes handeln. Da müsste man genauer hinschauen. Hilfreich wäre, wenn du ein lauffähiges Minimal-Projekt zur Verfügung stellen könntest, an dem das Verhalten studiert werden kann.

Freundliche Grüße

LOMBI 6. Jun 2007 09:41

Re: Daten anzeigen in StringGrid und TEdit
 
Guten Morgen marabu,

in Beitrag #4 hatte ich nachträglich meinen Code ergänzt und damit war das Doppelklicken auf
eine Gridzeile weg:

Delphi-Quellcode:
...
QueryAdr.RecNo := StringGrid.Row;             // Codezeile ergänzt!
...
Sharky hat mir darauf im Beitrag #5 geantwortet:

Zitat:

dieses Verfahren hat einen großen Nachteil. Wenn Du die Daten im StringGrid umsortierst stimmen die Nummern der Zeilen nicht mehr mit den RecNo der Datensätze überein.
Ist evtl. der Code von Sharky gar nicht notwendig?

Gruß
Lombi

marabu 6. Jun 2007 12:09

Re: Daten anzeigen in StringGrid und TEdit
 
Hallo Lombi,

Zitat:

Zitat von LOMBI
... Ist evtl. der Code von Sharky gar nicht notwendig? ...

"notwendig" heißt bei mir "es geht nicht ohne" - in diesem Sinne ist Sharkys Ansatz sicher nicht notwendig. Er wollte dir zeigen, wie du die direkte Kopplung von StringGrid.Row und Query.RecNo aufheben kannst. Nur für den Fall, dass du im Grid eine rein lokale Sortierung durchführen möchtest.

Alternativ kannst du die Sortierung natürlich immer über SELECT ... ORDER BY erreichen. Dabei wird die Sortierung über LocalSQL erledigt, immer noch clientseitig, aber immerhin nicht durch deinen eigenen Code - und später vielleicht auf einem SQL Server.

Willst du unbedingt in deiner Anwendung sortieren, dann kommt auch eine Entkopplung über einen Sortierindex (TIntegerDynArray) in Frage. Dann aber besser mit einem virtuellen Grid (dabei werden die Zellenwerte über OnDrawCell direkt aus den Datenpuffern geholt).

Freundliche Grüße

LOMBI 8. Jun 2007 18:08

Re: Daten anzeigen in StringGrid und TEdit
 
Danke marabu für Deine Hilfe!

Nach dem Start der Anwendung ist im Grid stets die letzte Zeile markiert und dazu im TEdit darunter
die Telefon-Nr. des ersten Datensatzes. Erst danach korrelieren die markierten Datensätze mit den
jeweiligen Telefon-Nr.

marabu 8. Jun 2007 18:32

Re: Daten anzeigen in StringGrid und TEdit
 
Hallo Lombi,

du kannst das Ereignis OnSelectCell(), dessen Handler die Edit-Felder aktualisiert, auch per Code (vielleicht beim Ereignis OnShow der Form?) auslösen und musst nicht auf die erste Bedieneraktion warten, damit die Feldinhalte synchronisiert werden.

Freundliche Grüße

LOMBI 9. Jun 2007 10:51

Re: Daten anzeigen in StringGrid und TEdit
 
Hallo marabu,

Dein Tipp war (wie immer) goldrichtig!

Herzliche Grüße
Lombi


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:04 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz