delphi DBGrid1 获取选中 记录 ID  
官方Delphi 学习QQ群: 682628230(三千人)\n
频道

delphi DBGrid1 获取选中 记录 ID


delphi  DBGrid1 获取选中 记录 ID

在 Delphi 中获取 DBGrid 选中记录的 ID,有多种方法。以下是常用且可靠的实现方式:

🎯 核心方法
方法 1:通过 DataSource 获取当前记录(最常用)
pascal
procedure TForm1.Button1Click(Sender: TObject);
var
  SelectedID: Integer;
begin
  // 方法1:直接通过数据集获取当前记录
  if DataSource1.DataSet.Active and not DataSource1.DataSet.IsEmpty then
  begin
    SelectedID := DataSource1.DataSet.FieldByName('ID').AsInteger;
    ShowMessage('选中的记录ID: ' + IntToStr(SelectedID));
  end
  else
    ShowMessage('没有选中任何记录');
end;
方法 2:通过 DBGrid 的 SelectedRows 获取多选记录
pascal
procedure TForm1.Button1Click(Sender: TObject);
var
  i: Integer;
  SelectedIDs: string;
  Bookmark: TBookmark;
begin
  // 设置 DBGrid 支持多选
  // DBGrid1.Options := DBGrid1.Options + [dgMultiSelect];
  
  SelectedIDs := '';
  
  // 遍历选中的行
  for i := 0 to DBGrid1.SelectedRows.Count - 1 do
  begin
    // 保存书签位置
    Bookmark := DBGrid1.SelectedRows.Items[i];
    
    // 移动到该书签位置
    DataSource1.DataSet.GotoBookmark(Bookmark);
    
    // 获取 ID
    if not SelectedIDs.IsEmpty then
      SelectedIDs := SelectedIDs + ', ';
    SelectedIDs := SelectedIDs + DataSource1.DataSet.FieldByName('ID').AsString;
  end;
  
  if SelectedIDs.IsEmpty then
    ShowMessage('未选中任何记录')
  else
    ShowMessage('选中的记录ID: ' + SelectedIDs);
end;
方法 3:通过 DBGrid 的点击事件获取
pascal
procedure TForm1.DBGrid1CellClick(Column: TColumn);
var
  SelectedID: Integer;
begin
  // 点击单元格时自动获取当前记录ID
  if DataSource1.DataSet.Active and not DataSource1.DataSet.IsEmpty then
  begin
    SelectedID := DataSource1.DataSet.FieldByName('ID').AsInteger;
    StatusBar1.SimpleText := '当前选中记录ID: ' + IntToStr(SelectedID);
    
    // 或者存储到全局变量
    FCurrentID := SelectedID;
  end;
end;
方法 4:通过鼠标双击事件获取
pascal
procedure TForm1.DBGrid1DblClick(Sender: TObject);
var
  SelectedID: Integer;
begin
  if DataSource1.DataSet.Active and not DataSource1.DataSet.IsEmpty then
  begin
    SelectedID := DataSource1.DataSet.FieldByName('ID').AsInteger;
    
    // 打开编辑窗体等操作
    EditRecord(SelectedID);
  end;
end;
📋 完整示例代码
pascal
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, DBGrids, DB, ADODB, StdCtrls, Grids;

type
  TForm1 = class(TForm)
    DBGrid1: TDBGrid;
    DataSource1: TDataSource;
    ADOQuery1: TADOQuery;
    ButtonGetCurrent: TButton;
    ButtonGetSelected: TButton;
    ButtonGetByBookmark: TButton;
    procedure ButtonGetCurrentClick(Sender: TObject);
    procedure ButtonGetSelectedClick(Sender: TObject);
    procedure ButtonGetByBookmarkClick(Sender: TObject);
    procedure DBGrid1CellClick(Column: TColumn);
    procedure FormCreate(Sender: TObject);
  private
    FCurrentID: Integer; // 存储当前选中ID
    procedure ShowSelectedID(const Msg: string; ID: Integer);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  // 设置 DBGrid 支持多选(如果需要)
  DBGrid1.Options := DBGrid1.Options + [dgMultiSelect, dgRowSelect];
  
  // 打开数据集(示例)
  ADOQuery1.SQL.Text := 'SELECT ID, Name, Age FROM Users';
  ADOQuery1.Open;
end;

// 方法1:获取当前选中的记录ID(单行)
procedure TForm1.ButtonGetCurrentClick(Sender: TObject);
var
  ID: Integer;
begin
  if ADOQuery1.Active and not ADOQuery1.IsEmpty then
  begin
    ID := ADOQuery1.FieldByName('ID').AsInteger;
    ShowSelectedID('当前记录ID', ID);
  end
  else
    ShowMessage('数据集为空或未激活');
end;

// 方法2:获取所有选中的记录ID(支持多选)
procedure TForm1.ButtonGetSelectedClick(Sender: TObject);
var
  i: Integer;
  IDs: string;
  Bookmark: TBookmark;
