![]() |
Wertübergbae für einen Stringgrid
Hallo!
Ich bin Anfänger im Programmieren mit Delphi 2005 und bitte um Hilfe für ein Stringgrid Problem. Ich möchte die in einem Stringgrid1 erfassten 9 Messwerte einer Solarzelle für Spannung und Stromstärke erfassen. Diese sollen für die Berechnung der Leistung an einen Stringggrid2 übergeben werden. Als Problemmeldung kommt beim Probelauf: '"ist kein gültiger Gleitkommawert. Vielleicht weiß jemand Rat. Danke im voraus. Mein Quellcode sieht so aus: [delphi]procedure TForm1.Button4_Berechne_PClick(Sender: TObject); var j: smallInt;{Lauf-Variablen zum Berechnen} leistung: double; u,i: array [1..9] of double; begin for j:=1 to 9 do begin u[j]:=StrToFloat(StringGrid1.Cells[1,j]); i[j]:=StrToFloat(StringGrid1.Cells[2,j]); end; for j:=1 to 9 do with StringGrid2 do {Ausgabe der berechneten Leistung} begin Cells[0,j]:= FloatToStr(leistung); leistung:= u[j]* i[j]; end; end; |
Re: Wertübergbae für einen Stringgrid
Hallo Technikus :hi:,
IMHO liegt dein problem darin, dass du versuchst einen Leerstring in eine Fließkommazahl umzuwandeln(StrToFloat). Das funktioniert nicht. Ich nehme an in deinem StringGrid steht in einer Zenne nix und da versuchst du zu lesen. Setz mal n Breakpoint und steppe mit [F8] durch um die Zelle/die Variable zu finden. mfg Christian Nachtrag: Fast hätte ich es vergessen: Herzlich Willkommen in der DP! :dp: :bounce1: :coder: |
Re: Wertübergbae für einen Stringgrid
Hallo Technikus,
herzlich willkommen in der Delphi-PRAXiS. Du hast beim Zugriff auf Cells den Spalten- und ZeileIndex vertauscht. Und die Berechnung solltest du vor der Ausgabe erledigen.
Delphi-Quellcode:
Grüße vom marabu
procedure TForm1.CalcButtonClick(Sender: TObject);
var i: integer; // Laufvariable dLeistung: double; aVolt, aAmpere: array [1..9] of double; begin for i := 1 to 9 do begin aVolt[i] := StrToFloat(sgMesswerte.Cells[i, 1]); aAmpere[i] := StrToFloat(sgMesswerte.Cells[i, 2]); end; { Ausgabe der berechneten Leistung } for i := 1 to 9 do with sgErgebnisse do begin dLeistung := aVolt[i] * aAmpere[i]; Cells[i, 0]:= FloatToStr(dLeistung); end; end; end. |
Re: Wertübergbae für einen Stringgrid
Zitat:
Ich muss zugeben ich war zu faul mich durch den Code zu quälen. @Technikus: Zur besseren Lesbarkeit verwende nächstes Mal bitte auch einen abschließenden delphi-Tag. Is für mich zwar nur ne unzureichende Entschuldigung, dass ich mich nicht eingehender damit beschäftigt habe, aber besser als nix... :mrgreen: mfg Christian |
Re: Wertübergbae für einen Stringgrid
Hallo Christian, hallo marabu
Danke für die Willkommensgrüße und die Hilfe. Diesen Satz verstehe ich nicht. "Setz mal n Breakpoint und steppe mit [F8] durch um die Zelle/die Variable zu finden." Ich habe alle Zellen mit Zahlen gefüllt. Im Quelltext von marabu sind doch die Spalte und Zeile des Stringgrid vertauscht. Habe ich also probiert, funktioniert aber nicht. Im Buch steht geschrieben, dass im StringGrid die Spalte zuerst und dann die Zeile geschrieben wird. also StringGrid.Cells[spalte,zeile]; Die Berechnungsvorschrift habe ich vorgezogen. Gruß Technikus |
Re: Wertübergbae für einen Stringgrid
Zitat:
Delphi-Quellcode:
var
s: string; f: real; begin f:= StrToFloat('1.5'); // <-- kein gültiger Gleitkommawert -<<< f:= StrToFloat('1,5'); // <---<<< OK s:= FloatToStr(f); end; |
Re: Wertübergbae für einen Stringgrid
Halle turboPASCAL,
ich habe zur Probe nur ganze Zahlen eingesetzt und erhalte die Meldung "ist kein gültiger Gleitkommawert. Gruß Technikus |
Re: Wertübergbae für einen Stringgrid
Hallo Technikus,
zuerst der Spalten-, dann der Zeilenindex - so ist es korrekt. Wenn deine Messwerte in Spalten angeordnet sind, dann hattest du den Index nicht vertauscht - sorry. Aber beachte, dass die Indexwerte bei 0 beginnen und eventuelle Zeilen- und Spaltenüberschriften (FixedCols, FixedRows) von dir berücksichtigt werden müssen. Wenn du also 9 Werte und keine Spaltenüberschrift hast, dann läuft dein Zeilenindex von 0 bis 8. Der Zugriff mit 9 liefert dann den von dir beschriebenen Fehler. marabu |
Re: Wertübergbae für einen Stringgrid
Hallo marabu,
ich habe eine Kopfzeile und eine Nummerierungszeile programmiert. Daher habe ich das array von 1-9 gesetzt. Sollte ich vielleicht den kompletten Quelltext nochmal anhängen? Wenn ja (ich habe das in der eurigen Form noch nicht gemacht) wie stelle ich das an,dass der Text eingerahmt ist? Gruß Technikus |
Re: Wertübergbae für einen Stringgrid
Zitat:
einfach den quellcode in die delphitags einschließen: [ delphi]showmessage('Hallo');[/ delphi] (dabei die leerzeichen weglassen) aenogym |
Re: Wertübergbae für einen Stringgrid
Ist bestimmt hilfreich, wenn du den relevanten Code anhängst.
Zu den Formatier-Hilfen: Wenn du auf den Delphi-Code Button oberhalb des Beitragseditors klickst wird das öffnende Tag produziert, klickst du nochmal, dann wird das schließende Tag produziert. Du kannst deinen Code auch nachträglich einfassen, indem du ihn markierst und dann auf den Button klickst, oder indem du die Tags mit der Hand schreibst - nachdem du das Prinzip verstanden hast ist das wahrscheinlich der schnellste Weg. marabu |
Re: Wertübergbae für einen Stringgrid
Hallo marabu
hier nun mein aktueller Quellcode:
Delphi-Quellcode:
unit unit1_solarzelle;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Borland.Vcl.Grids, System.ComponentModel, Borland.Vcl.StdCtrls, Borland.Vcl.ExtCtrls; type TForm1 = class(TForm) StringGrid1: TStringGrid; Panel1_Ueberschrift: TPanel; Panel2_Beleuchtungsstaerke: TPanel; Edit1_Eingabe_lx: TEdit; Button1_Speichern: TButton; Button2_Laden: TButton; Button3_Leeren: TButton; Button4_Berechne_P: TButton; Button5_Beende: TButton; Label1_Optimum: TLabel; Edit2_Optimum: TEdit; StringGrid2: TStringGrid; Edit3_Eingabe_n: TEdit; Label2_Anzahl_Messwerte: TLabel; procedure Button4_Berechne_PClick(Sender: TObject); procedure FormCreate(Sender: TObject); procedure Button5_BeendeClick(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; implementation {$R *.nfm} procedure TForm1.Button5_BeendeClick(Sender: TObject); begin close end; procedure TForm1.FormCreate (Sender: TObject); var i,n: smallInt; begin StringGrid1.Cells[0,0]:='Nr.'; StringGrid1.Cells[1,0]:='Spannung U'; StringGrid1.Cells[2,0]:='Stromstärke I'; StringGrid2.Cells[0,0]:='Leistung P'; {StringGrid1.RowCount:=n+1; } for i:=1 to 9 do StringGrid1.Cells[0,i]:=IntToStr(i)+'.'; with StringGrid1 do begin ColWidths[0]:= 28; ColWidths[1]:= 110; ColWidths[2]:= 110; end; end; procedure TForm1.Button4_Berechne_PClick(Sender: TObject); var j: integer;{Lauf-Variablen zum Berechnen} leistung: double; u,i: array [1..9] of double; begin for j:=1 to 9 do begin u[j]:=StrToFloat(StringGrid1.Cells[1,j]); i[j]:=StrToFloat(StringGrid1.Cells[2,j]); end; for j:=1 to 9 do with StringGrid2 do {Ausgabe der berechneten Leistung} begin leistung:= u[j]* i[j]; Cells[0,j]:= FloatToStr(leistung); end; end; end. |
Re: Wertübergbae für einen Stringgrid
Ich hab mal deinen Code übernommen und bei mir funktioniert der anstandslos. Ich hab nix verändert: Copy&Paste macht's möglich! :zwinker:
Fehler find ich auf Anhieb auch keine... Kann es sein, dass du dich mit den versionen ein bisschen verzettelt hast? Hast du zwischendurch mal eine Datei umbenannt oder unteer anderem Namen gespeichert. Der Code, den du gepostet hast scheint nämlich so zu stimmen... Zu den Breadpoints: Du kannstfehler suchen(debuggen) indem du einen Haltepunkt(Breakpoint) in eine Zeile setzt(einfach [F5] drücken oder mit der Maus an den Rand klicken). Wenn dein Prog dann diese Zeile ausführen will hällt es an aund du kannst die Werte der einzelnen Variablen überprüfen, indem du mit der Maus über die Variablen fährst. wenn dein Programm dann die nächste Zeile ausführen soll, drückst du [F8]. Wie das ganze funktioniert steht nochmal auf ![]() ![]() ![]() So kannst du genau feststellen, was dein prog wann macht und wo genau der Fehler auftritt. mfg Christian |
Re: Wertübergbae für einen Stringgrid
Dein Code ist korrekt - wenn auch etwas ungewöhnlich. Der von dir beschriebene Fehler dürfte entstehen, wenn du nicht alle Eingabezellen mit Werten belegt hast. Der folgende Code zeigt dir, wie du das abfangen könntest.
In meinem Code habe ich die Arrays für Spannung und Stromstärke der Einfachheit halber eliminiert. Dann habe ich den Komponenten sprechende Namen gegeben. i und j sind klassische Laufvariablen, ich habe deshalb dCurrent eingeführt - d kennzeichnet den Variablen-Typ double und Current sagt etwas über den Verwendungszweck der Variablen aus.
Delphi-Quellcode:
marabu
procedure TCalcForm.CalcButtonClick(Sender: TObject);
var i: integer; dVoltage, dCurrent, dPower: double; s: string; ok: boolean; begin with Grid do for i := FixedRows to RowCount - 1 do begin ok := TryStrToFloat(Cells[1, i], dVoltage); ok := ok and TryStrToFloat(Cells[2, i], dCurrent); if ok then begin dPower:= dVoltage * dCurrent; s := FloatToStr(dPower); end else s := ''; Cells[3, i] := s; end; end; PS: bei mir gibt es auch kein zweites Grid, die Ausgabe mache ich in Spalte 4... |
Re: Wertübergbae für einen Stringgrid
Hallo marabu,
ich habe meinen Quellcode so probiert, dass alle Zellen mit Zahlen belegt waren, der Fehler war der Gleiche. Nun habe ich meine Procedure durch deine Procedure ersetzt und angepasst. Nun funktioniert es wunderbar. Aber noch eine Frage: Kannst du mir mit Kommentaren deinen Quellcode bitte nochmal mit Kommentaren erklären, was so in den einzelnen Schritten abläuft? Ich möchte es gern verstehen. Vielen Dank nochmals für die Hilfe an alle Beteiligten. Technikus |
Re: Wertübergbae für einen Stringgrid
Zitat:
Delphi-Quellcode:
Den Hinweisen von Christian zum interaktiven Debuggen in der IDE solltest du vielleicht auch noch nachgehen. Die Inspektion der Variablen-Inhalte zur Laufzeit ist mitunter eine sehr schöne Sache.
procedure TCalcForm.CalcButtonClick(Sender: TObject);
var i: integer; dVoltage, dCurrent, dPower: double; s: string; ok: boolean; begin // Ich verwende gerne einen with Block zur // Verkürzung der qualifizierter Namen with Grid do // Die Untergrenze der Laufvariablen setze ich // auf die erste Zeile nach der Überschrift, // funktioniert so auch bei mehrzeiligen Überschriften. // Die Obergrenze ist wegen der 0 basierenden // Zeilenadressierung um 1 kleiner als die Gesamtzahl der Zeilen. for i := FixedRows to RowCount - 1 do begin // Ich versuche den Spannungswert zu gewinnen // und merke mir das Ergebnis ok := TryStrToFloat(Cells[1, i], dVoltage); // Jetzt noch den Stromwert. Das Ergebnis // verknüpfe ich mit dem vorigen. ok := ok and TryStrToFloat(Cells[2, i], dCurrent); // Nur wenn beide Werte korrekt vorliegen if ok then begin // brechne ich die Leistung dPower:= dVoltage * dCurrent; // und wandle sie für die Anzeige in einen String um s := FloatToStr(dPower); end else s := ''; // ansonsten bleibt der string leer // die Ausgabe-Zelle wird belegt Cells[3, i] := s; end; end; Freundliche Grüße vom marabu |
Re: Wertübergbae für einen Stringgrid
Hallo marabu,
ich danke dir für das Kommentar. Nun balstle ich schon an meinem nächsten Problem, passt aber auch hier her. Ziel: Der Nutzer des Programmes soll mit Eingabe von der selbstgewählten Anzahl von Messwerten seine Tabellengröße selbst bestimmen. Dazu habe ich folgenden Quellcode geschrieben, oder besser gesagt, deinen ergänzt.
Delphi-Quellcode:
Nun funktioniert das Ganze zwar, wenn ich im Eingabefeld "Anzahl der Messwerte" eine Interger-Zahl eingebe wird die Tabelle beim Betätigen des Buttons "Berechne" erweitert und die Nummerierung bis zur letzten Zeile ergänzt. Aber das ist für den Anwender unpraktisch-denke ich.
procedure TForm1.Button4_Berechne_PClick(Sender: TObject);
var i, anzahl: integer; dSpannung, dStrom, dLeistung: double; s: string; ok: boolean; begin anzahl:=StrToInt(Edit3_Eingabe_anzahl.Text); StringGrid1.RowCount:=anzahl+1; StringGrid2.RowCount:=anzahl+1; with StringGrid1 do for i := FixedRows to anzahl do begin StringGrid1.Cells[0,i]:=IntToStr(i)+'.'; ok := TryStrToFloat(Cells[1, i], dSpannung); ok := ok and TryStrToFloat(Cells[2, i], dStrom); if ok then begin dLeistung:= dSpannung * dStrom; s := FloatToStr(dLeistung); end else s := ''; StringGrid2.Cells[0, i] := s; end; end; end. Nun meine Überlegung zur Verbesserung: 1. Ich gebe eine Anzahl in das EditFeld ein, sobald ich mit der Maus in die Tabelle hineinklicke, wird die Tabelle auf die nötige Größe erweitert und durchnummeriert. Meine Frage: Ist sowas ohne großen Aufwand programmierbar, wenn ja, welchen Tipp könnt ihr geben? Danke Technikus |
Re: Wertübergbae für einen Stringgrid
Die beiden Aktionen "Tabelle dimensionieren" und "Leistung berechnen" sind unabhängig voneinander, also solltest du sie auch nicht miteinander vermischen. Nimm einen eigenen Button für die Dimensionierung oder was immer sonst dir für deine Benutzeroberfläche gefällt. Ich habe deinen Code ein wenig umgestellt. Das Nummerieren der Zeilen geschieht jetzt in einer eigenen Prozedur:
Delphi-Quellcode:
marabu
const
MAXVALUES = 20; procedure TCalcForm.RenumberGridLines; var i: integer; begin with Grid do for i := FixedRows to RowCount - 1 do Cells[0, i] := IntToStr(Succ(i - FixedRows)) + '.'; end; procedure TCalcForm.ResizeButtonClick(Sender: TObject); var s: string; i: integer; begin s := IntToStr(Grid.RowCount - 1); if not InputQuery('Tabelle dimensionieren', 'Zeilen', s) then Exit; if not TryStrToInt(s, i) then ShowMessage(Format('"%s" ist nicht numerisch', [s])) else if not (i in [1..MAXVALUES]) then ShowMessage(Format('"%d" ist keine gültige Zeilenzahl', [i])) else begin Grid.RowCount := Succ(i); RenumberGridLines; end; end; |
Re: Wertübergbae für einen Stringgrid
Zitat:
Ich würde das aber etwas anders machen: - nur einen StringGrid nehmen - die Leistung in die 3. Spalte eintragen. - einen Butten: Neuer wert - Beim Click auf diesem Button: Neue Zeile mit Nummerierung mfg Christian //Edit: Zu spät... :oops: |
Re: Wertübergbae für einen Stringgrid
@Christian: nicht schlecht - dein Ansatz mit dem inkrementellen Dimensionieren. Dann braucht man allerdings noch eine Lösung für das Verkleinern der Tabelle, die vom Ansatz her dazu passt...
Freundliche Grüße vom marabu |
Re: Wertübergbae für einen Stringgrid
Zitat:
mfg Christian |
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:35 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