Recent

Author Topic: [SOLVED] DBGrid Class: EDatabaseError Mensaje: "1.650,00" is not a valid float  (Read 887 times)

lainz

  • Hero Member
  • *****
  • Posts: 4468
    • https://lainz.github.io/
When I'm editing on a DBGrid and I type a float with a wrong format like this one: "1.650,00" I get an exception like this:

Class: EDatabaseError
Mensaje: "1.650,00" is not a valid float


There's a way to prevent the exception? And give the user a proper error message, like: 'The number you entered has a wrong format, please try again.' or something around the lines.

Thanks.
« Last Edit: July 05, 2022, 02:00:50 am by lainz »

wp

  • Hero Member
  • *****
  • Posts: 11910
I had thought this would be easier...

DBGrid inherits from its ancestors the event OnValidateEntry, however, it is declared only as protected and thus not accessible by the standard DBGrid. But it can easily be subclassed it to make the event public. Add the following declaration to the top of the form with the DBGrid (or to a separate unit which must be at the end of the uses line!):

Code: Pascal  [Select][+][-]
  1. type
  2.   TDBGrid = class(DBGrids.TDBGrid)
  3.   public
  4.     propety OnValidateEntry;
  5.   end;

Then write a handler for this event, something like this:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.ValidateEntryHandler(Sender: TObject; ACol, ARow: Integer;
  2.   const OldValue: string; var NewValue: String);
  3. var
  4.   x: Double;
  5. begin
  6.   if (DBGrid1.SelectedField is TFloatField) and not TryStrToFloat(NewValue, x) then
  7.   begin
  8.     MessageDlg(NewValue + ' is not a valid float.', mtError, [mbOK], 0);
  9.     Abort;
  10.   end;
  11. end;

Assign this handler to the DBGrid before its usage, e.g. in the form's OnCreate event:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormCreate(Sender: TObject);
  2. begin
  3.   ...
  4.   DBGrid1.OnValidateEntry := @ValidateEntryHandler;
  5. end;

korba812

  • Sr. Member
  • ****
  • Posts: 394
You can validate input text in TField.OnSetText event, and raise an EAbort exception if the value is invalid or just leave contents of field unchanged.
« Last Edit: July 05, 2022, 01:00:58 am by korba812 »

lainz

  • Hero Member
  • *****
  • Posts: 4468
    • https://lainz.github.io/
@wp thanks, but unfortunately that code didn't work. I've tested on Lazarus 2.2.2 32 bit on Windows.

@korba812 thanks that worked!

Code: Pascal  [Select][+][-]
  1.  
  2. ...
  3.  
  4. sqlqyProductos.Fields.FieldByName('Stock_Fisico').OnSetText:=@OnSetTextStockFisico;
  5.  
  6. ...
  7.  
  8.  
  9. procedure TfrmInventario.OnSetTextStockFisico(Sender: TField;
  10.   const aText: string);
  11. var
  12.   o: double;
  13. begin
  14.   if not TryStrToFloat(aText, o) then
  15.   begin
  16.     MessageDlg(aText + ' NO es un número con un formato correcto.', mtError, [mbOK], 0);
  17.     Abort;
  18.   end
  19.   else
  20.   begin
  21.     Sender.Value := o;
  22.   end;
  23. end;

wp

  • Hero Member
  • *****
  • Posts: 11910
@wp thanks, but unfortunately that code didn't work. I've tested on Lazarus 2.2.2 32 bit on Windows.
Strange, I had tested it before posting, and it had worked. But anyway, korba812's solution is much better because input validation should not be performed by the visual controls but by the database itself.

 

TinyPortal © 2005-2018