我在我的代码中对我的数据源的数据更改进行了编辑值的验证:
procedure TForm1.DataSource1DataChange(Sender: TObject; Field: TField);
var
sIDin :string;
Continue :boolean;
begin
Continue := True;
if (Table1.RecordCount <> 0 )and (Field <> Nil) then
begin
//////////
if (Field.Text = '') then //(1)
begin
Application.MessageBox('is Empty!','',MB_OK + MB_ICONWARNING);
Continue := false;
end
else if (Field.FieldName <> 'GaName') and (Field.FieldName <> 'MnName' )then
begin
sIDin := '$0' + Field.Text;
if not TryStrToInt64(sIDin) then
begin
Application.MessageBox('Not Hexadecimal!', '',MB_OK + MB_ICONWARNING);
Continue := false;
//Field.Text := ''; // here i need to set my filed empty not with wrong value.
// So i use this line ..
// but it generate an error (1)
end;
end;
if Not(Continue) then
abort
end;
inherited ;
end;
在这种情况下,我需要在输入not validate data时撤消更改:
if not TryStrToInt64(sIDin) then
begin
Application.MessageBox('Not Hexadecimal!', '',MB_OK + MB_ICONWARNING);
Continue := false;
end;
示例当我输入一个非十六进制值('NONEHexa'),我需要从我的数据集中忽略这个值。我尝试将我的字段设置为空Field.Text := ''
,但当我的字段为空时,它会产生其他错误。
我怎么能那样做呢?
============ Update1
my function TryStrToInt64:
function TryStrToInt64(InputString : string) : boolean ;
var
iValue64 :Int64;
begin
try
iValue64 := StrToInt64(InputString);
Except
on E : EConvertError do
begin
Result:= false;
exit;
end;
end;
Result:=true;
end;
不要尝试将字段值转换为整数,您可以测试它的每个字符在十六进制字符串中是否有效,像这样:
function ValidHex(Input : String) : Boolean;
var
i : Integer;
begin
Result := False;
// If Input is empty, it can't be valid Hex
if Input = '' then exit;
// Valid Hex must have an even number of characters
if Odd(Length(Input)) then exit;
for i := 1 to Length(Input) do
if not (CharInSet(Input[i], ['0'..'9', 'A'..'F', 'a'..'f'])) then
exit;
Result := True;
end;
当然,您可以使用HexToBin库函数将十六进制字符串转换为二进制值,并检查字符串中的所有字符是否在此过程中被消耗。
关于代码的三件事:
与其尝试在数据源的
OnDataChange
事件中进行验证,不如在字段的OnValidate
事件中进行验证,该事件恰好提供了这种验证。您可以使用字段的
EditMask
属性来限制可以输入的字符。再次,参见OLH。我不认为你可以使用EditMask来限制输入十六进制字符,虽然。最好避免使用
Continue
作为变量。它对编译器有特殊的意义,与for
循环的执行有关。同样,参见OLH
我尝试,但我可以看到如何确保验证与TField OnValidate..你能举个例子吗?其他问题:当我使用OnValidate字段,有可能撤消更新的一些字段,如果它是假的?例如:当我输入一个非十六进制值时,我的字段应该回滚,不接受这个值。在我的情况下,我可以在datachchange事件上得到这个错误。但在此之前,当我点击其他行,错误的值似乎保存在我的数据库!
错误的值被保存,因为当你点击另一个网格行时,当前行有一个未保存的更改,该更改将自动保存-这是Delphi数据集的标准行为。
如果您想将字段值恢复到用户更改之前的值,最简单的方法是使用数据源的ondatachchange事件,而不是字段的OnValidate事件。下面对Field.DataSet.Cancel
的调用将恢复字段的值:
procedure TForm1.DataSource1DataChange(Sender: TObject; Field: TField);
begin
if Field = Nil then Exit;
// First, check that the Field is the one we're interested in
if Field = Field.DataSet.FieldByName('Value') then begin
if not ValidHex(Field.AsString) then begin
ShowMessageFmt('Invalid value: %s for field: %s', [Field.AsString, Field.FieldName]);
Field.DataSet.Cancel;
end;
end;
end;
但是,要注意,这会将任何其他未保存的更改还原到同一行。为了能够只恢复对"十六进制"字段的更改将会复杂得多-我认为您必须将其他更改的值保存在某个地方,并在调用Cancel
后恢复它们。