Delphi: TDBGrid 未更新
Delphi: TDBGrid not update
我有一个表格,其中有一个 DataSource,AdoQuery,AdoConnection,DBgrid
加上一对 edit
和一个 memo
。
用户输入他的用户名、街道地址等,然后点击 'save' 按钮。当时,应用程序将详细信息写入逗号分隔的 txt 文件,该文件连接到 Access 链接 table。当用户点击 'save' 按钮时,它会立即写入备忘录,但不会实时更新 dbgrid 数据库,只有在重新打开应用程序时才会如此。
我搜索了很多,但每个人都有不同的建议:做一个dbgrid refresh, adorequery, post, append, showmodal, open and close the database
等等
我的问题是为什么 dbgrid liveupdate 不起作用?
源代码如下:
unit test;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, StrUtils, Grids, Buttons, pngimage, ExtCtrls,
ComCtrls, DBGrids, DB, DBTables, ColorGrd, DirOutln, ADODB,
FMTBcd, SqlExpr, DBCtrls, DBClient, jpeg;
type
TForm1 = class(TForm)
Memo1: TMemo;
exit: TButton;
resetbtn: TButton;
Label3: TLabel;
GroupBox1: TGroupBox;
Label7: TLabel;
Label8: TLabel;
GroupBox2: TGroupBox;
Label1: TLabel;
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
Generate: TButton;
GroupBox3: TGroupBox;
Label5: TLabel;
Label6: TLabel;
CheckBox1: TCheckBox;
Image1: TImage;
Image2: TImage;
Button6: TButton;
DateTimePicker1: TDateTimePicker;
GroupBox4: TGroupBox;
Label10: TLabel;
Label9: TLabel;
dellastentry: TButton;
ADOConnection1: TADOConnection;
ADOQuery1: TADOQuery;
DataSource1: TDataSource;
DBGrid1: TDBGrid;
Label13: TLabel;
Label14: TLabel;
Label16: TLabel;
Label17: TLabel;
Label18: TLabel;
Label2: TLabel;
Label4: TLabel;
Label11: TLabel;
Label15: TLabel;
ADOQuery1Username: TWideStringField;
ADOQuery1RequestedNumber: TWideStringField;
ADOQuery1AllocatedNumber: TWideStringField;
ADOQuery1DateofRequest: TWideStringField;
procedure exitClick(Sender: TObject);
procedure resetbtnClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure dellastentryClick(Sender: TObject);
procedure GenerateClick(Sender: TObject);
procedure CheckBox1Click(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure Button6Click(Sender: TObject);
procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
function GetCurrentUserName: string;
const
cnMaxUserNameLen = 50;
var
sUserName: string;
dwUserNameLen: DWORD;
begin
dwUserNameLen := cnMaxUserNameLen - 1;
SetLength(sUserName, cnMaxUserNameLen);
GetUserName(PChar(sUserName), dwUserNameLen);
SetLength(sUserName, dwUserNameLen);
Result := sUserName;
end;
procedure TForm1.exitClick(Sender: TObject);
begin
Memo1.Lines.SaveToFile('C:\Numbergen\NumberDB.txt');
form1.Close;
end;
procedure TForm1.resetbtnClick(Sender: TObject);
begin
edit1.Clear;
edit2.Clear;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Memo1.Lines.LoadFromFile('C:\Numbergen\NumberDB.txt');
Memo1.WordWrap := true;
end;
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
form1.ShowModal;
form1.Free;
end;
procedure TForm1.FormShow(Sender: TObject);
var lStrings: TStringList;
begin
DataSource1.DataSet.Append;
Label6.Caption :=GetCurrentUserName;
lStrings := TStringList.Create;
LStrings.Delimiter := ',';
lStrings.DelimitedText := Memo1.Lines[Memo1.Lines.Count-1];
Label8.Caption:= lStrings.Strings[0];
Label13.Caption:= lStrings.Strings[1];
Label14.Caption:= lStrings.Strings[2];
Label15.Caption:= lStrings.Strings[3];
end;
procedure TForm1.dellastentryClick(Sender: TObject);
begin
Memo1.Lines.Delete(Memo1.Lines.Count-1);
end;
procedure TForm1.Button6Click(Sender: TObject);
var val2, sum: Integer;
begin
val2 := StrToInt(Edit3.Text);
sum := val2;
Edit3.Text := (IntToStr(sum+1));
end;
procedure TForm1.CheckBox1Click(Sender: TObject);
begin
if checkbox1.Checked
then
Edit1.Text := Label6.Caption
else Edit1.Text :='';
end;
procedure TForm1.GenerateClick(Sender: TObject);
var val1, val2, sum: Integer;
begin
val1 := StrToInt(Edit2.Text);
val2 := StrToInt(Edit3.Text);
sum := val1 + val2;
Edit3.Text := IntToStr(sum);
Memo1.Lines.SaveToFile('C:\Numbergen\NumberDB.txt');
if edit1.Text =('')
then MessageDlg('Invalid/Blank Username! Please enter one!',mtError, mbOKCancel, 0)
else
memo1.Lines.Add(edit1.Text+',' +edit2.Text+','+IntToStr(sum-val1)+'-'+edit3.text+ ','+formatdatetime('yyyy/mm/dd', datetimepicker1.date) );
end;
end.
谢谢
保存对数据的更改不是 TDBGrid 的责任,您需要自己完成。换句话说,您的数据未保存的原因是您实际上并未调用 AdoQuery1 的 "save" 方法。此方法实际上称为 Post
,因此在您的代码中的某处,例如不存在的 "save" 按钮的 OnClick
你应该做的处理程序
if AdoQuery1.State in [dsEdit, dsInsert] then
AdoQuery1.Post;
顺便说一句,使用当前代码保存数据的原因是某些数据集操作(不是 DBGrid 操作)导致对数据集的任何更改被 Post
ed。这些包括导致数据集的逻辑光标滚动,例如通过单击 DBGrid 中的不同行或关闭数据集。但是依赖这个是非常糟糕的做法 - 您的表单应该始终为用户提供一种明确的方式来保存和取消对数据集的更改。
顺便说一句,永远不要像您在 FormKeyDown
中那样编写代码 - 这是一个等待发生的事故。
如您所见:
procedure TForm1.FormShow(Sender: TObject);
var lStrings: TStringList;
begin
DataSource1.DataSet.Append;
Label6.Caption :=GetCurrentUserName;
DataSet
在dsInsert
这里,所以你必须保存更改。
有两种方法可以做到这一点:
检查DataSet
状态为MartynA回答
在您的代码中添加一行 DataSource.DataSet.Post;
。
顺便说一句,我在你的代码中没有看到你将数据保存在数据库中。
我有一个表格,其中有一个 DataSource,AdoQuery,AdoConnection,DBgrid
加上一对 edit
和一个 memo
。
用户输入他的用户名、街道地址等,然后点击 'save' 按钮。当时,应用程序将详细信息写入逗号分隔的 txt 文件,该文件连接到 Access 链接 table。当用户点击 'save' 按钮时,它会立即写入备忘录,但不会实时更新 dbgrid 数据库,只有在重新打开应用程序时才会如此。
我搜索了很多,但每个人都有不同的建议:做一个dbgrid refresh, adorequery, post, append, showmodal, open and close the database
等等
我的问题是为什么 dbgrid liveupdate 不起作用?
源代码如下:
unit test;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, StrUtils, Grids, Buttons, pngimage, ExtCtrls,
ComCtrls, DBGrids, DB, DBTables, ColorGrd, DirOutln, ADODB,
FMTBcd, SqlExpr, DBCtrls, DBClient, jpeg;
type
TForm1 = class(TForm)
Memo1: TMemo;
exit: TButton;
resetbtn: TButton;
Label3: TLabel;
GroupBox1: TGroupBox;
Label7: TLabel;
Label8: TLabel;
GroupBox2: TGroupBox;
Label1: TLabel;
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
Generate: TButton;
GroupBox3: TGroupBox;
Label5: TLabel;
Label6: TLabel;
CheckBox1: TCheckBox;
Image1: TImage;
Image2: TImage;
Button6: TButton;
DateTimePicker1: TDateTimePicker;
GroupBox4: TGroupBox;
Label10: TLabel;
Label9: TLabel;
dellastentry: TButton;
ADOConnection1: TADOConnection;
ADOQuery1: TADOQuery;
DataSource1: TDataSource;
DBGrid1: TDBGrid;
Label13: TLabel;
Label14: TLabel;
Label16: TLabel;
Label17: TLabel;
Label18: TLabel;
Label2: TLabel;
Label4: TLabel;
Label11: TLabel;
Label15: TLabel;
ADOQuery1Username: TWideStringField;
ADOQuery1RequestedNumber: TWideStringField;
ADOQuery1AllocatedNumber: TWideStringField;
ADOQuery1DateofRequest: TWideStringField;
procedure exitClick(Sender: TObject);
procedure resetbtnClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure dellastentryClick(Sender: TObject);
procedure GenerateClick(Sender: TObject);
procedure CheckBox1Click(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure Button6Click(Sender: TObject);
procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
function GetCurrentUserName: string;
const
cnMaxUserNameLen = 50;
var
sUserName: string;
dwUserNameLen: DWORD;
begin
dwUserNameLen := cnMaxUserNameLen - 1;
SetLength(sUserName, cnMaxUserNameLen);
GetUserName(PChar(sUserName), dwUserNameLen);
SetLength(sUserName, dwUserNameLen);
Result := sUserName;
end;
procedure TForm1.exitClick(Sender: TObject);
begin
Memo1.Lines.SaveToFile('C:\Numbergen\NumberDB.txt');
form1.Close;
end;
procedure TForm1.resetbtnClick(Sender: TObject);
begin
edit1.Clear;
edit2.Clear;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Memo1.Lines.LoadFromFile('C:\Numbergen\NumberDB.txt');
Memo1.WordWrap := true;
end;
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
form1.ShowModal;
form1.Free;
end;
procedure TForm1.FormShow(Sender: TObject);
var lStrings: TStringList;
begin
DataSource1.DataSet.Append;
Label6.Caption :=GetCurrentUserName;
lStrings := TStringList.Create;
LStrings.Delimiter := ',';
lStrings.DelimitedText := Memo1.Lines[Memo1.Lines.Count-1];
Label8.Caption:= lStrings.Strings[0];
Label13.Caption:= lStrings.Strings[1];
Label14.Caption:= lStrings.Strings[2];
Label15.Caption:= lStrings.Strings[3];
end;
procedure TForm1.dellastentryClick(Sender: TObject);
begin
Memo1.Lines.Delete(Memo1.Lines.Count-1);
end;
procedure TForm1.Button6Click(Sender: TObject);
var val2, sum: Integer;
begin
val2 := StrToInt(Edit3.Text);
sum := val2;
Edit3.Text := (IntToStr(sum+1));
end;
procedure TForm1.CheckBox1Click(Sender: TObject);
begin
if checkbox1.Checked
then
Edit1.Text := Label6.Caption
else Edit1.Text :='';
end;
procedure TForm1.GenerateClick(Sender: TObject);
var val1, val2, sum: Integer;
begin
val1 := StrToInt(Edit2.Text);
val2 := StrToInt(Edit3.Text);
sum := val1 + val2;
Edit3.Text := IntToStr(sum);
Memo1.Lines.SaveToFile('C:\Numbergen\NumberDB.txt');
if edit1.Text =('')
then MessageDlg('Invalid/Blank Username! Please enter one!',mtError, mbOKCancel, 0)
else
memo1.Lines.Add(edit1.Text+',' +edit2.Text+','+IntToStr(sum-val1)+'-'+edit3.text+ ','+formatdatetime('yyyy/mm/dd', datetimepicker1.date) );
end;
end.
谢谢
保存对数据的更改不是 TDBGrid 的责任,您需要自己完成。换句话说,您的数据未保存的原因是您实际上并未调用 AdoQuery1 的 "save" 方法。此方法实际上称为 Post
,因此在您的代码中的某处,例如不存在的 "save" 按钮的 OnClick
你应该做的处理程序
if AdoQuery1.State in [dsEdit, dsInsert] then
AdoQuery1.Post;
顺便说一句,使用当前代码保存数据的原因是某些数据集操作(不是 DBGrid 操作)导致对数据集的任何更改被 Post
ed。这些包括导致数据集的逻辑光标滚动,例如通过单击 DBGrid 中的不同行或关闭数据集。但是依赖这个是非常糟糕的做法 - 您的表单应该始终为用户提供一种明确的方式来保存和取消对数据集的更改。
顺便说一句,永远不要像您在 FormKeyDown
中那样编写代码 - 这是一个等待发生的事故。
如您所见:
procedure TForm1.FormShow(Sender: TObject);
var lStrings: TStringList;
begin
DataSource1.DataSet.Append;
Label6.Caption :=GetCurrentUserName;
DataSet
在dsInsert
这里,所以你必须保存更改。
有两种方法可以做到这一点:
检查
DataSet
状态为MartynA回答在您的代码中添加一行
DataSource.DataSet.Post;
。
顺便说一句,我在你的代码中没有看到你将数据保存在数据库中。