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