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 操作)导致对数据集的任何更改被 Posted。这些包括导致数据集的逻辑光标滚动,例如通过单击 DBGrid 中的不同行或关闭数据集。但是依赖这个是非常糟糕的做法 - 您的表单应该始终为用户提供一种明确的方式来保存和取消对数据集的更改。

顺便说一句,永远不要像您在 FormKeyDown 中那样编写代码 - 这是一个等待发生的事故。

如您所见:

 procedure TForm1.FormShow(Sender: TObject);
       var lStrings: TStringList;
    begin
     DataSource1.DataSet.Append;
     Label6.Caption :=GetCurrentUserName;

DataSetdsInsert这里,所以你必须保存更改。

有两种方法可以做到这一点:

  • 检查DataSet状态为MartynA回答

  • 在您的代码中添加一行 DataSource.DataSet.Post;

顺便说一句,我在你的代码中没有看到你将数据保存在数据库中。