You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delphi表单验证异常:条件未满足仍触发数据库上传且报无效整数错误

Delphi表单数据上传验证逻辑问题分析与修复

问题根源

你的代码存在两个核心问题,导致空值检查不通过时仍触发数据库上传并报错:

  1. 空值检查后未终止流程:即使空值验证失败(弹出"Complete All Fields!"),后续代码仍会继续执行,包括对vidn的字符串截取和strtoint转换——当vidn为空时,copy(vidn,1,2)返回空字符串,strtoint就会抛出"is not a valid integer"错误。
  2. 验证顺序不合理:依赖vidn的年龄计算逻辑,放在了空值检查之后但没有阻断,导致无效数据进入转换流程。

关键修复点

  • 空值验证失败时,立即调用Exit终止整个按钮点击事件流程,避免后续无效代码执行。
  • 在对vidn执行strtoint前,先检查其是否为纯数字,防止非数字字符触发转换错误。
  • 调整验证顺序,先完成所有基础格式验证,再执行业务逻辑检查(如年龄、重复ID)。

修正后的代码

unit Unit6;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Spin, ExtCtrls,unit7,unit5,unit4, DB, ADODB, Grids, DBGrids,
  pngimage;

type
  Tfrmupload = class(TForm)
    Panel1: TPanel;
    edtname: TEdit;
    edtsurn: TEdit;
    edtidn: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    Panel2: TPanel;
    btnupload: TButton;
    edtmail: TEdit;
    cbprov: TComboBox;
    Image1: TImage;
    cbdiv: TComboBox;
    Label4: TLabel;
    procedure btnuploadClick(Sender: TObject);
    procedure Label7Click(Sender: TObject);
  private
    { Private declarations }
    function IsStringNumeric(const S: string): Boolean;
  public
    { Public declarations }
  end;

var
  frmupload: Tfrmupload;

implementation

{$R *.dfm}

// 辅助函数:检查字符串是否为纯数字
function Tfrmupload.IsStringNumeric(const S: string): Boolean;
var
  I: Integer;
begin
  Result := True;
  for I := 1 to Length(S) do
    if not (S[I] in ['0'..'9']) then
    begin
      Result := False;
      Break;
    end;
end;

procedure Tfrmupload.btnuploadClick(Sender: TObject);
var
  vname, vsurname, c, vidn, vprov, vmail, vdiv: string;
  year, i, age: Integer;
  bnotnull, bidl, bmail, byoung, valid, idrepeated: Boolean;
  dt: TDateTime;
begin
  vname := edtname.Text;
  vsurname := edtsurn.Text;
  vidn := edtidn.Text;
  vdiv := cbdiv.Text;
  vprov := cbprov.Text;
  vmail := edtmail.Text;

  // 初始化验证标记
  bnotnull := False;
  bidl := False;
  bmail := False;
  byoung := False;
  idrepeated := False;
  valid := False;

  // 1. 空值检查:不通过直接终止流程
  if (vname = '') or (vsurname = '') or (vidn = '') or (vprov = '') or (vmail = '') or (vdiv = '') then
  begin
    ShowMessage('Complete All Fields!');
    Exit; // 终止后续代码执行
  end;
  bnotnull := True;

  // 2. ID格式检查:长度+纯数字验证
  if Length(vidn) <> 13 then
  begin
    ShowMessage('ID Number must be 13 characters');
    Exit;
  end;
  bidl := True;

  if not IsStringNumeric(vidn) then
  begin
    ShowMessage('ID Number must contain only digits');
    Exit;
  end;

  // 3. 重复ID检查
  if unit5.frmadmin.ADODetails.Locate('ID number', vidn, []) then
  begin
    ShowMessage('ID Number already exists');
    idrepeated := True;
    Exit;
  end;

  // 4. 年龄计算与合法性检查
  dt := Now;
  year := StrToInt(FormatDateTime('yyyy', dt));
  c := Copy(vidn, 1, 2);
  
  if (StrToInt(c) >= 0) and (StrToInt(c) <= 22) then
    age := year - (2000 + StrToInt(c))
  else
    age := year - (1900 + StrToInt(c));

  if age < 6 then
  begin
    ShowMessage('Contestant too young, cannot compete');
    byoung := True;
    Exit;
  end;

  // 5. 邮箱格式检查(基础版,可扩展更严格规则)
  bmail := Pos('@', vmail) > 1; // @不能在开头,且至少存在一个
  if not bmail then
  begin
    ShowMessage('Incorrect Email Format');
    Exit;
  end;

  // 所有验证通过,执行数据库上传
  valid := True;
  if valid then
  begin
    unit5.frmadmin.ADODetails.Append;
    unit5.frmadmin.ADODetails['Name(s)'] := vname;
    unit5.frmadmin.ADODetails['Surname'] := vsurname;
    unit5.frmadmin.ADODetails['ID Number'] := vidn;
    unit5.frmadmin.ADODetails['Age'] := age;
    unit5.frmadmin.ADODetails['Province'] := vprov;
    unit5.frmadmin.ADODetails['Email'] := vmail;
    unit5.frmadmin.ADODetails.Post;

    unit4.frmcontest.ADOLead.Insert;
    unit4.frmcontest.ADOLead['ID Number'] := unit4.frmcontest.DBComboID.Text;
    unit4.frmcontest.ADOLead['Name(s)'] := unit4.frmcontest.DBCombonme.Text;
    unit4.frmcontest.ADOLead['Division'] := vdiv;
    unit4.frmcontest.ADOLead.Post;

    ShowMessage('Details Uploaded');
    frmupload.Hide;
  end;

  // 清空输入
  edtname.Clear;
  edtsurn.Clear;
  edtidn.Clear;
  cbdiv.Text := '';
  cbprov.Text := '';
  edtmail.Clear;
end;

procedure Tfrmupload.Label7Click(Sender: TObject);
begin
  frmupload.Hide;
end;

end.

额外说明

  • 添加了IsStringNumeric辅助函数,确保vidn是纯数字后再执行转换,避免类型错误。
  • 每个验证步骤不通过时都立即Exit,彻底阻断后续无效代码,包括数据库上传逻辑。
  • 邮箱验证做了简单优化,确保@不在字符串开头,你可以根据需求扩展为更严格的正则验证。

内容的提问来源于stack exchange,提问作者Mr Engine

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 17:45:42