begin
  IDs := '';
  
  if DBGrid1.SelectedRows.Count = 0 then
  begin
    ShowMessage('未选中任何记录');
    Exit;
  end;
  
  for i := 0 to DBGrid1.SelectedRows.Count - 1 do
  begin
    Bookmark := DBGrid1.SelectedRows.Items[i];
    ADOQuery1.GotoBookmark(Bookmark);
    
    if IDs <> '' then
      IDs := IDs + ', ';
    IDs := IDs + ADOQuery1.FieldByName('ID').AsString;
  end;
  
  ShowMessage('选中的记录ID: ' + IDs);
end;

// 方法3:使用书签方式获取(精确控制)
procedure TForm1.ButtonGetByBookmarkClick(Sender: TObject);
var
  CurrentBookmark: TBookmark;
  ID: Integer;
begin
  if ADOQuery1.Active and not ADOQuery1.IsEmpty then
  begin
    // 保存当前书签
    CurrentBookmark := ADOQuery1.GetBookmark;
    try
      // 获取当前记录的ID
      ID := ADOQuery1.FieldByName('ID').AsInteger;
      ShowSelectedID('当前记录ID(书签方式)', ID);
    finally
      // 释放书签
      ADOQuery1.FreeBookmark(CurrentBookmark);
    end;
  end;
end;

// 点击DBGrid单元格时更新当前ID
procedure TForm1.DBGrid1CellClick(Column: TColumn);
begin
  if ADOQuery1.Active and not ADOQuery1.IsEmpty then
  begin
    FCurrentID := ADOQuery1.FieldByName('ID').AsInteger;
    // 可以更新状态栏或做其他处理
    if Assigned(StatusBar1) then
      StatusBar1.SimpleText := '当前选中ID: ' + IntToStr(FCurrentID);
  end;
end;

// 辅助方法:显示选中ID
procedure TForm1.ShowSelectedID(const Msg: string; ID: Integer);
begin
  ShowMessage(Msg + ': ' + IntToStr(ID));
end;

end.
🔧 进阶技巧
1. 通过列名动态获取ID(支持不同数据集)
pascal
function GetCurrentRecordID(DataSet: TDataSet; const IDFieldName: string = 'ID'): Variant;
begin
  Result := Null;
  if Assigned(DataSet) and DataSet.Active and not DataSet.IsEmpty then
    Result := DataSet.FieldByName(IDFieldName).Value;
end;

// 使用示例
var
  ID: Variant;
begin
  ID := GetCurrentRecordID(DataSource1.DataSet, 'UserID');
  if not VarIsNull(ID) then
    ShowMessage('ID: ' + VarToStr(ID));
end;
2. 获取ID并自动处理主键字段名
pascal
function GetPrimaryKeyValue(DataSet: TDataSet): Variant;
var
  i: Integer;
begin
  Result := Null;
  if Assigned(DataSet) and DataSet.Active and not DataSet.IsEmpty then
  begin
    // 尝试获取主键字段(如果支持)
    if DataSet is TADOQuery then
    begin
      // ADO 方式
      for i := 0 to DataSet.FieldCount - 1 do
      begin
        if (DataSet.Fields[i] is TAutoIncField) or 
           (pfInKey in DataSet.Fields[i].ProviderFlags) then
        begin
          Result := DataSet.Fields[i].Value;
          Break;
        end;
      end;
    end
    else
    begin
      // 默认查找 ID 字段
      if DataSet.FindField('ID') <> nil then
        Result := DataSet.FieldByName('ID').Value;
    end;
  end;
end;
3. 在DBGrid的OnDrawColumnCell中显示选中状态
pascal
procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
  DataCol: Integer; Column: TColumn; State: TGridDrawState);
begin
  // 高亮当前选中行
  if gdSelected in State then
  begin
    DBGrid1.Canvas.Brush.Color := clHighlight;
    DBGrid1.Canvas.Font.Color := clHighlightText;
  end;
  
  // 绘制单元格内容
  DBGrid1.DefaultDrawColumnCell(Rect, DataCol, Column, State);
end;
⚠️ 注意事项
数据集状态:确保在获取ID前数据集已激活且不为空

字段名:根据实际表结构修改 'ID' 字段名(可能是 'UserID'、'CustomerID' 等)

空值处理:ID字段可能为 Null,使用 AsInteger 或 AsString 前应先判断

多选模式:启用 dgMultiSelect 选项后,当前记录可能不是选中的记录

性能考虑:大量数据时,频繁调用 FieldByName 会影响性能,可缓存字段对象

pascal
// 优化:缓存字段对象
private
  FIDField: TField;
  
procedure TForm1.FormCreate(Sender: TObject);
begin
  ADOQuery1.Open;
  FIDField := ADOQuery1.FieldByName('ID'); // 缓存字段引用
end;

procedure TForm1.ButtonClick(Sender: TObject);
begin
  if Assigned(FIDField) and not ADOQuery1.IsEmpty then
    ShowMessage('ID: ' + FIDField.AsString);
end;
🎯 推荐做法
对于大多数场景,方法1 最直接、最高效。如果需要支持多选或特殊交互,使用方法2或方法4。记得在事件处理前检查数据集的激活状态和是否为空。



推荐分享
图文皆来源于网络,内容仅做公益性分享,版权归原作者所有,如有侵权请告知删除!
 

Copyright © 2014 DelphiW.com 开发 源码 文档 技巧 All Rights Reserved
晋ICP备14006235号-8 晋公网安备 14108102000087号

执行时间: 0.046304941177368 seconds