gpt4 book ai didi

Delphi DBgrid 在错误更新时撤消更改

转载 作者:行者123 更新时间:2023-12-02 01:44:02 24 4
gpt4 key购买 nike

我在代码中对数据源的数据更改的编辑值进行了验证:

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;

在这种情况下,当输入不验证数据时,我需要撤消更改:

if not TryStrToInt64(sIDin) then
begin
Application.MessageBox('Not Hexadecimal!', '',MB_OK + MB_ICONWARNING);
Continue := false;
end;

例如,当我输入非十六进制值(“NONEHexa”)时,我需要从数据集中忽略该值。我尝试使用空 Field.Text := '' 设置字段,但当字段为空时,它会生成其他错误。

我怎样才能做到这一点?

============更新1

我的函数 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 库函数将十六进制字符串转换为二进制值,并检查该过程中是否消耗了字符串中的所有字符。

关于代码的三件事:

  1. 与其尝试在数据源的 OnDataChange 事件中进行验证,不如在字段OnValidate< 中进行验证 事件,提供该事件正是为了执行此类验证。有关详细信息,请参阅联机帮助。

  2. 您可以使用字段的 EditMask 属性来限制可以在其中输入的字符。再次参见 OLH。不过,我认为您不能使用 EditMask 将输入限制为十六进制字符。

  3. 您最好避免使用 Continue 作为变量。它对于编译器来说具有特殊的意义,与 for 循环的执行有关。再次,参见 OLH

更新:

I try, but i can see how to ensure the validation with TField OnValidate.. can you give an example!.. other question : When i use the OnValidate for field, it is possible to UNDO update on some field IF it's false? Example : when i enter a Non hexadecimal value, my field should rollback and not accept this value.. In my case, I can get this error on DataChange event. But before that when i click on other row, the wrong value seem be saved on my database!

保存了错误的值,因为当您单击另一个网格行而当前行有未保存的更改时,该更改会自动保存 - 这是 Delphi 数据集的标准行为。

如果要将字段值恢复为用户更改之前的值,最简单的方法是使用数据源的 OnDataChange 事件,而不是字段的 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 后恢复它们。

关于Delphi DBgrid 在错误更新时撤消更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39655978/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com