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 Wie zellsensitives Rechnen in StringGrid ? (https://www.delphipraxis.net/58891-wie-zellsensitives-rechnen-stringgrid.html)

EccoBravo 14. Dez 2005 10:53


Wie zellsensitives Rechnen in StringGrid ?
 
Hallo, da wär ich wieder, lange keine Frage mehr gestellt,

ich habe ein StringGrid und will in ihm rechnen wie in Excel.
Das StringGrid hat die Zellen a..z, wenn ich die Zellen a und b ändere soll die Zelle c berechnet werden, und wenn ich die Zelle c ändere sollen die Zellen a und b berechnet werden.
Nun meine Frage:
Wie teile ich dem StringGrid mit, daß es gerade die Zelle c war, die geändert wurde und die eine Neuberechnung auslösen soll (und nicht die Zellen a und b)?
Und wie bekommt die Zelle c mit, daß die Eingabe in sie fertig ist?

Danke

E. B.

Sharky 14. Dez 2005 11:07

Re: Wie zellsensitives Rechnen in StringGrid ?
 
Hai EccoBravo,

Du könntest im Delphi-Referenz durchsuchenOnGetEditText auswerten welche Zelle geändert wird und dann entsprechende deine Berechnungen machen.

EccoBravo 14. Dez 2005 11:54

Re: Wie zellsensitives Rechnen in StringGrid ?
 
Nun aber neues Problem

Soweit so gut,
aber unter OnGetEditText wird im StringGrid erst nach zweimaligem Drücken der EnterTaste das richtige ergebnis ausgerechnet.
Nach einmaligem Enter kommt keinErg oder sinnloses Erg.

Zur Illustration hier mein Code
Delphi-Quellcode:
function StrToFloate(wert:String):single;
begin
    if wert ='' then result :=0
    else result := StrToFloat(wert);
end;

procedure TForm1.SG1GetEditText(Sender: TObject; ACol,
  ARow: Integer; var Value: String);
begin
  if (aRow=1) then
  begin
      SG1.Cells[ACol,3]:= FloatToStr(StrToFloate(SG1.Cells[ACol,1])+StrToFloate(SG1.Cells[ACol,2]));
  end;
  if aRow=2 then
  begin
      SG1.Cells[ACol,3]:= FloatToStr(StrToFloate(SG1.Cells[ACol,1])+StrToFloate(SG1.Cells[ACol,2]));
  end;
  if aRow=3 then
  begin
      SG1.Cells[ACol,1]:= FloatToStr(StrToFloate(SG1.Cells[ACol,2])+StrToFloate(SG1.Cells[ACol,3]));
  end;
Danke

E. B.

ibp 14. Dez 2005 12:03

Re: Wie zellsensitives Rechnen in StringGrid ?
 
...sorry war ein denkfehler!

versuch es mal mit dem event onsettext!

EccoBravo 14. Dez 2005 14:04

Re: Wie zellsensitives Rechnen in StringGrid ?
 
Danke danke

AAbbeerrr

zu Ereignis OnGetEditText

man muß immer 2x Enter drücken bevor das richtige Ergebnis erscheint.
Die StringGridAnzeige hängt immer einen Schritt hinterher.
Gut ist, daß immer erst dann etwas passiert, wenn man die Entertaste drückt.

zu Ereignis OnSetEditText

gut daran ist, daß die StringGridAnzeige nicht mehr hinterher hängt.
Aber während des Editierens reagiert die StringGridAnzeige bei Drücken jedes einzelnen Zeichens.
Die Anzeige kann nicht warten, bis die Eingabe abgeschlossen ist.

Wie kommt man aus diesem Dilemma?

Danke

E. B.

Angel4585 14. Dez 2005 14:10

Re: Wie zellsensitives Rechnen in StringGrid ?
 
löse die Procedure doch manuell im OnKeyDown aus
(wenn Key = vk_Return)

MfG :angel:

EccoBravo 14. Dez 2005 15:04

Re: Wie zellsensitives Rechnen in StringGrid ?
 
Danke,

aber wie bringe ich dem Ereignis OnSetEditText das Ereignis vk_Return bei ?

Danke

E. B.

ibp 14. Dez 2005 15:10

Re: Wie zellsensitives Rechnen in StringGrid ?
 
Zitat:

Zitat von EccoBravo
...zu Ereignis OnSetEditText

gut daran ist, daß die StringGridAnzeige nicht mehr hinterher hängt.
Aber während des Editierens reagiert die StringGridAnzeige bei Drücken jedes einzelnen Zeichens.
Die Anzeige kann nicht warten, bis die Eingabe abgeschlossen ist.

ist denn das so schlimm?

ibp 14. Dez 2005 15:26

Re: Wie zellsensitives Rechnen in StringGrid ?
 
Zitat:

Zitat von EccoBravo
Danke,

aber wie bringe ich dem Ereignis OnSetEditText das Ereignis vk_Return bei ?

Danke

E. B.


da nicht aber in den onkey...ereignissen!

EccoBravo 14. Dez 2005 15:35

Re: Wie zellsensitives Rechnen in StringGrid ?
 
...und das da auch zellselektiv ?

EccoBravo 14. Dez 2005 15:54

Re: Wie zellsensitives Rechnen in StringGrid ?
 
ich habs

Trick 17 mit Selbstüberlistung.

? Es geht doch wohl nur OnKeyPressed oder OnSetEditText ?

Neiin, es geht ja beides.

siehe meinen Code:

Delphi-Quellcode:
var
  Form1: TForm1;
  Kai : Char;

implementation

{$R *.dfm}
function StrToFloate(wert:String):single;
begin
    if wert ='' then result :=0
    else result := StrToFloat(wert);
end;

procedure TForm1.SG1SetEditText(Sender: TObject; ACol, ARow: Integer;
  const Value: String);
var
    update:boolean;
begin
//
if Kai = #13 then
begin
  Case aRow of
  1: begin
        SG1.Cells[ACol,3]:= FloatToStr(StrToFloate(SG1.Cells[ACol,1])+StrToFloate(SG1.Cells[ACol,2]));
     end;

  2: begin
        SG1.Cells[ACol,3]:= FloatToStr(StrToFloate(SG1.Cells[ACol,1])+StrToFloate(SG1.Cells[ACol,2]));
     end;
  3: begin
        SG1.Cells[ACol,1]:= FloatToStr(StrToFloate(SG1.Cells[ACol,2])+StrToFloate(SG1.Cells[ACol,3]));
     end;
  end;
  end;
end;

procedure TForm1.SG1KeyPress(Sender: TObject; var Key: Char);
begin
 Kai := Key;
end;

end.
Das wars, Danke danke

E. B.

EccoBravo 15. Dez 2005 11:07

Re: Wie zellsensitives Rechnen in StringGrid ?
 
HiGi

Jetzt doch noch mal eine Frage zu meinem Trick "17"
(Eingabe mit OnKeyPressed und OnSetEditText in StringGrid steuern):

Zellselektives Ereignissteuern im StringGrid mit OnSetEditText
wird erst bei Key=#13 durch OnKeyPressed ausgelöst
- klassisches gewontes Arbeiten mit Tabellen
(siehe meinen Code oben)

setzt doch voraus, daß EreignisProcedure OnKeyPressed immer vor OnSetEditText ausgeführt wird.
Kann ich mich darauf verlassen, daß OnKeyPressed wirklich zuerst abgearbeitet wird?
(Dieses war bisher auch unbewußt der Grund, wieso ich mich an eine solche Ereignisstrukur nicht herangetraut habe)

Danke

E. B.

marabu 15. Dez 2005 12:00

Re: Wie zellsensitives Rechnen in StringGrid ?
 
Hallo Ecco,

ich will dich ja nicht aus dem Konzept bringen, aber ich würde anders vorgehen.

Ich lege mir eine Unit Global an:

Delphi-Quellcode:
unit Global;

interface

uses
  Messages;

const
  CM_RECALC = WM_USER;

type
  TCMRecalc = packed record
    Msg: Cardinal;
    iCol: integer;
    iRow: integer;
    Result: integer;
  end;

implementation

end.
Diese Unit binde ich in die Form-Unit mit dem StringGrid ein. Meine Form erhält dann noch einen private message handler:

Delphi-Quellcode:
private
  procedure CMRecalc(var msg: TCMRecalc); message CM_RECALC;
Und die Berechnung soll natürlich erst durchgeführt werden, wenn ich mit der Eingabe fertig bin:

Delphi-Quellcode:
procedure TCalcForm.SGSetEditText(Sender: TObject; ACol,
  ARow: Integer; const Value: String);
begin
  if not SG.EditorMode then
    PostMessage(Handle, CM_RECALC, ACol, ARow);
end;
Jetzt muss der message handler noch implementiert werden:

Delphi-Quellcode:
procedure TCalcForm.CMRecalc(var msg: TCMRecalc);
begin
  with msg do
  begin
    case iRow of
      1:
      begin
        SG.Cells[iCol, 3] := FloatToStr(StrToFloate(SG.Cells[iCol, 1])
          + StrToFloate(SG.Cells[iCol, 2]));
      end;
    end;
  end;
Den Code zum Berechnen des Zelleninhaltes habe ich von dir geklaut und verkürzt, nur um das Prinzip zu zeigen. Du wirst da noch einiges an safety code dazu geben müssen. Und wenn du wirklich wie in einem Spreadsheet rechnen möchtest, dann wirst du noch einen dependency tree aufbauen müssen nebst loop detection.

Freundliche Grüße vom marabu

EccoBravo 15. Dez 2005 12:39

Re: Wie zellsensitives Rechnen in StringGrid ?
 
Danke danke, ich werd's heute abend proobieren.

E. B.


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