Autor |
Beitrag |
GKar
Hält's aus hier
Beiträge: 5
Win XP
Delphi 7 trial
|
Verfasst: Di 07.06.05 09:02
Hallo, Leute,
bin neu in der Gegend...
Ich versuche gerade mir selber Delphi beizubringen... Ich möchte ein Feld, in welches ich via Tastatur nur Zahlen und EIN ',' eingeben kann. Das klappt alles auch schon, bis auf nur EIN ','. Könnt Ihr mir Bitte helfen, warum meine Kommaschleife nicht funzt??
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: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86:
| unit Eingabe;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type TForm1 = class(TForm) Label1: TLabel; Edit1: TEdit; procedure Edit1Change(Sender: TObject); function Zahlen(a:LongInt):real; private public end;
var Form1: TForm1; implementation
{$R *.dfm}
procedure TForm1.Edit1Change(Sender: TObject); var a:Real; begin a := Zahlen(LENGTH(Edit1.Text)); Label2.Caption:=FloatToStr(a); end;
function TForm1.Zahlen(a:LongInt):Real; var b,Pos1:LongInt; Text:string; begin b := 1; Pos1 := 0; Text := Edit1.Text;
while(b<=a) do begin if(Text[b] = ',') then begin Pos1 := b; inc(b); continue; end; if((Text[b] = ',') and (b <> Pos1)) then begin DELETE(Text,b,2); end; inc(b); end;
b := 1;
while(b<=a) do begin if((a>0) and (Text[b]<='9') and (Text[b]>='0') or (Text[b]=',')) then begin Text := Edit1.Text; end else begin Text := Label1.Caption; Edit1.Text := Label1.Caption; end; inc(b); end;
if(a>25) then begin Text := Label1.Caption; Edit1.Text := Text; end;
Label1.Caption := Text;
if(Text='') then result:=0.0 else result := StrToFloat(Text);
end;
end. |
Vielen Dank, Leute...
Gruß
Moderiert von Tino: Code- durch Delphi-Tags ersetzt.
Moderiert von Tino: Titel geändert.
|
|
mehmeh
      
Beiträge: 97
WIN XP
D5 Prof
|
Verfasst: Di 07.06.05 09:15
na ja so auf den ersten Blick würde ich sagen:
Probiers mal die funktion vor der procedure zu schreiben.
|
|
Heiko
      
