2012-04-02 7 views
7

Normalmente yo hacer lo siguiente para guardar un valor de cadena en la base de datos¿Cómo puedo aceptar solo números de un control de edición?

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

Ahora el problema viene cuando el usuario entra en algo que no se puede convertir en un número. ¿Cómo podría evitar esto? ¿Puede una persona usar una excepción y cómo escribiría esta excepción?

Estoy usando Delphi XE2.

+0

¿Por qué no está usando los controles de reconocimiento de datos? como [Vcl.DBCtrls.TDBEdit] (http://docwiki.embarcadero.com/Libraries/en/Vcl.DBCtrls.TDBEdit) – RRUZ

+0

Un enfoque alternativo sería evitar que el usuario ingrese datos no válidos en primer lugar. Podría usar un control que admita máscaras de entrada o podría manejar el evento 'TEdit.OnChange' para evitar que el usuario ingrese datos no numéricos. 'TEdit' también tiene una propiedad' NumbersOnly' pero no evitará que el usuario copie y pegue datos no válidos en el campo. –

+0

¿Qué beneficio me dará un control de datos sobre un TEdit normal – Japster

Respuesta

11

El La mejor solución (en mi humilde opinión) es usar 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; 

No creo que sea particularmente 'limpio' utilizar un try..except cuando el error es tan trivial y, de hecho, como se esperaba, como en este caso.

+1

@Japster: El resultado de la conversión de cadena a flotante se guarda en 'myfloat', es decir,' TryStrToFloat (S, F) 'intenta convertir la cadena' S' en un número de coma flotante. Si tiene éxito, devuelve 'true' y el resultado se guarda en' myfloat'. Si no, devuelve 'falso'. –

+1

@Andreas: estoy totalmente de acuerdo en que Exception debería usarse para casos excepcionales, no cuando existe una posibilidad tan buena de que ocurra de manera rutinaria. –

5

Puede detectar la excepción con el siguiente

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

También puede ser que desee mirar a

StrToFloatDef(edtNumber.text, -1) 

Si sólo tiene que asegurarse de que convertir devuelve un número válido

+0

qué hace StrToFloatDef (edtNumber.text, -1) exactamente – Japster

+0

devuelve el valor pasado en valor predeterminado -1 en este caso, si la cadena no representa un número válido – Dampsquid

+0

También hay 'TryStrToFloat (edtNumber.Text, val) ' – jasonpenny

1

Hay muchos controles que pueden ser contados solo para aceptar entradas numéricas, y esto tiene algunos beneficios sobre el enfoque que usted aceptó como respuesta.

Por ejemplo, el jedi JVCL library incluye varios controles de entrada numéricos y el VCL básico incluye algunas posibilidades, incluido el control Spin Edit, que es para la entrada de valores enteros.

0

He encontrado solución en http://www.festra.com/eng/snip05.htm

(código de enlace)

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; 
Cuestiones relacionadas