databasedelphidelphi-2009tdbgrid

Delphi: TDBGrid not update


I had a form which has a DataSource,AdoQuery,AdoConnection,DBgrid plus couple edit and a memo. User enter his username,street address, etc.. and hit 'save' button. On that time the application is write the details in a comma separated txt file, which is connected to an Access linked table. When user hit 'save' button it write into the memo instantly but not live update the dbgrid database, only when reopen the app.

I search a lot but everybody has different suggestions: do a dbgrid refresh, adorequery, post, append, showmodal, open and close the database etc.

My question is why the dbgrid liveupdate doesn't work?

Sourcecode is the following:


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.

Thank you


Solution

  • It's not the responsibility of a TDBGrid to save changes to data, you need to do that yourself. In other words, the reason your data isn't getting saved is that you aren't actually calling the "save" method of AdoQuery1. This method is actually called Post, so somewhere in your code, e.g. the non-existent "save" button's OnClick handler you should be doing

    if AdoQuery1.State in [dsEdit, dsInsert] then
      AdoQuery1.Post;
    

    Btw, the reason your data gets saved at all with your current code is that certain dataset operations (not DBGrid ones) cause any changes to the dataset to be Posted. These include causing the dataset's logical cursor to scroll, e.g. by clicking in a different row in the DBGrid or closing the dataset. But it is extremely bad practice to rely on this - your form should always provide the user with an explicit way to save and cancel changes to a dataset.

    Also btw, never write code like you have in your FormKeyDown - it is an accident waiting to happen.