首页 > 解决方案 > 生成具有特定格式 ex 'PRT-00000' 的数字增加

问题描述

我想在 delphi 示例中为我的访问数据库创建自动编号:

我有一个带有零件名称的数据库,我想创建一个自动 id 来计算这些记录的数量并生成一个带有编号的名称作为“PRT-00000”,并在每次添加记录时将其增加一个并保持这种格式五位数,例如“PRT-00001”

请帮助我,非常感谢。

对不起我糟糕的英语

标签: delphi

解决方案


假设您的 Access 表名为“Parts”,并且有一个名为“ID”的自动编号字段和一个名为“PartNumber”的短文本字段。生成 PartNumber 值的一种方法是让 Access 为您计算它,但既然您询问了 Delphi,我将解释一种在 Delphi 中执行此操作的方法。

请开始一个新的、非常简单的项目,在主窗体上只包含以下项目:

  • 一个 TAdoConnection 配置为连接到您的数据库;
  • 一个 TAdoQuery 配置为使用 TAdoConnection,其 SQL.Text 属性设置为“从零件中选择 *”
  • 一个 TDataSource 和 TDBGrid 配置为显示 TAdoQuery 的内容。
  • 一个T按钮

然后,将以下代码添加到表单的单元中:

procedure TForm2.Button1Click(Sender: TObject);
begin
  NewPart;
end;

procedure TForm2.NewPart;
const
  sSelect = 'select * from Parts';
  sPrefix = 'PRT-';
  iDigits = 5;
var
  PartNumber : String;
  ID : Integer;
begin
  qryParts.Insert;

  try
    //  First, set the new record's PartNumber field to a temporary value
    qryParts.FieldByName('PartNumber').AsString := 'xxxx';

    // save the record so that we can then read the ID value Access has allocated to the record
    qryParts.Post;

    // read the ID value

    ID := qryParts.FieldByName('ID').AsInteger;

    //  next, construct the desired value for the PartNumber field based on the ID
    PartNumber := qryParts.FieldByName('ID').AsString;

    //  left-pad the PartNumber with zeroes
    while Length(PartNumber) < iDigits do
      PartNumber := '0' + PartNumber;

    // pre-pend the PRT- prefix
    PartNumber := sPrefix + PartNumber;

    // put qryParts into its dsEdit state
    qryParts.Edit;
    qryParts.FieldByName('PartNumber').AsString := PartNumber;

  finally
     // post the record back to the Parts table
    qryParts.Post;
  end;
end;

procedure TForm2.FormCreate(Sender: TObject);
begin
  qryParts.Open;
end;

更新我已经设法在将新部件发布到数据库之前获得新部件的自动编号 ID。要使用它,请添加NewAutoNumber函数并修改NewPart方法,如下所示。

function TForm2.NewAutoNumber(ATable, AColumn: String): Integer;
var
  vCat : OleVariant;
  vTable : OleVariant;
  vColumn : OleVariant;
begin
  vCat := CreateOleObject('ADOX.Catalog');
  vCat.ActiveConnection := AdoConnection1.ConnectionString;
  vTable := vCat.Tables[ATable];
  vColumn := vTable.Columns[AColumn];
  Result := vColumn.Properties['Seed'].Value;
end;

procedure TForm2.NewPart;
const
  sSelect = 'select * from Parts';
  sPrefix = 'PRT-';
  iDigits = 5;
var
  PrvSql : String;
  PartNumber : String;
  ID : Integer;
begin
  ID := NewAutoNumber('Parts', 'ID');
  try
    qryParts.Insert;
    qryParts.FieldByName('PartNumber').AsString := 'xxxx';
    qryParts.Post;

    if not qryParts.Locate('ID', ID, []) then begin
      raise exception.CreateFmt('Failed to create new Parts record with ID = %d', [ID]);
    end;

    PartNumber := qryParts.FieldByName('ID').AsString;

    while Length(PartNumber) < iDigits do
      PartNumber := '0' + PartNumber;
    PartNumber := sPrefix + PartNumber;

    qryParts.Edit;
    qryParts.FieldByName('PartNumber').AsString := PartNumber;
  finally
    qryParts.Post;
  end;
end;

更新 #2作为使用上述任一方法获取新添加的零件记录的 ID 值的替代方法,可以使用“选择@@identity”方法获取它。最简单的方法是在表单中添加另一个 TAdoQuery,qryAutoNumber,并添加此函数以获取 AutoNumber 值:

function TForm2.NewAutoNumberFromIdentity : Integer;
begin
  if qryAutoNumber.Active then
    qryAutoNumber.Close;
  qryAutoNumber.SQL.Text := 'select @@identity';
  qryAutoNumber.Open;
  Result := qryAutoNumber.Fields[0].AsInteger;
end;

请注意,要获取正确的 ID 值,应在调用后立即调用此函数qryParts.Post。但是,我仅出于完整性考虑将其包括在内,但据我所知,这在很大程度上是没有意义的,因为一旦发布了新的零件记录,就可以直接从ID.qryParts


推荐阅读