2012-04-02 12 views
7

Normalnie bym wykonać następujące czynności, aby zapisać wartość ciągu do bazyJak mogę akceptować tylko liczby z formantu edycji?

DataModule.tbTableNumber.Value := StrToFloat(edtNumber.text); 

Teraz problem pojawia się, gdy użytkownik wprowadzi coś, co nie można przekonwertować na liczbę. Jak byłbym w stanie temu zapobiec? Czy dana osoba może używać wyjątku i jak mógłbym napisać ten wyjątek?

Używam Delphi XE2.

+0

Dlaczego nie używasz kontroli danych świadomy? podobnie jak [Vcl.DBCtrls.TDBEdit] (http://docwiki.embarcadero.com/Libraries/en/Vcl.DBCtrls.TDBEdit) – RRUZ

+0

Alternatywnym rozwiązaniem byłoby uniemożliwienie użytkownikowi wprowadzania nieprawidłowych danych w pierwszej kolejności. Możesz użyć kontrolki obsługującej maski wejściowe lub poradzić sobie z zdarzeniem 'TEdit.OnChange', aby uniemożliwić użytkownikowi wprowadzanie danych nieliczbowych. 'TEdit' również ma właściwość' NumbersOnly', ale nie uniemożliwia użytkownikowi kopiowania i wklejania nieprawidłowych danych do pola. –

+0

Jaką korzyść sprawdzi kontrola nad danymi ponad normę TEdit – Japster

Odpowiedz

11

The najlepszym rozwiązaniem (IMHO) jest użycie TryStrToFloat:

procedure TForm1.Button1Click(Sender: TObject); 
var 
    myfloat: double; 
begin 
    if TryStrToFloat(Edit1.Text, myfloat) then 
    DataModule.tbTableNumber.Value := myfloat 
    else 
    ShowMessage('Incorrect value.'); 
end; 

Nie sądzę, że używanie "try..except" jest szczególnie "czyste", gdy błąd jest tak banalny i, w rzeczywistości, zgodnie z oczekiwaniami, jak w tym przypadku.

+1

@Japster: Wynik konwersji łańcuch-float jest zapisywany w 'myfloat', to znaczy' TryStrToFloat (S, F) 'próbuje przekonwertować ciąg' S' na liczbę zmiennoprzecinkową. Jeśli się powiedzie, zwraca 'true', a wynik jest zapisywany w' myfloat'. Jeśli nie, zwraca 'false'. –

+1

@Andreas: całkowicie zgodzili się, że wyjątek powinien być stosowany w wyjątkowych przypadkach, a nie wtedy, gdy istnieje tak duża szansa, że ​​tak się dzieje rutynowo. –

5

można złapać wyjątek z następującym

try 
    val := StrToFloat(edtNumber.text); 
    except 
    on E: EConvertError do 
    begin 
     ShowMessage('Entered Data is not a valid Floating Point number'); 
    end; 
    end; 

Można również zajrzeć do

StrToFloatDef(edtNumber.text, -1) 

Jeśli wystarczy, aby zapewnić Ci konwertować zwraca prawidłowy numer

+0

Co powoduje, że StrToFloatDef (edtNumber.text, -1) ma dokładnie – Japster

+0

zwraca zwróconą domyślną wartość -1 w tym przypadku, jeśli ciąg nie reprezentuje poprawnej liczby – Dampsquid

+0

Istnieje również parametr 'TryStrToFloat (edtNumber.Text, val) ' – jasonpenny

1

Istnieje wiele elementów sterujących, które można powiedzieć tylko po to, aby zaakceptować wprowadzanie liczbowe, a to ma pewne zalety w stosunku do podejścia, które przyjęto jako odpowiedź.

Na przykład jedi JVCL library zawiera kilka cyfrowych kontrolek wejściowych, a podstawowy VCL zawiera kilka możliwości, w tym sterowanie Wirowanie Edycji, które służy do wprowadzania wartości całkowitych.

0

znalazłem rozwiązanie na http://www.festra.com/eng/snip05.htm

(kod z linku)

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char); 
begin 
    if not (Key in [#8, '0'..'9', '-', DecimalSeparator]) then begin 
    ShowMessage('Invalid key: ' + Key); 
    Key := #0; 
    end 
    else if ((Key = DecimalSeparator) or (Key = '-')) and 
     (Pos(Key, Edit1.Text) > 0) then begin 
    ShowMessage('Invalid Key: twice ' + Key); 
    Key := #0; 
    end 
    else if (Key = '-') and (Edit1.SelStart <> 0) then begin 
    ShowMessage('Only allowed at beginning of number: ' + Key); 
    Key := #0; 
    end; 
end; 
Powiązane problemy