Beiträge: 3169
Erhaltene Danke: 11
|
Verfasst: Di 07.06.05 09:20
Warum einfach, wenn es auch schwer geht  .
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7:
| procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char); begin if (pos(',', Edit1.Text)) or (not (Key in ['0'..'9', ',', #8])) then begin Key:=#0 end end; |
|
|
GKar 
Hält's aus hier
Beiträge: 5
Win XP
Delphi 7 trial
|
Verfasst: Di 07.06.05 11:03
Danke, Heiko!
Kannst Du mir nur kurz erklären, was diese pos() und Key #8 bzw. #0 bedeuten? Bin doch noch anfänger...
Ansonsten probiere ich das später (sitze gerade nicht daheim) noch aus. (Und schlage mich durch die Hilfethemen...).
Gruß
|
|
jasocul
      
Beiträge: 6393
Erhaltene Danke: 147
Windows 7 + Windows 10
Sydney Prof + CE
|
Verfasst: Di 07.06.05 11:09
Für die Pos-Funktion liest du hier.
#8 entspricht der "Tab"-Taste. Die sollte auch zugelassen sein, damit du mit der Tastatur im Programm arbeiten kannst.
#0 "neutralisiert" die eingegebene Taste.
|
|
Heiko
      
Beiträge: 3169
Erhaltene Danke: 11
|
Verfasst: Di 07.06.05 11:17
jasocul hat folgendes geschrieben: | #8 entspricht der "Tab"-Taste. Die sollte auch zugelassen sein, damit du mit der Tastatur im Programm arbeiten kannst. |
FALSCH!!! #8 ist die Backspace-Taste. Die Tab-Taste ist #9  und in OnKeyPress-Ereignis kann man die Tab-Taste nicht abfangen, wodurch du ohne Probleme im Programm weiterarbeiten kannst, wenn #9 theroretisch blockiert werden müsste. Die Tab-Taste-Abzufangen ist nicht das leichteste.
|
|
jasocul
      
Beiträge: 6393
Erhaltene Danke: 147
Windows 7 + Windows 10
Sydney Prof + CE
|
Verfasst: Di 07.06.05 11:19
Ich schäme mich jetzt ganz doll
Stimmt natürlich mit BackSpace. Sorry.
|
|
Heiko
      
Beiträge: 3169
Erhaltene Danke: 11
|
Verfasst: Di 07.06.05 11:24
Wieder einer der fast  vor Scham vor mir  .
|
|
alzaimar
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: Di 07.06.05 11:45
|
|
Heiko
      
Beiträge: 3169
Erhaltene Danke: 11
|
Verfasst: Di 07.06.05 11:55
Ich finde Tastenüberwachung wesentlich besser, auch für den User de3s Programms. Außerdem wie willst du mit StrToFloat überprüfen ob eine gültige Zahl eingegeben ist? An der Fehlrmeldung etwa?
Wenn du es nicht mit Tastenüberwachung machen willst nimm lieber
function TryStrToFloat(const S: string, out Value: Extended): Boolean;anstatt StrToFloat  .
|
|
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Di 07.06.05 12:04
Ich würde val nehmen und den Rückgabecode auswerten, da erspart man sich die Exception, da eine Exception immer einen ziemlichen Overhead im Code produziert. Desweiteren könnte man beim OnChange prüfen, ob schon ein Komma eingegeben wurde und dann jedes weitere irgnorieren.
|
|
alzaimar
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: Di 07.06.05 12:07
Zitat: | Außerdem wie willst du mit StrToFloat überprüfen ob eine gültige Zahl eingegeben ist? An der Fehlrmeldung etwa? |
Deine Frage verstehe ich nicht. Wenn StrToFloat keine Exception liefert, war der übergebene String wohl oder übel ein Float, oder nicht? Natürlich erkenne ich an der Fehlermeldung, das der String wohl kein Float war.
TryStrToFloat ginge auch. Oder StrToIntDef. Ich arbeite aber mit Exceptions als Mittel der Programmflusskontrolle. Das erhöht die Übersichtlichkeit, ist aber Geschmacksache.
Die Tastenüberwachung geht nicht so einfach, weil du ja dann den Editor simulieren musst:
Sei Edit.Text = '123' und Key = '-'. Erlauben wir das, oder nicht?
Hmm, hängt doch von der Cursorposition und dem Einfügemodus (insert/overwrite) ab.
Bevor Du sagst, das es mit OnKeyPress besser geht, poste doch mal die Alternative.
|
|
MrFox
      
Beiträge: 208
WIN 2000 Professional, Ubuntu 5.10
D3 Prof, D7 Pers, D2005 Pers, Java (Eclipse)
|
Verfasst: Di 07.06.05 12:51
TMaskEdit ???
_________________ Das Leben auf der Erde mag zwar teuer sein, aber eine jährliche Rundreise um die Sonne ist gratis mit dabei.
|
|
alzaimar
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: Di 07.06.05 13:01
Geht auch einigermassen, aber man bekommt syntaktisch korrekte Realzahlen mit der Maskenbeschreibung nicht hin.
|
|
hansa
      
Beiträge: 3079
Erhaltene Danke: 9
|
Verfasst: Di 07.06.05 14:30
Warum denn überhaupt mit Try/except, wenn solche Fehler von vorneherein ausgeschlossen werden könen ?
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| ZulZeichen := ['0'..'9']; ... if (Key in ZulZeichen) then begin if Pos(DecimalSeparator, Text) = 0 then ZulZeichen := ZulZeichen + [DecimalSeparator] else ZulZeichen := ZulZeichen - [DecimalSeparator]; if not (Key in ZulZeichen) then Key := #0; end; |
Der User kann dann unmöglich ein zweites Trennzeichen eingeben !! Vorbeugen ist nun mal besser als heilen. 
_________________ Gruß
Hansa
|
|
alzaimar
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: Di 07.06.05 14:54
@hansa: Das mit Try..Except bzw. gleich Val oder TryStrToFloat ist schon klar.
Zu deiner Idee: Was ist mit Vorzeichen? Und Exponenten? Deine Version erlaubt auch diese Eingaben:
Ich denke, es ging dem Fragesteller um reele Zahlen, dazu gehören auch Vorzeichenbehaftete und Zahlen mit Exponenten, aber nicht die eben Erwähnten. Das sind ja keine Zahlen.
Zitat: |
Der User kann dann unmöglich ein zweites Trennzeichen eingeben !!
|
Ein erstes Trennzeichen kann er auch unmöglich eingeben  , weil ZulZeichen falsch initialisiert wurde. Damit überhaupt etwas bezüglich des '.' (oder ',') geprüft werden kann, muss der Dezimaltrenner zunächst in den ZulZeichen enthalten sein.
Und die Frage, ob nun heute mal '.' oder ',' das Dezimaltrennzeichen ist, sollte man auch nicht dem Anwender überlassen. Also, kürzen wir nochmal, damit alle berechtigten Einwände aus der Welt sind und wir erhalten:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| procedure TForm1.Edit1Change(Sender: TObject); Var d,s: String; p : Integer; cEdit : TEdit; fDummy : Extended;
begin cEdit := Sender as TEdit; p := cEdit.SelStart; If DecimalSeparator =',' Then d := '.' else d := ','; s := StrReplace (cEdit.Text+'0',d,DecimalSeparator); If TryStrToFloat (s, fDummy) Then Begin SetLength (s, Length (s) - 1); fLastValidEditText := s; End; cEdit.Text := fLastValidEditText; cEdit.SelStart := p; End; |
Dieser Code akzeptiert einfach alle gültigen reellen Zahlen. Ich weiss nich... find ich einfacher.
|
|
jasocul
      
Beiträge: 6393
Erhaltene Danke: 147
Windows 7 + Windows 10
Sydney Prof + CE
|
Verfasst: Di 07.06.05 15:19
Vorschlag:
Nehmt doch einfach eine existierende Komponente aus der Jedi-Bibliothek. Man muss das Rad doch nicht immer wieder neu erfinden.
@Hansa:
Ich weiß, dass du Fremd-Komponenten nicht magst. Das müssen wir nicht neu diskutieren. 
|
|
alzaimar
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: Di 07.06.05 15:38
Werden da nicht gleich 170.000 andere Komponenten mit installiert? Ansonsten hast du vollkommen Recht. Ich persönlich mag nämlich 90% der Jedi-Teile nicht. Aber der Rest wäre für mich absolut brauchbar.
|
|
jasocul
      
Beiträge: 6393
Erhaltene Danke: 147
Windows 7 + Windows 10
Sydney Prof + CE
|
Verfasst: Di 07.06.05 16:19
Ist zwar etwas OT, aber trotzdem meine Meinung dazu:
Stimmt leider.
Es ist eine Komponentensammlung, in der viele andere Komponentensammlungen aufgenommen wurden (z.B. rxLib). Dummerweise weiß man erst hinterher, welche Komponenten man nicht hätte mitinstallieren sollen.
Man kann aber bei der Installation durchaus entscheiden, was man haben möchte und was nicht.
|
|
hansa
      
Beiträge: 3079
Erhaltene Danke: 9
|
Verfasst: Di 07.06.05 20:28
alzaimar hat folgendes geschrieben: | Zu deiner Idee: Was ist mit Vorzeichen? Und Exponenten? Deine Version erlaubt auch diese Eingaben:
Ein erstes Trennzeichen kann er auch unmöglich eingeben , weil ZulZeichen falsch initialisiert wurde. Damit überhaupt etwas bezüglich des '.' (oder ',') geprüft werden kann, muss der Dezimaltrenner zunächst in den ZulZeichen enthalten sein.
Und die Frage, ob nun heute mal '.' oder ',' das Dezimaltrennzeichen ist, sollte man auch nicht dem Anwender überlassen. |
Von dem hier zitierten stimmt aber nicht viel.  Gut Du kannst auch nicht ales wissen. Eingaben wie "0," werden mit Nullen aufgefüllt. Die Anzahl der Nachkommastellen stelle ich hierbei im OI ein. Es würde also nach verlassen des Feldes z.B. "0,00" drin stehen. Führende "," "-" usw. sind nicht erwünscht. Wäre aber wohl kein Problem, bei einem "," am Anfang daraus "0," zu machen. Sobald ein gültiges Zeichen vorhanden ist, kann doch der Decimalseparator eingegeben werden. Wieso denn nicht  Aber nur der, wie er auch Windows bekannt ist. Das überlasse ich doch nicht dem Anwender.
Für mich bleibt da als Rechtfertigung von Try/Except nur noch die wissenschaftliche Schreibweise übrig. Aber wer braucht die schon, um Eingaben zu machen ?
Und @Jasocul : ja, das ist in der Tat ein Teil einer eigenen Komponente. Aber wieso mag ich keine Fremdkomponenten ? Die sind mir nur lediglich egal, sofern ich in der Lage bin mit vertretbarem Aufwand selber eine zu machen. Allerdings gibt es momentan tatsächlich handfeste Argumente gegen den Einsatz derselben. Ich sage nur .NET. Wielange dauert die Portierung einer Fremdkomponente ? Wird das überhaupt in Angriff genommen ? Wie weit ist z.B. Jedi.NET ? Wer weiß. Zur Zeit ist alles sehr ungewiss. Siehe Schicksal von Turbopower. Für den hier angesprochenen Zweck sind die Jedi-Ritter allerdings eher wie Atombomben auf Spatzen zu werfen. 
_________________ Gruß
Hansa
|
|