Autor |
Beitrag |
Biarchiv
      
Beiträge: 688
|
Verfasst: Do 15.06.06 20:50
Hallo,
folgender Coder erlaubt das man nur Zahlen von 0-9 und Komma "," in
ein TEdit schreiben darf.
Allerdings wie würde das funktionieren damit die TEdit nur ein Komma akzeptiert und
ein weiteres nicht annimmt.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| var SS,SL,i,i1,f:integer; Buf:string; begin f := 0; with Sender as TEdit do begin SS:=SelStart; SL:=SelLength; SetLength(Buf,0); for i:=1 to length(Text) do if Text[i] in (['0'..'9',',']) then begin for i1:=1 to length(Text) do if Text[i] = ',' then f := f + 1; if (f >= 3) then break; Buf:=Buf+Text[i]; end; Text:=Buf; SelStart:=SS; SelLength:=SL; end; |
|
|
Marc.
      
Beiträge: 1876
Erhaltene Danke: 129
Win 8.1, Xubuntu 15.10
|
Verfasst: Do 15.06.06 20:55
hallo,
warum prüfst du nicht einfach schon bei der Eingabe, ob bereits ein Komma enthalten ist?
Würde dann wie folgt aussehen:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char); begin if key = ',' then if pos(',', edit1.Text) <> 0 then begin key := #0; end;
if not (key in ['0'..'9', ',' , #8]) then begin key := #0; end; end; |
Zuletzt bearbeitet von Marc. am Fr 16.06.06 18:30, insgesamt 2-mal bearbeitet
|
|
mkinzler
      
Beiträge: 4106
Erhaltene Danke: 13
Delphi 2010 Pro; Delphi.Prism 2011 pro
|
Verfasst: Do 15.06.06 20:56
Du könntest es auch mit einem TMaskedEdit versuchen.
_________________ Markus Kinzler.
|
|
aim65
      
Beiträge: 312
Win 9x, Win XP
Delphi 3pro, 7PE
|
Verfasst: Fr 16.06.06 10:57
@ NoTVerYEvilPzYchO
"edit.text" mag der Compiler ganz und gar nicht - erwartet sowas wie "edit1.text".
Daher ist der Ansatz leider nicht universell zu gebrauchen. 
|
|
Marc.
      
Beiträge: 1876
Erhaltene Danke: 129
Win 8.1, Xubuntu 15.10
|
Verfasst: Fr 16.06.06 18:37
@ aim65
er soll den Code ja auch nicht kopieren, sondern verstehen. Der Code selbst stammt aus meinem alten Taschenrechner. Ich hoffe allerdings, dass seine Edits nicht durchnummeriert sind, sondern entsprechende, sinnvolle Namen haben, die Rückschluss auf ihre Funktion geben. Ist das der Fall, muss er so oder so den Code anpassen.
Damit er allerdings jetzt universell brauchbar ist, habe ich den Quellcode entsprechend editiert 
|
|
aim65
      
Beiträge: 312
Win 9x, Win XP
Delphi 3pro, 7PE
|
Verfasst: Sa 17.06.06 10:48
@ NoTVerYEvilPzYchO
Ist mir schon klar.
Mein "universell nicht brauchbar" bezog sich auf die KeyPress-Routine und die Tatsache, daß man bei der von Dir angeführten Methode immer nur EIN bestimmtes Editfeld auf doppeltes Dezimalzeichen abfragen kann. Wenn ich nun z.B. 20 Eingabefelder habe, die über die Keypress-Routine bedient werden sollen, geht's halt so nicht. Ich habe bisher noch keine gute Lösung für das Abfangen des doppelten Dezimalzeichens innerhalb einer allgemeingültigen KeyPress-Abfrage gefunden. Scheitert immer wieder an der Backspace Problematik. Kennst Du eine? (ohne Bezug auf bestimmte Editfelder).
P.S. Ich verwende mittlerweile immer "DecimalSeparator" statt Komma oder Punkt. Mache ich, weil meine Progrämmchen auch auf englischen Versionen laufen sollen. Hab mal meine "Universal"-Routine hier kopiert, leider ohne Lösung des o.g. Problems (  für's Englisch).
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| begin if not (Key in [#8,'0'..'9']) then if Key in [',','.',';',':'] then Key := DecimalSeparator else if Key =#13 then begin Perform(WM_NEXTDLGCTL, 0, 0); Key := #0; end else Key := #0; end; |
Edit: Mein Kram geht wohl haarscharf am Thema vorbei, da Biarchiv ja wohl nur ein Edit-Feld braucht... 
|
|
Born-to-Frag
      
Beiträge: 1094
Win XP SP2, Win 2000 SP4
Delphi 7, 2k5
|
Verfasst: Sa 17.06.06 10:54
Hallo!
Man kann doch statt
if Pos(',', Edit1.Text) > 0 ...
einfach
if Pos(',', (Sender as TEdit).Text) > 0 ...
nehmen, dann kann man für jedes Edit das gleiche KeyPress Ereignis verwenden, oder hab ich das jetzt falsch verstanden?
greetz
_________________ Theorie ist wenn man alles weiß, aber nichts funktioniert. Praxis ist wenn alles funktioniert, aber niemand weiß warum.
Microsoft vereint Theorie und Praxis: Nichts funktioniert und niemand weiß warum.
|
|
aim65
      
Beiträge: 312
Win 9x, Win XP
Delphi 3pro, 7PE
|
Verfasst: Sa 17.06.06 11:09
@ Born-to-Frag
WARUM HAT MIR DAS KEINER VOR EINEM JAHR GESAGT??
Spaß beiseite - manchmal hat man wirklich eine ganze Bretterwand vor'm Kopp
Werde gleich Dein Zeilchen in meinen Kram einfügen, danke für den Tip.
(Mann, kann's immer noch nicht fassen - so alt und noch so beschränkt..  )
|
|
Biarchiv 
      
Beiträge: 688
|
Verfasst: Mo 19.06.06 21:35
Hallo,
fällt jamanden auch eine Lösung zo OnChange ein?
Sonst müßte ich alles Umbauen.
Mein Vorschlag läuft leider nicht.
Hier will ich prüfen ob schon ein , komma trin ist, wenn ja dann nur Zahlen akzeptieren.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| var SS,SL,i,i1:integer; Buf:string; ifkomma : Boolean; begin with Sender as TEdit do begin SS:=SelStart; SL:=SelLength; SetLength(Buf,0); for i:=1 to length(Text) do begin showmessage(inttostr(pos(',', Text))); if (pos(',', Text) > 0) then ifkomma := true else ifkomma := false; if ifkomma = false then begin if Text[i] in ((['0'..'9',','])) then Buf:=Buf+Text[i]; end; if ifkomma = true then begin if Text[i] in ((['0'..'9'])) then Buf:=Buf+Text[i]; end; end; Text:=Buf; SelStart:=SS; SelLength:=SL; end; |
|
|
aim65
      
Beiträge: 312
Win 9x, Win XP
Delphi 3pro, 7PE
|
Verfasst: Mo 19.06.06 23:46
Gibt es denn einen triftigen Grund, "OnChange" für dein Edit-Feld zu benutzen? (Außer, daß du evtl. bei einigen Edits das Ereignis von OnChange auf OnKeyPress ändern mußt).
Die KeyPress-Routine erschlägt doch deine Frage mit nur wenigen Zeilen, weil hier ein unerwünschtes Zeichen schon vorher abgefangen werden kann, bevor es im Edit erscheint. Bei deiner Methode kommt ein unerwünschtes Zeichen ja noch "durch" und müßte dann wieder aus dem String entfernt werden - abgesehen von der Komplexität deines Ansatzes.
Ehrlich gesagt, steige ich auch nicht so ganz durch deine Routine...
Du kannst jedenfalls alles, was du mit OnChange machen kannst, auch mit KeyPress erschlagen - und das mit wesentlich weniger Code.
|
|
Biarchiv 
      
Beiträge: 688
|
Verfasst: Di 20.06.06 16:50
aim65 hat folgendes geschrieben: | Gibt es denn einen triftigen Grund, "OnChange" für dein Edit-Feld zu benutzen? (Außer, daß du evtl. bei einigen Edits das Ereignis von OnChange auf OnKeyPress ändern mußt).
Die KeyPress-Routine erschlägt doch deine Frage mit nur wenigen Zeilen, weil hier ein unerwünschtes Zeichen schon vorher abgefangen werden kann, bevor es im Edit erscheint. Bei deiner Methode kommt ein unerwünschtes Zeichen ja noch "durch" und müßte dann wieder aus dem String entfernt werden - abgesehen von der Komplexität deines Ansatzes.
Ehrlich gesagt, steige ich auch nicht so ganz durch deine Routine...
Du kannst jedenfalls alles, was du mit OnChange machen kannst, auch mit KeyPress erschlagen - und das mit wesentlich weniger Code. |
Ja, es sind ca. 500 Edits.
Warscheinlich muss ich es eh ändern.
Ich hab zu dumm, leider in der OnChange angefangen.
|
|
Lannes
      
Beiträge: 2352
Erhaltene Danke: 4
Win XP, 95, 3.11, IE6
D3 Prof, D4 Standard, D2005 PE, TurboDelphi, Lazarus, D2010
|
Verfasst: Di 20.06.06 23:47
aim65 hat folgendes geschrieben: | ...Du kannst jedenfalls alles, was du mit OnChange machen kannst, auch mit KeyPress erschlagen - und das mit wesentlich weniger Code. |
wie behandelst Du das einfügen von Text über das Kontextmenü.
Und was ist mit Strg+V und Umschalt+Insert? Fängst Du das auch ab,
dann unterbindest damit eine gewünschte Funktionalität.
Schlage mal das folgende vor:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| sFloat : String = '0'; procedure TForm1.Edit1Change(Sender: TObject); var E: Extended; begin if TextToFloat(PChar(Edit1.Text), E, fvExtended) then sFloat := Trim(Edit1.Text) else begin Edit1.Text := sFloat; Edit1.SelStart := Length(Edit1.Text); end; end; |
Bei 500 Edits  kann statt der Variable sFloat ein Array of String entsprechend genutzt werden.
_________________ MfG Lannes
(Nichts ist nicht Nichts) and ('' <> nil ) and (Pointer('') = nil ) and (@('') <> nil )
|
|
aim65
      
Beiträge: 312
Win 9x, Win XP
Delphi 3pro, 7PE
|
Verfasst: Mi 21.06.06 12:33
@ Lannes:
 Klar, hast recht, wenn man nicht nur eine reine Tastatur-Eingabe sondern auch copy+paste usw. berücksichtigt. Ich war nur von der Tastatureingabe ausgegangen.
Dein eleganter Ansatz mit TextToFloat war mir neu - hab's gleich mal ausprobiert.
Dabei habe ich festgestellt, daß die erste Ziffer nicht mehr gelöscht werden kann. Wenn das erste Zeichen ein '-'(minus) oder ein nicht zulässiges Zeichen ist, erscheint eine '0', die ebenfalls nicht mehr löschbar ist. Hab ich was übersehen?
@ Biarchiv:
500 Edits - das riecht nach Arbeit, egal was du nimmst...
Edit: Hatte übersehen, daß sFloat ja mit '0' initialisiert wird. ABER, wieso akzeptiert die Routine kein (führendes) Minuszeichen?
|
|
aim65
      
Beiträge: 312
Win 9x, Win XP
Delphi 3pro, 7PE
|
Verfasst: Mi 21.06.06 13:34
Da bin ich schon wieder...
Hab' mal mit Lannes' Routine weiter herumgespielt und noch folgende Erkenntnisse gewonnen:
1) Was Erfreuliches:
Man kann die Procedure auf mehrere Edit-Felder anwenden, wenn man Born-to-Frag's Tip mit "(Sender as TEdit)" überall statt "Edit1" einbaut.
2) Man kann über Copy&Paste auch eine Zahl mit Minuszeichen einfügen, die auch richtig in der Variablen E weiterverarbeitet wird. Allerdings bleiben bei einem Löschversuch mit Backspace jetzt das '-' UND die nächste Ziffer stehen.
3) Bei der Weiterverarbeitung von E (ich hab einfach mal E*E genommen) gibt es beim Versuch, die erste (oder besser die letzte verbleibende) Ziffer zu löschen, die nette Meldung "Fehler bei Fließkommaoperation".
Habe selber (bis auf 1) noch nichts in der Procedure verändert. Wat nu? 
|
|
Lannes
      
Beiträge: 2352
Erhaltene Danke: 4
Win XP, 95, 3.11, IE6
D3 Prof, D4 Standard, D2005 PE, TurboDelphi, Lazarus, D2010
|
Verfasst: Mi 21.06.06 15:12
aim65 hat folgendes geschrieben: | ...ABER, wieso akzeptiert die Routine kein (führendes) Minuszeichen? |
nur wenn das '-' Zeichen als erstes eingegeben wird.
Halt mal den Code erweitern um eine zusätzliche Bedingung:
Delphi-Quelltext 1:
| if (Text = '-') or (TextToFloat(PChar(Text), E, fvExtended)) then |
aim65 hat folgendes geschrieben: | ...Da bin ich schon wieder... |
zu 1.
klar geht das  siehe unten
zu 2.
Bedingung (Text = '') eingebaut und keine Vorbelegung mit '0'
zu 3.
Die Variable E ist nur für die Funktion TextToFloat eingebaut.
Wenn man mit E rechnen willst, dann nur wenn Edit.Text nicht leer ist.
Hier ein allgemeiner und verbesserter Code damit man ihn für viele Edits einsetzen kann.
Dazu alle Edits in der Tag-Eigenschaft von 0 bis X durchnummerieren und ein Array zur Zwischenspeicherung verwenden. Die Procedure allen Edits als Event-Handler für OnChange zuweisen. Der Code sieht dann in etwa so aus:
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:
| sFloatArr : Array [0..9] of String; procedure TForm1.AllEditChange(Sender: TObject); var E: Extended; begin with TEdit(Sender) do if (Text = '') or (Text = '-') or (TextToFloat(PChar(Text), E, fvExtended)) then begin sFloatArr[Tag] := Trim(Text); if Text <> sFloatArr[Tag] then begin Text := sFloatArr[Tag]; SelStart := Length(Text); end; if Text <> '' then end else begin Text := sFloatArr[Tag]; SelStart := Length(Text); end; end; |
_________________ MfG Lannes
(Nichts ist nicht Nichts) and ('' <> nil ) and (Pointer('') = nil ) and (@('') <> nil )
|
|
aim65
      
Beiträge: 312
Win 9x, Win XP
Delphi 3pro, 7PE
|
Verfasst: Mi 21.06.06 17:15
Komme gerade vom Rasenmähen (muß ja auch mal sein... )
Gleich mal deine Routine ausprobiert: Na, geht doch...
Zitat: | nur wenn das '-' Zeichen als erstes eingegeben wird. |
Alles andere macht ja bei einer Eingabe keinen Sinn.
Nur der Vollständikeit halber: in Zeile 15 muß es heißen
Delphi-Quelltext 1:
| if (Text <>'') and (Text <>'-') then |
(ich weiß, nur wenn man in der Routine selbst weiterrechnen will).
Da ich nicht so fit bin, noch eine Verständnisfrage: Bei welchen Anwendungen ist der Tag-Array sinnvoll?
Konnte jedenfalls bei mehreren Edit-Feldern ohne die Tags keine Probleme feststellen.
Dachte hierbei an Biarchiv
Jedenfalls, prima Lösung, hab's schon in meine Sammlung aufgenommen.
|
|
Lannes
      
Beiträge: 2352
Erhaltene Danke: 4
Win XP, 95, 3.11, IE6
D3 Prof, D4 Standard, D2005 PE, TurboDelphi, Lazarus, D2010
|
Verfasst: Mi 21.06.06 19:30
aim65 hat folgendes geschrieben: | ...Da ich nicht so fit bin, noch eine Verständnisfrage: Bei welchen Anwendungen ist der Tag-Array sinnvoll?
Konnte jedenfalls bei mehreren Edit-Feldern ohne die Tags keine Probleme feststellen. |
in dem Array wird über die Tag-Eigenschaft der Edits als Index für jedes Edit der letzte gültige Wert zwischengespeichert. Sonst würde bei einer Fehleingabe (als erste Eingabe) der letzte gültige Wert, der in einem anderen Edit eingegeben wurde, in das aktuelle Edit gesetzt. Außerdem hat das den Vorteil, das die Werte für weitere Überprüfungen, Berechnungen usw in einem Array vorliegen.
Alternativ kann mit nur eine Variable gearbeitet werden, wenn zusätzlich in einem allgemeinen Event-Handler für das Ereignis OnEnter der Wert zwischengespeichert wird.
_________________ MfG Lannes
(Nichts ist nicht Nichts) and ('' <> nil ) and (Pointer('') = nil ) and (@('') <> nil )
|
|
aim65
      
Beiträge: 312
Win 9x, Win XP
Delphi 3pro, 7PE
|
Verfasst: Mi 21.06.06 19:48
|
|
Biarchiv 
      
Beiträge: 688
|
Verfasst: Mo 26.06.06 11:05
Hallo,
danke Lannes der Code funktioniert sehr gut.
Nur ein kleinen Fehler hat er noch.
Er soll fals TEdit leer ist einfach 0,00 reinschreiben da es sonst
zu einen flaschen Gleitkommawert kommt.
|
|
aim65
      
Beiträge: 312
Win 9x, Win XP
Delphi 3pro, 7PE
|
Verfasst: Mo 26.06.06 11:18
Ich würde das oder die Editfelder in Form.Create/Activate mit '0,00' initialisieren.
Dann diesen Code-Teil von Lannes' Routine verändern:
Delphi-Quelltext 1: 2: 3: 4: 5:
| with TEdit(Sender) do if Text='' then Text:='0,00' else if (Text = '-') or (TextToFloat(PChar(Text), E, fvExtended)) then begin.... |
Dann wird beim Löschen des Feldes automatisch '0,00' gesetzt.
Edit:  Sorry, ist absoluter Käse, da bei einer Zahleneingabe das '0,00' nicht gelöscht wird. Mal wieder zu schnell....
Edit2:
Hab mal weiter gebastelt. Das hier vermeidet jedenfalls die Fehlermeldung. Das Editfeld bleibt allerdings leer. Hoffe, daß ich keinen weiteen Mist gebaut habe. Jedenfalls gehts bei mir jetzt mit allen Eingaben und Korrekturen.
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| with TEdit(Sender) do begin if Text='' then E:=0; if (Text = '') or (Text = '-') or (TextToFloat(PChar(Text), E, fvExtended)) then begin.. ... end; |
Falls du Berechnungen in der OnChange durchführen willst, mußt du das unten auch ändern:
Delphi-Quelltext 1: 2:
| if (Text <> '') and (Text <>'-') or (E=0) then |
Ansonsten bleibt halt der letzte gültige Wert für E stehen.
(Highlight für "or (E=0)" funktioniert nicht ??? )
|
|
|