Advanced validation for stringGrid input in delphi
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;
精彩评论