Test auf float-Werte mit try...catch - ist das ok?


  • Mod

    Hallo

    @Joe_m

    eine Prüfung zur Laufzeit, ob ein Floatwert eingegeben wurde ist extrem aufwändig

    extrem -> ein 4 Zeiler
    zwei if-Abfrage - mehr nicht
    (wegen Eingabe . und , um das ganze fuer alle Anwender bedienbar zu machen)

    (dazu gehoert natuerlich auch noch in OnExit die Anpassung der Anzeige 3 ->3.00 wenn ueberhaupt noetig)

    MfG
    Klaus



  • Marc++us' Sekretär schrieb:

    Und wie unterbinde ich die Möglichkeit, in einem StringGrid die Eingabe von Buchstaben etc. zuzulassen, so dass nur . , 0..9 erlaubt sind?

    Ich rate davon dringed ab. Nur eines ist nerviger für den Benutzer als die Eingabe auf bestimmte Tasten zu beschränken: Formatprüfung während der Eingabe.

    Wie bereits erwähnt, klemmst du damit wahrscheinlich auch die Zwischenablage ab. Zudem musst du noch - und e/E zulassen. Oder willst du dem Benutzer zumuten, 1e100 ausschreiben zu müssen?

    Außerdem bringt es einfach nichts. Die Beschränkung auf bestimmte Zeichen garantiert dir keine richtig formatierte Zahl. Beispiel: .2,.5-3,8ee-

    Jetzt könnte man darauf kommen, schon bei der Eingabe das Format der Zahl zu prüfen. Aber das finde ich, wie gesagt, noch schlimmer. Angenommen, ich will das Komma bei einer eingegebenen Zahl verschieben. Dann würde mich das Programm dazu zwingen, zuerst das alte Komma zu entfernen, bevor ich das neue setzen kann. Das nervt gewaltig.

    Bleib bei der Prüfung nach der Eingabe. Und bleib bei der fertigen Funktion.



  • @all:
    Danke, ich belasse es also erst einmal dabei, mit try...catch das gesamte Grid nach erfolgter Eingabe auf gültige floats zu testen.



  • Mit einem 4-Zeiler? Den möchte ich sehen... 😉

    Den brauch ich ja schon fast um das Dezimaltrennzeichen aus den Windows-Einstellungen zu lesen. 😉
    Ansonsten muß man auf - (eventuell auch +) an erster Stelle des 'Textes' prüfen, dann, je nach Dezimaltrennzeichen alle (überflüssigen) Punkte oder Kommas ingnorieren, prüfen, ob das Dezimaltrennzeichen nur einmal vokommt und ob der Rest nur aus Zahlen besteht. Das Ganze kann dann nur noch in der OnChange des Edits (oder was auch immer) gemacht werden, da sonst wieder das Einfügen der Zwischenablage nicht überprüft werden kann. Aber hier ist es dann nicht mehr so einfach ein Zeichen zu 'verwerfen'.

    EDIT: Ups, ich sollte mir beim posten wohl nicht so viel Zeit lassen, der letzte Beitrag, den ich gelesen hatte, war der von KlausB...



  • Also ich hab' mal so einen Test gemacht:

    void __fastcall TForm1::ParamCheck(TObject *Sender)               //Testet, ob Eingabewert gueltig ist
    {
      static Checking=false;
      AnsiString AS;
      double Value;
      TEdit *Edit;
      Edit=(TEdit*)Sender;                                            //zu testendes Edit
      if (!Checking)                                                  //keine Rekursionen!!!
      {
        Checking=true;
        try
        {
          AS=Edit->Text;                                              //String fuer Debugger
          Value=Edit->Text.ToDouble();                                //Wert aus Eingabe
          Edit->ClearUndo();                                          //Rueckgaengig aus!
          Checking=false;
        }
        catch(EConvertError &e)                                       //bei Konvertierungsfehler - falsche Zeichen
        {
          Edit->Undo();                                               //Rueckgaengig
          Checking=false;
        }
      }
      else
        Edit->ClearUndo();                                            //Rueckgaengig aus!
    }
    

    Diese Funktion rufe ich in jedem TEdit bei OnChange auf!

    Bei Fehleingaben wird sofort!!! korrigierend eingegriffen!
    Das kann noch mit nem Peep oder ner Message erweitert werden.



  • DerAltenburger schrieb:

    Diese Funktion rufe ich in jedem TEdit bei OnChange auf!

    Bei Fehleingaben wird sofort!!! korrigierend eingegriffen!

    Das meinte ich. Bei einem Programm, das mich derart bevormundet, suche ich innerhalb kürzester Zeit nach einem Button mit der Aufschrift "ICH WAR NOCH NICHT FERTIG!". Warum muss, wenn ich den Inhalt eines Eingabefeldes ändere, jeder einzelne Zwischenschritt der Änderung ein gültiges Format haben?

    Das kann noch mit nem Peep oder ner Message erweitert werden.

    Das setzt dem Ganzen noch eins drauf. Was würdest du von einer Entwicklungsumgebung halten, die bei jeder Änderung im Quelltext eine Syntaxprüfung macht und dich mit einer MessageBox auf Fehler hinweist?



  • Sehe ich genauso. Wenn überhaubt, dann würde ich die Eingabe auf 0..9 "," "." "e" "E" beschränken und eine endgültige Gültigkeitsprüfung am ende machen. Alles andere ist nur nervig.



  • Nun ja, ich bin der Meinung, dass die Vorgehensweise vom Umfeld abhängt. Grundsätzlich stimme ich MFK zu: Keine Überprüfung in der OnChange() (es sei denn um den Button zum Verlassen des Forms zu deaktivieren...).

    Wenn auf dem Form grundsätzlich in allen Feldern nur Zahleneingaben gemacht werden dürfen, macht es vielleicht noch Sinn, die Eingabe zu beschränken. Wenn es aber auch reine Textfelder gibt, mache ich überhaupt keine Einschränkung. Dann kann der User, wenn er sich im Feld vertan hat noch mit Cut and Paste arbeiten. Ich mache das normalerweise ohne irgendeine Beschränkung bei der Eingabe und prüfe in der OnExit(), ob ein gültiger Wert eingeben wurde. Ich habe allerdings auch Eingabemasken, da wird erst bei dem Versuch das Formular zu verlassen (oder was mit den Daten zu machen) eine Prüfung für alle Werte durchgeführt. Dies macht zum Beispiel Sinn, wenn sich Eingaben gegenseitig ausschließen, man aber nicht für jede Änderung in einem Feld alle abhängingen Komponenten (egal ob Edit oder ListBox usw) neu initialisieren möchte oder kann.



  • MFK schrieb:

    DerAltenburger schrieb:

    Diese Funktion rufe ich in jedem TEdit bei OnChange auf!

    Bei Fehleingaben wird sofort!!! korrigierend eingegriffen!

    Das meinte ich. Bei einem Programm, das mich derart bevormundet, suche ich innerhalb kürzester Zeit nach einem Button mit der Aufschrift "ICH WAR NOCH NICHT FERTIG!"...

    Das hat doch mit "Bevormunden" nichts zu tun! Das vermeidet doch nur Fehleingaben - OHNE dass sich der User darum kümmern muss!

    PS:
    Diese Kontrollroutine nutze ich natürlich nur bei TEdits fuer Dezimalzahleingabe!
    Für allgemeine Eingaben ist das VÖLLIG unbrauchbar. Aber um Zahleneingaben ging es ja wohl in dem Thread.



  • DerAltenburger schrieb:

    Das hat doch mit "Bevormunden" nichts zu tun! Das vermeidet doch nur Fehleingaben - OHNE dass sich der User darum kümmern muss!

    Wirft ToDouble() bei einem String wie "1.000000.0" (also mit zwei Dezimaltrennzeichen) eine Exception? Falls ja, folgendes Beispiel:

    Ich habe in einem TEdit die Zahl 1000000.0 stehen und möchte daraus 1.0000000 machen. Ich würde das so machen, dass ich zuerst die Einfügemarke hinter die 1 setze, einen Punkt eingebe, dann mit der Ende-Taste nach hinten springe, ein Zeichen nach links gehe, und mit der Entfernen-Taste den hinteren Punkt lösche. Deine Fehleingabenvermeidungsfunktion lässt das aber nicht zu. Sie zwingt mich dazu, zuerst den Punkt hinten zu entfernen, bevor ich Punkt vorne eingeben kann.

    Das ist für mich Bevormundung des Benutzers, und auf jeden Fall ein Grund, diese Software nicht zu benutzen.

    Worauf ich hinaus will: Du kannst in OnChange nicht wissen, ob der Benutzer mit der Eingabe fertig ist. Und solange solltest du IMHO die Eingabe auch nicht auswerten.



  • MFK hat absolut recht. der Richtige Ort für so eine Routine ist OnExit...

    -junix



  • OK!

    Überzeugt - OnExit ist besser. 😉

    Aber dann auch bei Eingabe von <Return>! 😉

    PS:

    ToDouble() wirft bei 2 Kommas eine Exception.
    Dann muss das falsche zuerst raus! Das kann manchmal stören. 😕


  • Mod

    Hallo

    zum eigentlichen Thema ist zu sagen
    OnExit wird beim StringGrid erst ausgeloest, wenn das StringGrid verlassen wird
    -> ist also in dem speziellen Fall untauglich (oder)

    in OnKeyPressed kann man eine Vorpruefung machen, um nur Tasten zuzulassen
    die erlaubt sind (4-Zeiler)

    und in OnExit die Zahlen normieren (auf das gewuenschte Format)

    (aber das habe ich ja schonmal geschrieben)

    Ich halte nichts davon einen Bediener (einer Software) erst dutzende Eingaben machwen zu lassen und dann wenn er meint er sei fertig zusagen
    da sind Fehler drinnen (such sie doch oder so)

    mit OnKexPressed kann man sicher nicht alle Fehler vermeiden - aber 99%

    MfG
    Klaus


Anmelden zum Antworten