开发者

Advanced validation for stringGrid input in delphi

开发者 https://www.devze.com 2023-02-11 10:04 出处:网络
I have a string grid where each co开发者_如何学Clumns have a different type of validation. For example, the first column accepts strings which match this regular expression [0-9]+[U-Wu-w] The second a

I have a string grid where each co开发者_如何学Clumns have a different type of validation. For example, the first column accepts strings which match this regular expression [0-9]+[U-Wu-w] The second and third column accepts only float numbers. I know there are many advanced tables which can be buy in the market, but that is a no go for me (in fact, my boss is against using anything that doesn't come with the delphi standard library) but I manage to use TPerlRegex after I show it was included in the newest versions.

If there is no straightforward way, what is the code for the validations? assuming that after each change the real numbers will be assigned to a variable of type double and then repainted? (which makes me loose the decimal separators)

EDIT: I should have written that the table represents values of some structures and this values should be setted only when the string matches the expressions.


Assuming formatting the string value in the stringgrid cell is the main issue,you might try checking if the string is a number, and if it is then

uses sysutils;

var 
inputstring:double;  
begin  // for columns 2 and 3 
 inputstring:=123.5678; //if it is input as a double 
 StringGrid2.Cells[0,1]:= FloatToStrF(inputstring, ffFixed, 8, 2);
end;

In the case of the first column, you might check for an integer in the first string position? Something like:

if copy(yourinputstring,1,1) in [0..9] then //for column 1 if a single digit starts the string
begin;
  validinput:=yourinputstring;
end;

or

if copy(yourinputstring,10,1) in [0..9] then //for column 1 if a the digit string is always 10 characters long
begin;
  validinput:=yourinputstring;
end;

You might also test if the entire string is characters versus characters plus numerals or entirely numerals: something like:

function StringIsDigit (const s: AnsiString):Boolean;
var      
I : Integer;
  begin
   Try
      Result := s <>'';
      for I:= 1 to Length(s) do
        begin
          if not (((s[i] >= '0') and (s[i] <= '9'))) then
            begin
              Result := False;
              Exit;
            end;
        end;

    except
    result:=false;
    end;

end;


Ok, I basically solved keeping a buffer to the last partially matched string and the last edited row and column, so at the end the code looks like

procedure TMyClass.MyStrGrdSetEditText(Sender: TObject; ACol, 
                                       ARow: Integer; const Value: string);
var
  filter : TPerlRegEx;
  matched : Boolean;
begin
  if DidCellChange(ACol, ARow) then begin // checks if I am editing another cell
    last_partially_matched_string_ := '';
    my_strgrd.Cells[last_edited_cell_column_, last_edited_cell_row] :=
       GetContentsOfCellFromDataStructure(last_edited_cell_column_,
                                          last_edited_cell_row);
  last_edited_cell_column_ := ACol;
  last_edited_cell_row_ := ARow;

  case ACol of
    0: filter := regex_filter_1;
    1: filter := regex_filter_2;
    2: filter := regex_filter_3;
    else Exit;
  end;

  filter.Subject := Value;
  matched := filter.Match;
  if matched and (filter.MatchedLength = Length(Value)) then begin
    last_partially_matched_string_ := Value;
    SetValueOnDataStructure(ARow, ACol, Value);
  end else if filter.PartialMatch and not matched then begin
    last_partially_matched_string_ := Value;
  end else begin
    my_strgrd.Cells[ACol, ARow] := last_partially_matched_string_;
  end;
end;
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号