Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - fehlermeldung abfangen
hassedelphi - Do 14.08.03 12:44
Titel: fehlermeldung abfangen
hi
ich hab ein programm, in dem ein Timer (interval auf maximum) enthalten ist, um ein paar variablen auf dem neuesten stand zu bringen. immer wenn ich im stringgrid eine zahl ändere merkt das der timer bei seinem nächsten durchlauf. und da liegt das problem;
falls der nutzer nun eine negative zahl eingibt, ist der timer zu schnell, und sobald NUR ein minus in einer zelle steht (die darauf folgende zahl hat der nutzer noch nicht eingegeben, weil zu langsam) häufen sich die felhermeldungen:
'-' ist kein gültiger gleitkommawert
das programm stürtzt dann nach ein paar secunden von alleine ab.
ich will nun eine procedure (oder was auch immer) schreiben, die beim auslösen der >'-' ist kein gültiger gkw< fehlermeldung sofort den interval auf 0 stellt. nur hab ich (wie immer) keine peilung, wie ich diese fehlermeldung 'abfangen' kann.
kann jmd helfen? :puke:
AndyB - Do 14.08.03 12:53
Und warum willst du das abfangen? Sorge lieber for und prüfe, ob es sich um einen gültigen Integer handelt. Prevention ist immer besser als Symthombekämpfung.
Terra23 - Do 14.08.03 12:57
Ich würde es vielleicht mal so probieren:
1) Im OnKeyDown-Ereignis der Tabelle setzt du
Delphi-Quelltext
1:
| Timer1.Enabled:=False; |
2) Im OnKeyUp-Ereignis der Tabelle setzt du
3) Im OnKeyPressEreignis der Tabelle setzt du
Delphi-Quelltext
1: 2:
| If Not (Key In [#08, '0'..'9']) Then Key:=#0; |
Letztere Prozedur läßt nur Zahlen und die Backspace-Taste zu, so daß ein Minus verhindert wird. Zusätzlich könntest du noch
StrToFloatDef zu Rate ziehen, denn dort kannst du einen Default-Wert eingeben, der im Falle einer Exception benutzt wird, sprich wenn der umzuwandelnde Wert wegen Fehlern (Buchstaben, Sonderzeichen) nicht umgewandelt werden kann. Da du eine Fehlermeldung bezüglich Gleitkommazahl bekommst, gehe ich mal davon aus, daß do eine Kommazahl hast (Ich habe Float schon lange nicht gebraucht :-) ).
hassedelphi - Do 14.08.03 13:10
thx für antwort (andy,terra)
bei deinem sourcecode kann ich kein minus mehr eingeben (3) und bei 2 und 1 kommt das gleiche (sobald ich die minustaste loslasse wird der time aktiviert) aber warte du hasst mich auf ne idee gebracht:
ich werde eifach bei keydown timer.interval:=0 und bei keyup
If (Key In [#08, '0'..'9']) Then timer.interval:=max.
die sache mit dem minus wäre gegessen, nur falls der user jetzt ein bustaben eingibt, und danach eine zahl, kommt die gleiche fehlermeldung.
ShadowThief - Do 14.08.03 14:19
ich bin mir nicht sicher, ob dieser kommentar hier angebracht ist,
deswegen wäre ich nicht böse, wenn er wieder gelöscht werden würde,
aber:
variablen mit einem timer abzugleichen, also ... das ist schon echt
schlechter programmierstil. ich würde mir überlegen, ob dass nicht
irgendwie anders geht.
ich bin auch bereit konstruktive kritik zu bringen, nur weiss ich nicht
genug über das programm oder die problematik bescheid.
shadow.
hassedelphi - Do 14.08.03 15:27
mag sein. aber glaub mir, alle anderen varianten sahen *mist*e aus/haben nicht gefunzt
ich sag dir jetzt was ich machen wollte, und wenn du 'ne bessere idee hast, einfach posten :D !
ich hab ein stringgrid (etwa 8*10), hinter jeder zeile eine checkbox (8 davon) wenn eine ganze Zeile ausgefüllt ist, schaltet die checkbox von enabled:= false auf true => jetzt erst kann ich sie 'checken'. der timer:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34:
| procedure TForm1.Timer1Timer(Sender: TObject); var i,b : integer; begin max:=4294967295; timer1.interval:=max; for i := 1 to 8 do begin if (findcomponent('checkbox'+inttostr(i))as Tcheckbox).Checked = true then begin cfe[i]:=strtofloat(stringgrid1.cells[2,i+1]); cfl[i]:=strtofloat(stringgrid1.cells[3,i+1]); cgas[i]:=strtofloat(stringgrid1.cells[4,i+1]); m[i]:=strtofloat(stringgrid1.cells[5,i+1]); T1[i]:=strtofloat(stringgrid1.cells[6,i+1]); Ts[i]:=strtofloat(stringgrid1.cells[7,i+1]); qs[i]:=strtofloat(stringgrid1.cells[8,i+1]); Tv[i]:=strtofloat(stringgrid1.cells[9,i+1]); qv[i]:=strtofloat(stringgrid1.cells[10,i+1]); end; end; button1.Enabled:=true; for b := 2 to 9 do begin if (stringgrid1.cells[2,b] <> '') and (stringgrid1.cells[3,b] <> '') and (stringgrid1.cells[4,b] <> '') and (stringgrid1.cells[5,b] <> '') and (stringgrid1.cells[6,b] <> '') and (stringgrid1.cells[7,b] <> '') and (stringgrid1.cells[8,b] <> '') and (stringgrid1.cells[9,b] <> '') and (stringgrid1.cells[10,b] <> '') then (findcomponent('checkbox'+inttostr(b-1))as Tcheckbox).Enabled:=true else begin (findcomponent('checkbox'+inttostr(b-1))as Tcheckbox).Enabled:=false; (findcomponent('checkbox'+inttostr(b-1))as Tcheckbox).Checked:=false; end; end; end; |
sicher dass hätte man mit on keypress oder so auch hingekrickt, aber ich kann die spalten auch noch anders füllen. ich habe vor jede zeile ein panel mit namen stoff[zeile]. beim klicken, wird 'ne combobox angezeigt, wenn ich aus der wähle, werden die zellen automatisch gefüllt (es gibt mehrere combos, die mit itemindex verknüpft sind):
(*wieso kann ich die delphitags nicht in die mitte setzten?*)
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| procedure TForm1.Stoff1Click(Sender: TObject); var i : integer; begin if combobox1.Visible=false then combobox1.Visible:=true; for i := 1 to 8 do begin if sender = findcomponent('stoff'+inttostr(i)) as TPanel then begin combobox1.top:= (findcomponent('stoff'+inttostr(i)) as TPanel).top; combobox1.Left:= (findcomponent('stoff'+inttostr(i)) as TPanel).Left + (findcomponent('stoff'+inttostr(i)) as TPanel).Width; s:=i; end; end; end; |
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| procedure TForm1.ComboBox1Change(Sender: TObject); var i,i3 : integer; begin for i := 2 to 10 do (findcomponent('combobox'+inttostr(i))as Tcombobox).ItemIndex := combobox1.ItemIndex; for i3 := 2 to 10 do begin stringgrid1.cells[i3,s+1]:=(findcomponent('combobox'+inttostr(i3))as Tcombobox).text; end; combobox1.visible:=false; if (combobox1.Text=('Wasser')) or (combobox1.Text=('Eis(0°C)')) then begin stringgrid1.cells[2,s+1]:=('2,09'); stringgrid1.cells[3,s+1]:=('4,19'); stringgrid1.cells[4,s+1]:=('1,86'); stringgrid1.cells[7,s+1]:=('0'); stringgrid1.cells[8,s+1]:=('334'); stringgrid1.cells[9,s+1]:=('100'); stringgrid1.cells[10,s+1]:=('2260'); end; end; |
wenn das ding nun die zellen ausfüllt, und sich die maus außerhalb des formular befindet (wähle mit pfeiltasten aus) dann wird die checkbox nicht enabled:=true!, auch wenn alle zellen der zeile ausgefüllt sind (zumindest nicht mit mousemove oder key down usw. ; mit dem timer schon)
hassedelphi - Do 14.08.03 15:32
ehrlichgesagt wäre ich über verbesserungs, vereinfachungsvorschläge sehr erfreut, da ich selbst nicht mehr ganz so durchsehe. :lol:. aber ich will ja nicht, dass ihr mein programm schreibt :lol:
weiß nun jemand, wie ich den fehler abfange?
Terra23 - Do 14.08.03 15:45
Eigentlich hatte ich vorhin einen Beitrag geschrieben, doch der ist wohl nicht da. Naja.
Das die Meldung wieder kommt, liegt an dem fehlenden:
... denn das macht eine nicht erlaubte Taste wieder "weg", quasi. Du sollst halt nicht am Code rummachen. :-)
Und was für deine Zwecke vielleicht hilfreich ist:
Zeichne dir doch mal auf ein Blatt Papier auf, wie dein Tool aussehen soll und was welche Komponente machen soll, z.B.
Tabelle:
1) Darf nur Zahlen bekommen
2) Soll
nach Eingabe überprüft werden und nicht während der Eingabe
...
...
So kannst du dann der Reihe nach alles schön programmieren und du findest dich dann besser zurecht. Mal ehrlich: Meinst du, du weißt noch, was der obige Code bewirkt, wenn dein Programm komplett fertig ist?
hassedelphi - Do 14.08.03 16:35
| Terra23 hat folgendes geschrieben: |
So kannst du dann der Reihe nach alles schön programmieren und du findest dich dann besser zurecht. Mal ehrlich: Meinst du, du weißt noch, was der obige Code bewirkt, wenn dein Programm komplett fertig ist? |
mitlerweile hab ich das programmm so oft neu programmiert, dass ich das bestimmt noch wissen werde. schätze mit dem aufzeichnen meinst du ein struktogramm, oder?
ich war noch nie gut im erklären, ich versuch's nochmal:
der fehler kommt immer wieder, weil der timer seine aufgabe ca. 18 mal pro secude macht => 18 fehlermeldungen pro secunde falls ein wert kein real ist => keine chance irgendetwas zu berichtigen! :cry:
Terra23 - Do 14.08.03 18:29
Gut. Dann gib mir mal deine Hand und wir lesen nochmal gemeinsam, was ich dir oben geschrieben habe..:
| Terra23 hat folgendes geschrieben: |
Zusätzlich könntest du noch StrToFloatDef zu Rate ziehen, denn dort kannst du einen Default-Wert eingeben, der im Falle einer Exception benutzt wird, sprich wenn der umzuwandelnde Wert wegen Fehlern (Buchstaben, Sonderzeichen) nicht umgewandelt werden kann.
|
Du mußt halt dein StrToFloat ersetzen, denn dann werden die Fehlermeldungen umgangen und der angegebene Default-Wert wird benutzt. Alles klar? Na wunderbar.. ;-)
hassedelphi - Do 14.08.03 19:03
cool :D (hab ich überlesen)
dass heißt wen ich strtofloatdef nehme dann...häh? :?
angenommen ich gebe die zahl 1,05g6 in ein editfeld ein, was die aufgabe hat die zahl umzuwandel, und ein label, das die umgewandelte zahl ausgibt, was krieg ich dann raus (aus dem label?)
funzt das auch mit strtointdef oder floattostrdef?
Terra23 - Do 14.08.03 20:00
Nun solltest du wirklich langsam mal die Hilfe von deinem Delphi bemühen. Wenn du die Eingabe eines Edit-Feldes in ein Label setzen willst, brauchst du nichtmal umwandeln, weil beide einen String erwarten, also:
Delphi-Quelltext
1:
| Label1.Caption:=Edit1.Text; |
Vielleicht könnte ich dir helfen, aber durch deinen Code steige ich nicht durch. Sorry..
hassedelphi - Fr 15.08.03 08:03
:D
natürlich weiß ich wie ich das mit dem editfeld zum label mache.
im grunde wollte ich nur wissen, was passiert, wenn ich eine falsche real zahl (145,05g67824) eingebe, und sie mit strtofloatdef umgewandelt wird.
Terra23 - Fr 15.08.03 13:05
Das habe ich dir geschrieben. Intern passiert eine Exception und damit die nicht sichtbar wird, nimmt man deinen Default-Wert, also:
Delphi-Quelltext
1:
| Label1.Caption:=FloatToStrDef((1323erer/34), 1,506); |
würde theoretisch dann "1,506" ergeben. Nun bin ich mir nur nicht mehr ganz sicher, wie man den Real-Wert übergibt. Mußt du mal probieren..
hassedelphi - Fr 15.08.03 16:20
also...na ja...
hab immer noch keine ahnung was du meinst. floattostrdef gibts bei mir nicht und sowas hier:
Delphi-Quelltext
1: 2: 3: 4:
| var a : real; begin a := strtofloatDef(edit1.text) end; |
gibt mir einen
[Fehler] Unit1.pas(30): Es gibt keine überladene Version von 'StrToFloatDef', die man mit diesen Argumenten aufrufen kann
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!